How to implement invisible watermark image in image using 3 LSB - matlab

I need to implement 3 LSB watermarking without using the existing functions in MATLAB.
I need my function to get 2 images, both gray-level, and preform watermarking using 3 LSB.
I tried the following, but the result of the original image subtracted from the new image is all zeros which means they are the same.
function [C] = Q2(image,watermark)
% clc;
% image=imread('moon.tif');
% watermark=imread('cameraman.tif');
[X,Y] = size(image);
rewatermark = imresize(watermark,[X,Y]); % resizing watermark to fit image
% iterate the 3 LSB of the watermark and set them to a copy of the original
% image 3 LSB
C = image;
for i = 1:X
for j = 1:Y
for k = 1:3
if(bitget(rewatermark(i,j),k) == 1)
bitset(C(i,j),k,1);
else
bitset(C(i,j),k,0);
end
end
end
end
subplot(1,3,1)
imshow(image);
title('Original');
subplot(1,3,2);
imshow(rewatermark)
title('Watermark');
subplot(1,3,3)
imshow(C)
title('Invisble watermarked');
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
set(gcf,'name','Q2 - Results','numbertitle','off')

Instead of bitset(C(i,j),k,1), use: C(i,j) = bitset(C(i,j),k,1)
Except of OOP programing, MATLAB does not support references (or pointers).
Executing bitset(C(i,j),k,1), does not modify the content of C(i,j), it sets the relevant bit to 1, and return the modified value.
Note:
I recommend suing the high bits of rewatermark (bits 6,7,8) instead of the lower bits 1,2,3 that are mainly "noise" (but it depends on your objectives).
Here is a code sample:
%function [C] = Q2(image,watermark)
clc;
image=imread('moon.tif');
watermark=imread('cameraman.tif');
[X,Y] = size(image);
rewatermark = imresize(watermark,[X,Y]); % resizing watermark to fit image
% iterate the 3 LSB of the watermark and set them to a copy of the original
% image 3 LSB
C = image;
for i = 1:X
for j = 1:Y
for k = 1:3
b = bitget(rewatermark(i,j), k+5); % Use the high bits 6,7,8 (instead of lower bits 1,2,3 that are mainly "noise")
C(i, j) = bitset(C(i, j), k, b); % Set bit k to the value of b (1 or 0)
%if(bitget(rewatermark(i,j),k) == 1)
% bitset(C(i,j),k,1);
%else
% bitset(C(i,j),k,0);
%end
end
end
end
subplot(1,3,1)
imshow(image);
title('Original');
subplot(1,3,2);
imshow(rewatermark)
title('Watermark');
subplot(1,3,3)
imshow(C)
title('Invisble watermarked');
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
set(gcf,'name','Q2 - Results','numbertitle','off')
reconstructed_rewatermark = bitshift(C, 5);
imshow(reconstructed_rewatermark);title('reconstructed_rewatermark');

Related

Visualizing matrix values in real time

