How to find a specific region of the boundary of the object?
17 ビュー (過去 30 日間)
古いコメントを表示
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
採用された回答
Image Analyst
2018 年 7 月 29 日
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.
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Convert Image Type についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!