MATLAB: Serious problem with “createMask” function.

Image Processing Toolboxproblem with createmask

Dear all,
I am trying to develop a tool that lets the user to correct manually the contour of an object. The idea is to convert each pixel in the contour and make it a vertex using "impoly" in following code:
Z = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
BW = im2bw(Z);
B = bwboundaries(BW);
b = B{1};
X = b(:, 1);
Y = b(:, 2);
figure, imshow(BW);
hpoly = impoly(gca,[Y, X]);
wait (hpoly)
maskImage = hpoly.createMask();
figure, imshow(maskImage);
figure, imshow(Z);
Now, if you didn't do any change to the vertex and just double clicked inside the square you can notice that "maskImage" and "Z" are not the same!
Any one can tell me why is that? and how can we solve it?
Any help will be appreciated.
Meshoo

Best Answer

Here is some code illustrating how to use bwboundaries to get X-Y polygon vertices that work better for mask creation via createMask or poly2mask (which createMask calls). The idea is to get a polygon that includes the centers of the desired mask pixels inside the polygon instead of along its edges. First, here is your code with some graphics to show the area of each pixel and to show the output of bwboundaries going through pixel centers.
BW = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
B = bwboundaries(BW);
b = B{1};
imshow(BW,'InitialMagnification','fit');
hold on
[M,N] = size(BW);
x = [0.5 (N+0.5)];
for k = 1.5:(M-0.5)
y = [k k];
plot(x,y,'Color',[.7 .7 .7],'LineStyle','--');
end
y = [0.5 (M+0.5)];
for k = 1.5:(N-0.5)
x = [k k];
plot(x,y,'Color',[.7 .7 .7],'LineStyle','--');
end
plot(b(:,2),b(:,1),'r')
hold off
And here is modified code that produces X-Y values that do not go directly through pixel centers.
BW3 = imresize(Z,3,'nearest');
B3 = bwboundaries(BW3);
b3 = B3{1};
b3 = (b3 + 1)/3;
imshow(BW,'InitialMagnification','fit');
hold on
[M,N] = size(BW);
x = [0.5 (N+0.5)];
for k = 1.5:(M-0.5)
y = [k k];
plot(x,y,'Color',[.7 .7 .7],'LineStyle','--');
end
y = [0.5 (M+0.5)];
for k = 1.5:(N-0.5)
x = [k k];
plot(x,y,'Color',[.7 .7 .7],'LineStyle','--');
end
plot(b3(:,2),b3(:,1),'r')
hold off