Suppose I have a 5x5 matrix.
The elements of the matrix change (are refreshed) every second.
I would like to be able to display the matrix (not as a colormap but with the actual values in a grid) in realtime and watch the values in it change as time progresses.
How would I go about doing so in MATLAB?
A combination of clc and disp is the easiest approach (as answered by Tim), here's a "prettier" approach you might fancy, depending on your needs. This is not going to be as quick, but you might find some benefits, such as not having to clear the command window or being able to colour-code and save the figs.
Using dispMatrixInFig (code at the bottom of this answer) you can view the matrix in a figure window (or unique figure windows) at each stage.
Example test code:
fig = figure;
% Loop 10 times, pausing for 1sec each loop, display matrix
for i=1:10
A = rand(5, 5);
dispMatrixInFig(A,fig)
pause(1)
end
Output for one iteration:
Commented function code:
function dispMatrixInFig(A, fig, strstyle, figname)
%% Given a figure "fig" and a matrix "A", the matrix is displayed in the
% figure. If no figure is supplied then a new one is created.
%
% strstyle is optional to specify the string display of each value, for
% details see SPRINTF. Default is 4d.p. Can set to default by passing '' or
% no argument.
%
% figname will appear in the title bar of the figure.
if nargin < 2
fig = figure;
else
clf(fig);
end
if nargin < 3 || strcmp(strstyle, '')
strstyle = '%3.4f';
end
if nargin < 4
figname = '';
end
% Get size of matrix
[m,n] = size(A);
% Turn axes off, set origin to top left
axis off;
axis ij;
set(fig,'DefaultTextFontName','courier', ...
'DefaultTextHorizontalAlignment','left', ...
'DefaultTextVerticalAlignment','bottom', ...
'DefaultTextClipping','on');
fig.Name = figname;
axis([1, m-1, 1, n]);
drawnow
tmp = text(.5,.5,'t');
% height and width of character
ext = get(tmp, 'Extent');
dy = ext(4);
wch = ext(3);
dwc = 2*wch;
dx = 8*wch + dwc;
% set matrix values to fig positions
x = 1;
for i = 1:n
y = 0.5 + dy/2;
for j = 1:m
y = y + 1;
text(x,y,sprintf(strstyle,A(j,i)));
end
x = x + dx;
end
% Tidy up display
axis([1-dwc/2 1+n*dx-dwc/2 1 m+1]);
set(gca, 'YTick', [], 'XTickLabel',[],'Visible','on');
set(gca,'XTick',(1-dwc/2):dx:x);
set(gca,'XGrid','on','GridLineStyle','-');
end
I would have thought you could achieve this with disp:
for i=1:10
A = rand(5, 5);
disp(A);
end
If you mean that you don't want repeated outputs on top of each other in the console, you could include a clc to clear the console before each disp call:
for i=1:10
A = rand(5, 5);
clc;
disp(A);
end
If you want to display your matrix on a figure it is quite easy. Just make a dump matrix and display it. Then use text function to display your matrix on the figure. For example
randMatrix=rand(5);
figure,imagesc(ones(20));axis image;
hold on;text(2,10,num2str(randMatrix))
If you want to do it in a for loop and see the numbers change, try this:
for i=1:100;
randMatrix=rand(5);
figure(1),clf
imagesc(ones(20));axis image;
hold on;text(2,10,num2str(randMatrix));
drawnow;
end

How would I make a checkered pattern using a for loop in MATLAB for a user inputted dimension?

Basically the problem I can't solve is how to adapt into a for loop so depending on whatever dimensions I am given it does it on its own. This is an example using 2x2 dimensions. So for example if was to do 3x3 how would I do it in a for loop?
N=4;
R=2;
theta=zeros(1,N);
for k=1:N
theta(k)=2*pi*(k-1)/N;
end
x1=(R*cos(theta+pi/4)/sqrt(2));
y1=(R*sin(theta+pi/4)/sqrt(2));
plot(x1,y1);
fill(x1,y1,'w');
x2=(R*cos(theta+pi/4)/sqrt(2))+R;
y2=(R*sin(theta+pi/4)/sqrt(2));
plot(x2,y2);
fill(x2,y2,'y');
x3=(R*cos(theta+pi/4)/sqrt(2));
y3=(R*sin(theta+pi/4)/sqrt(2))+R;
plot(x3,y3);
fill(x3,y3,'y');
x4=(R*cos(theta+pi/4)/sqrt(2))+R;
y4=(R*sin(theta+pi/4)/sqrt(2))+R;
plot(x4,y4);
fill(x4,y4,'w');
hold;
You could set up a grid of points using ndgrid (or meshgrid).
To create index for the checker pattern, one trick is to use invhilb.
Below I used constant x and y instead of the one you created from R*cos(theta+pi/4)/sqrt(2)
% User input
N = 4;
% Basic square index
x = [0 1 1 0];
y = [0 0 1 1];
% Create axes and set to 'hold'
axes('NextPlot','Add')
% Create grid
[X,Y] = ndgrid(0:N-1);
% Loop over grid
for idx = 1:numel(X)
fh(idx) = fill(X(idx) + x, Y(idx) + y, 'w');
end
% Color as a check board (but with yellow)
set(fh(invhilb(N) > 0),'FaceColor','y')

Ploting a simple binaryThresholding function graph in matlab as shown in image and figure

