2

I have been taking an image and drawing a contour on it. I need to count the no of pixels and the positions of them too in three categories (in MATLAB)

  1. The pixels that are outside the curve
  2. The pixels that are inside the curve
  3. The pixels that are on the boundary of the curve.

I have tried using inpolygon in MATLAB. It can count the pixels inside and outside but not on the boundary. On the boundary it counts for those only which passes directly through the center of the small grids. I need to also count those pixels where the contour passes through any one of the four edges of the small grids.

Please Help. I have provided the code below.

%Polygon Plotting 
clc;clear all;close all;
I = imread('cameraman.tif');
I = imresize(I,[100 100]);
I = double(I(:,:,1));
imagesc(I,[0 255]);colormap(gray);
axis([1 size(I,1) 1 size(I,2)]);
[BW xi yi] = roipoly();  %select your own coordinates. 
X=xi;
Y=yi;
hold on;
contour(BW,'r');
hold off;
xa = 1 : size(I,2);
ya = 1 : size(I,1);
[x,y] = meshgrid(xa,ya);
[in on] = inpolygon(x,y,X,Y);
count1 = sum(sum(in));
count2 = size(I,1)*size(I,2) - count1; 
count3 = sum(sum(on));
%count1 = inside the polygon and on boundary
%count2 = outside the polygon
%count3 = on the boundary only
inside = zeros(count1,2);
outside = zeros(count2,2);
onthecurve = zeros(count3,2);
l=1;m=1;n=1;

    for i = 1:size(I,1)
        for j = 1:size(I,2)
            if in(i,j)==1
                inside(l,1)=i;
                inside(l,2)=j;
                l=l+1;
            end
            if in(i,j)==0
                outside(m,1)= i;
                outside(m,2)= j;
                m = m+1;
            end
            if on(i,j)==1
                onthecurve(n,1)= i;
                onthecurve(n,2)= j;
                n = n+1;
            end
        end
    end
figure,    
plot(inside(:,1),inside(:,2),'+g');
axis([1 size(I,1) 1 size(I,2)]);
hold on 
plot(outside(:,1),outside(:,2),'+r');
hold on
plot(onthecurve(:,1),onthecurve(:,2),'+b');
hold off

Please refer to links if images are not displayed properly: 1.Original Image & Contour 2.Green - inside, Red - outside

As it can be seen the points on the contour are not marked in blue. Indeed count3 almost always gives an output 0. So inpolygon is not very efficient in counting the points on the boundary.

How can I modify my code so as to count those pixels too ? Thanks Everybody.

roni
  • 1,443
  • 3
  • 28
  • 49

1 Answers1

1

You can use edge to detect the border of a Black and White (BW) image (the input polygon in this case).

%% Polygon Plotting
I = imread('cameraman.tif');
imshow(I);
inBW = roipoly(); % Select your own coordinates.

%% Make BW matrices
outBW = ~inBW; % Find 'out'
edBW = edge(inBW); % Find the 'edge'
inBW(edBW) = 0; % Remove edge from 'in'
outBW(edBW) = 0; % Remove edge from 'out'

%% Show result
imshow(double(cat(3, inBW, edBW, outBW)))

Also to show that all the pixels are included in the 3 sets:

prod(size(I)) - sum(sum(inBW + outBW + edBW))

Should become zero.

Hope it helps.

p8me
  • 1,840
  • 1
  • 15
  • 23
  • Thank you! but i wanted to do the function without using the edge operator . Any other suggestions are appreciated. – roni Jul 05 '13 at 18:31
  • Another thing I really wanted to calculate the pixels that are outside , inside and on the curve. I had done so easily enough by using a for loop. Then I wanted to display the plots and compare it with the original contour. However they are not similar. This is due to the fact that in an Image the point (1,1) is at the topmost left corner whereas in a Matrix in Matlab , (1,1) is at the bottom most left position. How can I reverse my y axis in plot command ? – roni Jul 05 '13 at 18:34
  • If you don't want to use `edge` command you can write your own edge detection function, I am pretty sure that there are many algorithms for edge detection. About matching indices of a matrix to an image take a look at [`flipud`](http://www.mathworks.com/help/matlab/ref/flipud.html). – p8me Jul 05 '13 at 18:54