Split a rhombus in an image into four through centroid
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
I need to find the area of 4 partitions of the rhombus like image. Thank you in advance for the support.
The partition should be based on the centre point and the corners of rhombus. Assuming rombus may be angled.

採用された回答
Image Analyst
2022 年 12 月 13 日
Try this:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = [];
baseFileName = 'rhombus.png';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgb2gray(grayImage);
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Update the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Show the histogram
subplot(2, 2, 2);
imhist(grayImage);
title('Histogram of Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
grid on;
%--------------------------------------------------------------------------------------------------------
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
lowThreshold = 58;
highThreshold = 255;
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, grayImage)
%--------------------------------------------------------------------------------------------------------
% Create a mask
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Fill blobs
mask = imfill(mask,"holes");
% Take largest blob only.
mask = bwareafilt(mask, 1);
subplot(2, 2, 3);
imshow(mask, []);
impixelinfo;
axis('on', 'image');
title('Mask', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Measure blob features.
labeledImage = bwlabel(mask);
props = regionprops(mask, grayImage, 'WeightedCentroid', 'Centroid');
if isempty(props)
msgbox('No blobs found.')
return;
end
fprintf('Found %d blobs.\n', numel(props))
% Get the weighted centroid. Not sure which centroid you want.
% xCentroid = props.WeightedCentroid(1);
% yCentroid = props.WeightedCentroid(2);
% Get the unweighted centroid.
xCentroid = props.Centroid(1);
yCentroid = props.Centroid(2);
% Draw lines for the quadrants.
hold on;
xline(xCentroid, 'LineWidth', 2, 'Color', 'r');
yline(yCentroid, 'LineWidth', 2, 'Color', 'r');
hold off;
subplot(2, 2, 1);
hold on;
xline(xCentroid, 'LineWidth', 2, 'Color', 'r');
yline(yCentroid, 'LineWidth', 2, 'Color', 'r');
hold off;
% Get the area of the 4 quadrants. Dividing lines align with the edges of the image.
% Get area of upper left.
quad1 = mask(1 : floor(yCentroid), 1 : floor(xCentroid));
areaUpperLeft = nnz(quad1)
% Get area of upper right.
quad2 = mask(1 : floor(yCentroid), ceil(xCentroid) : end);
areaUpperRight = nnz(quad1)
% Get area of lower left.
quad3 = mask(ceil(yCentroid) : end, 1 : floor(xCentroid));
areaLowerLeft = nnz(quad1)
% Get area of lower right.
quad4 = mask(ceil(yCentroid) : end, ceil(xCentroid) : end);
areaLowerRight = nnz(quad1)
% Show areas as bar chart.
areas = [areaUpperLeft, areaUpperRight, areaLowerLeft, areaLowerRight];
subplot(2, 2, 4);
bar(areas);
title('Areas of Quadrants', 'FontSize', fontSize)
xlabel('Quadrant', 'FontSize', fontSize)
ylabel('Area in pixels', 'FontSize', fontSize)
grid on;

7 件のコメント
D D
2022 年 12 月 14 日
I am sorry.. But I need to partition only the blob into 4 through centroid of the blob and find area of each blob partition.
Image Analyst
2022 年 12 月 14 日
Why are you sorry? I did it for you. What's the problem?
I got your idea! Thank You.. 2 doubts.
1) When I add up 4 area together, it is not exactly same as total blob area. (I made some changes in code, since I am working in Simulink)
buff = imread('11101kaz-MO_100-DPY2_2mA.png');
Map = rgb2gray(buff);
mask = imbinarize(Map);
mask = imfill(mask,"holes");
% Take largest blob only.
mask = bwareafilt(mask, 1);
[X Y] = size(mask);
quad1 = mask(1 : floor(Cent_Y), 1 : floor(Cent_X));
area1 = nnz(quad1);
% Get area of upper right.
quad2 = mask(1 : floor(Cent_X), ceil(Cent_X) : Y);
area2 = nnz(quad2);
% % Get area of lower left.
quad3 = mask(ceil(Cent_X) : X, 1 : floor(Cent_X));
area3 = nnz(quad3);
% % Get area of lower right.
quad4 = mask(ceil(Cent_X) : X, ceil(Cent_X) : Y);
area4 = nnz(quad4);
2) Won't the partition be wrong, if the rhombus is slightly angled.
Is there a way to find the cordinate whether the bounding box meets the corners, rather than assuming the axes as horizontal and perpendicular.
Corners of each quandrant will be centre point and corners of rhombus.