How can I correct this code, I have been trying to do it from 2 day but unable to do it still. Please help.
function BinaryThresholding(I)
%Reading minimum and maximum intensity values of Image I.
Min = min(I(:));
Max = max(I(:));
%Finding the middle value (thresholding) A.K.A m below.
m = (Min+Max)/2;
%For ploting the thresholding tranformation function we will also
%define X and Y (Ranges) parameters based upon min and max range and the
%process them according to our transformation algoritm as below.
x = (Min/Max):(Max/Max); %input range.
y = x;
% Now we will apply alogithm to threshold the threshold I at
% the middle intensity,thresholdingValue, of its dynamic
% range [minValue maxValue]. G is our processed image.
[Rows, Columns, Channels] = size(I);
%First we will check if the image is gray-scale and conver it if not.
if(Channels==3)
I = rgb2gray(I);
end
%Processing Image.
for i=1:1:Rows
for j=1:1:Columns
if( I(i,j)< m)
G(i,j) = 0;
else
G(i,j) = 1;
end
end
end
% Algorithm works great :D --> Testingw with : figure, imshow(G);
%Displaying image on a new figure window.
figure('Name','Image Thresholding','NumberTitle','on'),
subplot(1,3,1); imshow(I); title(['Input Image - Dynamic Range: [',num2str(Min),' ',num2str(Max),']']);
subplot(1,3,2); imshow(G); title(['Output Image - Threshold:' num2str(m)]);
subplot(1,3,3); plot(x,y); title('Plot of Thresholding Transformation Function');
%Let pixel info to be shown on the figure.
impixelinfo;
%Writing the image G as a .png file to the current folder (Drive D:/).
% imwrite(G,'D:/G.png');
endDesired output
Actual output
From the title of outputs I think you want to fix this line
subplot(1,3,3); plot(x,y); title('Plot of Thresholding Transformation Function');
which means only correct these couple of lines
x = (Min/Max):(Max/Max); %input range.
y = x;
that means: x is equally spaced from min to max... and Y is also equally spaced from min to max (as you can see from your actual output). Try something like:
x = (Min/Max):(Max/Max); %input range.
y = zeros(length(x));
for i=1:length(x)
if (x > m)
y(i) = 1;
end
end

Segmenting cursive character (Arabic OCR)

I want to segment an Arabic word into single characters. Based on the histogram/profile, I assume that I can do the segmentation process by cut/segment the characters based on it's baseline (it have similar pixel values).
But, unfortunately, I still stuck to build the appropriate code, to make it works.
% Original Code by Soumyadeep Sinha
% Saving each single segmented character as one file
function [segm] = trysegment (a)
myFolder = 'D:\1. Thesis FINISH!!!\Data set\trial';
level = graythresh (a);
bw = im2bw (a, level);
b = imcomplement (bw);
i= padarray(b,[0 10]);
verticalProjection = sum(i, 1);
set(gcf, 'Name', 'Trying Segmentation for Cursive', 'NumberTitle', 'Off')
subplot(2, 2, 1);imshow(i);
subplot(2,2,3);
plot(verticalProjection, 'b-'); %histogram show by this code
% hist(reshape(input,[],3),1:max(input(:)));
grid on;
% % t = verticalProjection;
% % t(t==0) = inf;
% % mayukh = min(t)
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > 0;
% Find Rising and falling edges
d = diff(letterLocations);
startingColumns = find(d>0);
endingColumns = find(d<0);
% Extract each region
y=1;
for k = 1 : length(startingColumns)
% Get sub image of just one character...
subImage = i(:, startingColumns(k):endingColumns(k));
% se = strel('rectangle',[2 4]);
% dil = imdilate(subImage, se);
th = bwmorph(subImage,'thin',Inf);
n = imresize (th, [64 NaN], 'bilinear');
figure, imshow (n);
[L,num] = bwlabeln(n);
for z= 1 : num
bw= ismember(L, z);
% Construct filename for this particular image.
baseFileName = sprintf('char %d.png', y);
y=y+1;
% Prepend the folder to make the full file name.
fullFileName = fullfile(myFolder, baseFileName);
% Do the write to disk.
imwrite(bw, fullFileName);
% subplot(2,2,4);
% pause(2);
% imshow(bw);
end
% y=y+1;
end;
segm = (n);
Word image is as follow:
Why the code isn't work?
do you have any recommendation of another codes?
or suggested algorithm to make it works, to do a good segmentation on cursive character?
Thanks before.
Replace this code part from the posted code
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > 0;
% Find Rising and falling edges
d = diff(letterLocations);
startingColumns = find(d>0);
endingColumns = find(d<0);
with the new code part
threshold=max(verticalProjection)/3;
thresholdedProjection=verticalProjection > threshold;
count=0;
startingColumnsIndex=0;
for i=1:length(thresholdedProjection)
if thresholdedProjection(i)
if(count>0)
startingColumnsIndex=startingColumnsIndex+1;
startingColumns(startingColumnsIndex)= i-floor(count/2);
count=0;
end
else
count=count+1;
end
end
endingColumns=[startingColumns(2:end)-1 i-floor(count/2)];
No changes needed for the rest of the code.

Extracting image region within boundary

