How to find a specific region of the boundary of the object?
13 views (last 30 days)
Show older comments
Hi I would appreciate if you answer my questions. I have attached the image. I have found the boundary of it. However, I just wanna find the boundary of last 30 percent of it. ( more or less) just wanna know how I can adjust the boundary and process the image from the part where exactly I am interested. When I find the last 30 percent of the boundary, I have a couple of images, I would like the see how the pixel density is changing at the end of the object ( 30 percent is just hypothetically). I hope my question is clear and appropriate to answer.
clear all;
clc;
B = imread('08.png');
bwImage = imbinarize(B,0.5);
bigMask = bwImage;
[ a, b ]=size(bigMask);
for i=1:a
for j=1:b
c = bigMask(i,j);
if c == 1
bigMask(i,j)=0;
end
if c == 0
bigMask(i,j)=1;
end
end
end
[B, L ,N] = bwboundaries(bigMask);
boundaries = bwboundaries(bigMask);
boundary1=cell2mat(boundaries(1));
x = boundary1(:,1);
y = boundary1(:,2);
figure;
imshow ('08.png');
hold on
plot(y,x,'r','LineWidth',1)
axis on
Accepted Answer
Image Analyst
on 29 Jul 2018
Well, there are lots of ways that code could be improved. Rather than go over all of them, just look at the code below and try to see what I did. It's very well commented.
clc; % Clear the command window.
clearvars;
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
grayImage = imread('08.png');
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
grayImage = rgb2gray(grayImage);
end
subplot(2, 3, 1);
imshow(grayImage, []);
axis('on', 'image');
title('Original Image', 'FontSize', fontSize);
% Display histogram of the image, just for fun.
subplot(2, 3, 2);
imhist(grayImage);
grid on;
title('Histogram of Image', 'FontSize', fontSize);
% Binarize the image.
binaryImage = ~imbinarize(grayImage, 0.5);
% Display binary image.
subplot(2, 3, 3);
imshow(binaryImage, []);
axis('on', 'image');
title('Initial Binary Image', 'FontSize', fontSize);
drawnow;
% Get rid of blobs touching the borders except for the left border.
binaryImage(:, 1) = false; % Erase left column so it won't be deleted.
% Delete if touching the top, bottom, or right border.
binaryImage = imclearborder(binaryImage);
% Take the largest of the blobs that remain.
binaryImage = bwareafilt(binaryImage, 1);
% Fill the hole.
binaryImage = imfill(binaryImage, 'holes');
subplot(2, 3, 4);
imshow(binaryImage, []);
axis('on', 'image');
title('Final Binary Image', 'FontSize', fontSize);
% Find the boundaries.
boundaries = bwboundaries(binaryImage);
boundaryXY=cell2mat(boundaries(1));
x = boundaryXY(:, 2);
y = boundaryXY(:, 1);
% Plot boundaries over the original image.
subplot(2, 3, 5);
imshow(grayImage, []);
hold on
plot(x, y, 'r-' , 'LineWidth', 1)
title('Image with Boundary and 30% line', 'FontSize', fontSize);
axis on
% Find the right most 30%.
minX = min(x);
maxX = max(x);
% First find the column at which divides the 70/30 protions of the image.
x30 = 0.7 * abs(maxX - minX) + minX
line([x30, x30], [1, rows], 'Color', 'm', 'LineWidth', 2);
line([maxX, maxX], [1, rows], 'Color', 'm', 'LineWidth', 2);
% Find indexes where x is in the rightmost 30%.
last30 = x > x30;
% Extract only those elements where x is in the rightmost 30%.
xLast30 = x(last30);
yLast30 = y(last30);
% Plot those elements.
subplot(2, 3, 6);
plot(xLast30, yLast30, 'b-', 'LineWidth', 2);
grid on;
% Reverse y axis to match direction of images.
ax = gca;
ax.YDir = 'reverse';
axis equal;
title('Rightmost 30 Percent', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
% Optional next steps.
% % Smooth with conv
% windowWidth = 31;
% kernel = ones(windowWidth, 1) / windowWidth;
% smoothedX = conv(xLast30, kernel, 'valid');
% smoothedY = conv(yLast30, kernel, 'valid');
% hold on;
% plot(smoothedX, smoothedY, 'c-');
% Now we need to find out "how the pixel density is changing at the end of the object".
% Get a mask of the rightmost 30%
mask = binaryImage; % Initialize.
mask(:, 1 : round(x30)) = false; % Erase leftmost 70%.
figure;
subplot(2, 1, 1);
imshow(mask, []);
axis('on', 'image');
title('Mask of Right 30%', 'FontSize', fontSize);
% Get the pixels only within the mask.
pixelsInMask = grayImage(mask);
% Histogram those:
subplot(2, 1, 2);
histogram(pixelsInMask, 'edgecolor', 'none');
axis('on', 'image');
grid on;
title('Histogram of Right 30%', 'FontSize', fontSize);
xlabel('Gray Level', 'FontSize', fontSize);
ylabel('Count', 'FontSize', fontSize);
axis 'square'
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/192755/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/192756/image.png)
Let me know if it's not what you want or need, or if you need something beyond this.
Personally I'd do a background division by a blank field of view to flatten the background and get better boundary accuracy.
More Answers (0)
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!