PS: I am a beginner in MATLAB and Image Processing.
Sorry, I made a copy and paste error - forgot to change quadrants in the nnz() calls. Corrected code is below. The area of the whole mask now sums to the area of the quadrants. But I see you discovered that bug and fixed it so your quadrant areas should all sum to the area of the mask. What do you get when you do
theSum = area1 + area2 + area3 + area4
theSum2 = nnz(mask)
Here is my corrected demo:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = [];
baseFileName = 'rhombus.png';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgb2gray(grayImage);
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Update the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Show the histogram
subplot(2, 2, 2);
imhist(grayImage);
title('Histogram of Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
grid on;
%--------------------------------------------------------------------------------------------------------
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
lowThreshold = 58;
highThreshold = 255;
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, grayImage)
%--------------------------------------------------------------------------------------------------------
% Create a mask
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Fill blobs
mask = imfill(mask,"holes");
% Take largest blob only.
mask = bwareafilt(mask, 1);
subplot(2, 2, 3);
imshow(mask, []);
impixelinfo;
axis('on', 'image');
title('Mask', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Measure blob features.
labeledImage = bwlabel(mask);
props = regionprops(mask, grayImage, 'WeightedCentroid', 'Centroid');
if isempty(props)
msgbox('No blobs found.')
return;
end
fprintf('Found %d blobs.\n', numel(props))
% Get the weighted centroid. Not sure which centroid you want.
% xCentroid = props.WeightedCentroid(1);
% yCentroid = props.WeightedCentroid(2);
% Get the unweighted centroid.
xCentroid = props.Centroid(1);
yCentroid = props.Centroid(2);
% Draw lines for the quadrants.
hold on;
xline(xCentroid, 'LineWidth', 2, 'Color', 'r');
yline(yCentroid, 'LineWidth', 2, 'Color', 'r');
hold off;
subplot(2, 2, 1);
hold on;
xline(xCentroid, 'LineWidth', 2, 'Color', 'r');
yline(yCentroid, 'LineWidth', 2, 'Color', 'r');
hold off;
% Get the area of the 4 quadrants. Dividing lines align with the edges of the image.
% Get area of upper left.
quad1 = mask(1 : floor(yCentroid), 1 : floor(xCentroid));
areaUpperLeft = nnz(quad1)
% Get area of upper right.
quad2 = mask(1 : floor(yCentroid), ceil(xCentroid) : end);
areaUpperRight = nnz(quad2)
% Get area of lower left.
quad3 = mask(ceil(yCentroid) : end, 1 : floor(xCentroid));
areaLowerLeft = nnz(quad3)
% Get area of lower right.
quad4 = mask(ceil(yCentroid) : end, ceil(xCentroid) : end);
areaLowerRight = nnz(quad4)
% Show areas as bar chart.
areas = [areaUpperLeft, areaUpperRight, areaLowerLeft, areaLowerRight];
subplot(2, 2, 4);
bar(areas);
title('Areas of Quadrants', 'FontSize', fontSize)
xlabel('Quadrant', 'FontSize', fontSize)
ylabel('Area in pixels', 'FontSize', fontSize)
grid on;
theSum = areaUpperRight + areaUpperLeft + areaLowerRight + areaLowerLeft
nnz(mask)
As far as a tilted rhombus, it's not in general a perfect rhombus. It could be an arbitrary quadrilateral. For example if you located the vertices of the shape (see attached demo) the lines drawn between vertices could not in general intersect at exactly 90 degrees. So now the lines separating the quadrants of the shape could be drawn such that they cut across pixels, giving areas of a partial pixel. How do you want to handle that? Do you NEED to handle that? There is a variety of ways to handle that but they're all somewhat complicated. For example you could find the centroid, find the distance of the boundary to the centroid, call findpeaks to find the vertices, take the farthest vertices and one directly across from it and determine the angle, rotate the image so that it is aligned with the vertical and horizontal axes, then compute the quadrant areas as I have already done. But is all that really necessary? What are you going to do with the information once you have it? We need to know that to determine if it's really needed.
D D
2022 年 12 月 15 日
Thank you for your reply.
Lets me explain my final requirements

1) Find area of partitions ①,②,③ and ④
2) Find lengths of 4 dotted lines l1,l2,l3 and l4 ( From Centre)
3) Find angles of 4 dotted lines l1,l2,l3 and l4 from the center to the vertices of each entity
For finding above data, first I wanted to figureout the cordinates at the corners. I attempted different methods. And finally the below logic giving an approximate result. Here I searches through the bounding box (logic may not be excellent)
buff = imread('11101kaz-MO_100-DPY2_2mA.png');
Map = rgb2gray(buff);
mask = imbinarize(Map);
mask = imfill(mask,"holes");
%iterate through ounding box)
Cellcol = bb(1);
Cellrow= bb(2);
Firsthigh = int32(0);
Lasthigh = int32(0);
Cellvalue = logical(0);
% Find upper point
for i = 0:bb(3)
Cellvalue = mask(Cellrow, Cellcol+i);
if(1 == Cellvalue)
Firsthigh = i;
break;
end
end
for i= bb(3):-1:0
Cellvalue = mask(Cellrow, Cellcol+i);
if(1 == Cellvalue)
Lasthigh = i;
break;
end
end
UpperMiddlepoint = bb(1)+ Firsthigh + ceil(0.5*(Lasthigh-Firsthigh));
% Find lower point
Firsthigh = int32(0);
for i = 0:bb(3)
Cellvalue = mask(Cellrow+bb(4)-1, Cellcol+i);
if(1 == Cellvalue)
Firsthigh = i;
break;
end
end
Lasthigh = int32(0);
for i= bb(3):-1:0
Cellvalue = mask(Cellrow+bb(4)-1, Cellcol+i);
if(1 == Cellvalue)
Lasthigh = i;
break;
end
end
LowerMiddlepoint = bb(1)+ Firsthigh + ceil(0.5*(Lasthigh-Firsthigh));
% Find left point
Firsthigh = int32(0);
for i = 0:bb(4)
Cellvalue = mask(Cellrow+i, Cellcol);
if(1 == Cellvalue)
Firsthigh = i;
break;
end
end
Lasthigh = int32(0);
for i= bb(4):-1:0
Cellvalue = mask(Cellrow+i, Cellcol);
if(1 == Cellvalue)
Lasthigh = i;
break;
end
end
LeftMiddlepoint = bb(2) + Firsthigh + ceil(0.5*(Lasthigh-Firsthigh));
% Find right point
Firsthigh = int32(0);
for i = 0:bb(4)
Cellvalue = mask(Cellrow+i, Cellcol+bb(3)-1); % Check why -1 was needed
if(1 == Cellvalue)
Firsthigh = i;
break;
end
end
Lasthigh = int32(0);
for i= bb(4):-1:0
Cellvalue = mask(Cellrow+i, Cellcol+bb(3)-1);
if(1 == Cellvalue)
Lasthigh = i;
break;
end
end
RightMiddlepoint = bb(2) + Firsthigh + ceil(0.5*(Lasthigh-Firsthigh));
imshow(mask);
hold on
%plot(x,y,'b','LineWidth',2)
plot(bb(1)+bb(3),RightMiddlepoint, 'r+', 'MarkerSize', 30, 'LineWidth', 2);
plot(bb(1),LeftMiddlepoint, 'r+', 'MarkerSize', 30, 'LineWidth', 2);
plot(LowerMiddlepoint,bb(2)+bb(4), 'r+', 'MarkerSize', 30, 'LineWidth', 2);
plot(UpperMiddlepoint,bb(2), 'r+', 'MarkerSize', 30, 'LineWidth', 2);
plot(Cent_X,Cent_Y, 'r+', 'MarkerSize', 30, 'LineWidth', 2);
rectangle('Position',[bb(1) bb(2) bb(3) bb(4)],'EdgeColor','green');
hold off
The result I obtained is below. Now I am need to measure the items in my requirement list.

Image Analyst
2022 年 12 月 15 日
I already knew that. You basically just repeated saying that you need to measure the quadrants. But you didn't say why even though I asked directly. Maybe it's secret or proprietary and that's why you won't tell anyone.
But how will your algorithm work on the attached image?

Does it find the vertices? (Like the attached demo)
D D
2022 年 12 月 19 日
I understood your point.. But Such a big tilt is not expected in the input image.. Thank you for helping me with solving the problem..
その他の回答 (1 件)
Image Analyst
2022 年 12 月 12 日
If you still can't figure it out (how to get the centroid and use indexing to split it into 4 parts) then write back, but it should be pretty easy.
カテゴリ
ヘルプ センター および File Exchange で Neighborhood and Block Processing についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
