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)
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.
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.