I have to do a project using 2D CT images and segment liver and tumor in it using Matlab(only). Initially i have to segment liver region alone. I use region growing for liver segmentation. It gets seed point as input.
The output is an image with a boundary for liver region. Now I need the region that is surrounded by the boundary alone.
My program has a main program and a regionGrowing.m function. As I'm a new user am not allowed to post images. If you do need images I will mail you. Kindly help me.
% mainreg.m
IR=imread('nfliver5.jpg');
figure, imshow(IR), hold all
poly = regionGrowing(IR,[],15,1200); % click somewhere inside the liver
plot(poly(:,1), poly(:,2), 'LineWidth', 2, 'Color', [1 1 1])
%regionGrowing.m
function [P, J] = regionGrowing(cIM, initPos, thresVal, maxDist, tfMean, tfFillHoles, tfSimplify)
% REGIONGROWING Region growing algorithm for 2D/3D grayscale images
%
% Syntax:
% P = regionGrowing();
% P = regionGrowing(cIM);
% P = regionGrowing(cIM, initPos)
% P = regionGrowing(..., thresVal, maxDist, tfMean, tfFillHoles, tfSimpl)
% [P, J] = regionGrowing(...);
%
% Inputs:
% cIM: 2D/3D grayscale matrix {current image}
% initPos: Coordinates for initial seed position {ginput position}
% thresVal: Absolute threshold level to be included {5% of max-min}
% maxDist: Maximum distance to the initial position in [px] {Inf}
% tfMean: Updates the initial value to the region mean (slow) {false}
% tfFillHoles: Fills enclosed holes in the binary mask {true}
% tfSimplify: Reduces the number of vertices {true, if dpsimplify exists}
%
% Outputs:
% P: VxN array (with V number of vertices, N number of dimensions)
% P is the enclosing polygon for all associated pixel/voxel
% J: Binary mask (with the same size as the input image) indicating
% 1 (true) for associated pixel/voxel and 0 (false) for outside
%
% Examples:
% % 2D Example
% load example
% figure, imshow(cIM, [0 1500]), hold all
% poly = regionGrowing(cIM, [], 300); % click somewhere inside the lungs
% plot(poly(:,1), poly(:,2), 'LineWidth', 2)
%
% % 3D Example
% load mri
% poly = regionGrowing(squeeze(D), [66,55,13], 60, Inf, [], true, false);
% plot3(poly(:,1), poly(:,2), poly(:,3), 'x', 'LineWidth', 2)
%
% Requirements:
% TheMathWorks Image Processing Toolbox for bwboundaries() and axes2pix()
% Optional: Line Simplification by Wolfgang Schwanghart to reduce the
% number of polygon vertices (see the MATLAB FileExchange)
%
% Remarks:
% The queue is not preallocated and the region mean computation is slow.
% I haven't implemented a preallocation nor a queue counter yet for the
% sake of clarity, however this would be of course more efficient.
%
% Author:
% Daniel Kellner, 2011, braggpeaks{}googlemail.com
% History: v1.00: 2011/08/14
% error checking on input arguments
if nargin > 7
error('Wrong number of input arguments!')
end
if ~exist('cIM', 'var')
himage = findobj('Type', 'image');
if isempty(himage) || length(himage) > 1
error('Please define one of the current images!')
end
cIM = get(himage, 'CData');
end
if ~exist('initPos', 'var') || isempty(initPos)
himage = findobj('Type', 'image');
if isempty(himage)
himage = imshow(cIM, []);
end
% graphical user input for the initial position
p = ginput(1);
% get the pixel position concerning to the current axes coordinates
initPos(1) = round(axes2pix(size(cIM, 2), get(himage, 'XData'), p(2)));
initPos(2) = round(axes2pix(size(cIM, 1), get(himage, 'YData'), p(1)));
end
if ~exist('thresVal', 'var') || isempty(thresVal)
thresVal = double((max(cIM(:)) - min(cIM(:)))) * 0.05;
end
if ~exist('maxDist', 'var') || isempty(maxDist)
maxDist = Inf;
end
if ~exist('tfMean', 'var') || isempty(tfMean)
tfMean = false;
end
if ~exist('tfFillHoles', 'var')
tfFillHoles = true;
end
if isequal(ndims(cIM), 2)
initPos(3) = 1;
elseif isequal(ndims(cIM),1) || ndims(cIM) > 3
error('There are only 2D images and 3D image sets allowed!')
end
[nRow, nCol, nSli] = size(cIM);
if initPos(1) < 1 || initPos(2) < 1 ||...
initPos(1) > nRow || initPos(2) > nCol
error('Initial position out of bounds, please try again!')
end
if thresVal < 0 || maxDist < 0
error('Threshold and maximum distance values must be positive!')
end
if ~isempty(which('dpsimplify.m'))
if ~exist('tfSimplify', 'var')
tfSimplify = true;
end
simplifyTolerance = 1;
else
tfSimplify = false;
end
% initial pixel value
regVal = double(cIM(initPos(1), initPos(2), initPos(3)));
% text output with initial parameters
disp(['RegionGrowing Opening: Initial position (' num2str(initPos(1))...
'|' num2str(initPos(2)) '|' num2str(initPos(3)) ') with '...
num2str(regVal) ' as initial pixel value!'])
% preallocate array
J = false(nRow, nCol, nSli);
% add the initial pixel to the queue
queue = [initPos(1), initPos(2), initPos(3)];
%%% START OF REGION GROWING ALGORITHM
while size(queue, 1)
% the first queue position determines the new values
xv = queue(1,1);
yv = queue(1,2);
zv = queue(1,3);
% .. and delete the first queue position
queue(1,:) = [];
% check the neighbors for the current position
for i = -1:1
for j = -1:1
for k = -1:1
if xv+i > 0 && xv+i <= nRow &&... % within the x-bounds?
yv+j > 0 && yv+j <= nCol &&... % within the y-bounds?
zv+k > 0 && zv+k <= nSli &&... % within the z-bounds?
any([i, j, k]) &&... % i/j/k of (0/0/0) is redundant!
~J(xv+i, yv+j, zv+k) &&... % pixelposition already set?
sqrt( (xv+i-initPos(1))^2 +...
(yv+j-initPos(2))^2 +...
(zv+k-initPos(3))^2 ) < maxDist &&... % within distance?
cIM(xv+i, yv+j, zv+k) <= (regVal + thresVal) &&...% within range
cIM(xv+i, yv+j, zv+k) >= (regVal - thresVal) % of the threshold?
% current pixel is true, if all properties are fullfilled
J(xv+i, yv+j, zv+k) = true;
% add the current pixel to the computation queue (recursive)
queue(end+1,:) = [xv+i, yv+j, zv+k];
if tfMean
regVal = mean(mean(cIM(J > 0))); % --> slow!
end
end
end
end
end
end
%%% END OF REGION GROWING ALGORITHM
% loop through each slice, fill holes and extract the polygon vertices
P = [];
for cSli = 1:nSli
if ~any(J(:,:,cSli))
continue
end
% use bwboundaries() to extract the enclosing polygon
if tfFillHoles
% fill the holes inside the mask
J(:,:,cSli) = imfill(J(:,:,cSli), 'holes');
B = bwboundaries(J(:,:,cSli), 8, 'noholes');
else
B = bwboundaries(J(:,:,cSli));
end
newVertices = [B{1}(:,2), B{1}(:,1)];
% simplify the polygon via Line Simplification
if tfSimplify
newVertices = dpsimplify(newVertices, simplifyTolerance);
end
% number of new vertices to be added
nNew = size(newVertices, 1);
% append the new vertices to the existing polygon matrix
if isequal(nSli, 1) % 2D
P(end+1:end+nNew, :) = newVertices;
else % 3D
P(end+1:end+nNew, :) = [newVertices, repmat(cSli, nNew, 1)];
end
end
% text output with final number of vertices
disp(['RegionGrowing Ending: Found ' num2str(length(find(J)))...
' pixels within the threshold range (' num2str(size(P, 1))...
' polygon vertices)!'])
If I understand you correctly, you have a binary image of the boundary of the kidney and now need to set the inside of the boundary to 1s. To do this, you can use the imfill() function with the 'holes' setting on.
BW2 = imfill(BW,'holes');
EDIT: Looking at the code, it seems that it does what you want already.
% Outputs:
% J: Binary mask (with the same size as the input image) indicating
% 1 (true) for associated pixel/voxel and 0 (false) for outside
so you just need to get the second output as well:
IR=imread('nfliver5.jpg');
figure, imshow(IR), hold all
[poly im] = regionGrowing(IR,[],15,1200); % click somewhere inside the liver
imshow(im,[])
Now im is a binary image with your segmented region.
EDIT2:
Once you have the binary image im, you can simply use element-wise multiplication to remove all parts of the orignal image outside the segmented region.
SEG = IR.*im;
imshow(SEG,[])
EDIT3:
For 3D images, you need to specify the coordinates manually, and not by using the mouse. This is because the mouse only gives us 2 coordinates (x and y) and you need 3 (x,y and z). So just find the coordinates you need by looking at the image, and then choosing an appropriate z coordinate.
%Example coordinates,
coordinates = [100 100 5]
poly = regionGrowing(squeeze(IR), coordinates, 60, Inf, [], true, false);