Distance between several defects/points
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
Hello there, i currently doing researach on estimating distance between points. i need help with my code. I need to get the size measurement (diameter) and the distance between each of the defects/ point (pixel convert to mm) in the thermal image and it must be the same as the original real measurement as attached
I used colour threshold in matlab tools to get the defects. I stucked at gray image, region props and function of pdist. thank you, hope to hear feedback.
This is the thermal image
and the real measurement 
and the real measurement 
here is the error 

the coding looks so not right i know
This is my current code
% read the original image
I = imread('defects1.png');
% call createMask function to get the mask and the filtered image
[BW,maskedRGBImage] = createMask(I);
% plot the original image, mask and filtered image all in one figure
%subplot(1,3,1);imshow(I);title('Original Image');
%subplot(1,3,2);
imshow(BW);title('Mask');
%subplot(1,3,3);imshow(maskedRGBImage);title('Filtered Image');
mask = grayImage > someValue;
mask = bwareafilt(mask, 13); % Take 13 largest blobs.
imshow(mask);
hold on;
props = regionprops(mask, 'Centroid');
xy = certcat(props.Centroid);
for k = 1 : size(xy, 1)
caption = sprintf(' %d', k);
plot(xy(k, 1), xy(k, 2), 'r+', 'MarkerSize', 20);
text(caption, xy(k, 1), xy(k, 2), 'Color', 'r', 'FontWeight', 'bold', 'FontSize', 20);
end
distances = pdist2(xy, xy)
%distancesInPixels = pdist2(xy, xy);
%distancesInCm = distancesInPixels * cmPerPixel;
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 18-Feb-2021
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.049;
channel1Max = 0.160;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.000;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.000;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
採用された回答
Image Analyst
2021 年 2 月 21 日
Try this:
% Initialization steps.
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 = 13;
% read the original image
rgbImage = imread('defects1.png');
% Display the image.
subplot(2, 2, 1);
imshow(rgbImage);
axis('on', 'image');
title('Original RGB Image', 'FontSize', fontSize);
impixelinfo;
% call createMask function to get the mask and the filtered image
[mask,maskedRGBImage] = createMask(rgbImage);
% Display the image.
subplot(2, 2, 2);
imshow(mask);
axis('on', 'image');
impixelinfo;
title('Mask', 'FontSize', fontSize);
subplot(2, 2, 3);
% Take 13 largest blobs.
mask = bwareafilt(mask, 13);
imshow(mask);
hold on;
% Make measurements.
props = regionprops(mask, 'Centroid');
xy = vertcat(props.Centroid);
for k = 1 : size(xy, 1)
x = xy(k, 1);
y = xy(k, 2);
caption = sprintf(' %d', k);
plot(x, y, 'r+', 'MarkerSize', 20);
text(x, y, caption, 'Color', 'r', 'FontWeight', 'bold', 'FontSize', 20);
end
g = gcf;
g.WindowState = 'maximized';
distances = pdist2(xy, xy)
%distancesInPixels = pdist2(xy, xy);
%distancesInCm = distancesInPixels * cmPerPixel;
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 18-Feb-2021
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.049;
channel1Max = 0.160;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.000;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.000;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end

18 件のコメント
Faiz Yusoff
2021 年 2 月 21 日
Great solution. But now i have problem reading the distance, im not sure which relation distances meant by the answer. Could you explain a bit.
One more thing, i need to declare the diameter of the blops too.

The distances array is the distance from blob #(row number) to blob #(column number). For example, the value at distances (3,5) is the distance from the blob numbered #3 to the blob numbered #5.
To get the areas:
props = regionprops(mask, 'Centroid', 'Area'); % Add in 'Area' to also compute the area.
allAreas = [props.Area]
Faiz Yusoff
2021 年 2 月 21 日
Okay i think i got it. So now the diameters and the distances is in pixel isn't?
How do i make it turn into millimeter(mm) automatically.
If i need to find the pixel frame size or whatsoever, how im gonna do that sir.
Coming out of regionprops(), everything is in pixels. You have to multiple distance measurements by the number of mm per pixel and the area by (mm per pixel)^2.
props = regionprops(mask, 'Centroid', 'Area', 'EquivDiameter'); % Add in 'Area' to also compute the area.
allAreasInPixels = [props.Area]
allAreasInMm = allAreasInPixels * mmPerPixel ^ 2
allDiamsInMm = [props.EquivDiameter] * mmPerPixel ^ 2
To find the frame size in pixels you can use size()
[rows, columns, numberOfColorChannels] = size(rgbImage);
Faiz Yusoff
2021 年 2 月 27 日
I tried to convert the pixel size into mm but it failed. Could you help me using the reference lenght that i gave in the question.
Image Analyst
2021 年 2 月 27 日
Do you know your field of view? Or the distance between any of the spots?
Faiz Yusoff
2021 年 3 月 2 日
I have no idea what is that. You mean actual distance between the the spots? As i attached at question? The actual measurement
My code gives you the centroid of each spot. To find the distance in pixels between each spot and every other spot, do this
distances = pdist2(xy, xy);
Faiz Yusoff
2021 年 3 月 3 日
i mean i already got the distance between each spot. I just dont get it how to convert from pixel to milimetres.
And as addition, i want to get the x and y for the each centroid. how would i do that
Faiz Yusoff
2021 年 3 月 10 日
I want to add addiotional measurement which is the x, y of every centroid of cirlces. So i could display area, distance and also x,y. could you help me?
Faiz Yusoff
2021 年 3 月 10 日
I attached the spatial calibration that ive done.. Is that correct? How i want to insert to my codiing so i could convert my disntace automatically.
Faiz Yusoff
2021 年 3 月 13 日
@Image Analyst Could you help me to figure this out. Ive been stucked with these problems. Thank you so much.
Image Analyst
2021 年 3 月 13 日
編集済み: Image Analyst
2021 年 3 月 13 日
I'm not sure where your difficulty lies. Simply multiply the coordinates or distances by the value of mmPerPixel.
Add to the end of my program this code:
distances = pdist2(xy, xy);
mmPerPixel = 1.716565;
distancesInMM = distances * mmPerPixel;
xInMM = x * mmPerPixel;
yInMM = y * mmPerPixel;
Full demo attached.
Faiz Yusoff
2021 年 3 月 14 日
I have tried using the full demo test7. But it does not show anything in the command window.
So i tried to add the value of the distance mmPerPixel in the previous code that you gave me, but it does not change any value (supposed to convert the value from pixel to mm) in the command window. Is there anything wrong?
% Initialization steps.
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 = 13;
% read the original image
rgbImage = imread('defects1.png');
% Display the image.
subplot(2, 2, 1);
imshow(rgbImage);
axis('on', 'image');
title('Original RGB Image', 'FontSize', fontSize);
impixelinfo;
% call createMask function to get the mask and the filtered image
[mask,maskedRGBImage] = createMask(rgbImage);
% Display the image.
subplot(2, 2, 2);
imshow(mask);
axis('on', 'image');
impixelinfo;
title('Mask', 'FontSize', fontSize);
subplot(2, 2, 3);
% Take 13 largest blobs.
mask = bwareafilt(mask, 13);
imshow(mask);
hold on;
% Make measurements.
props = regionprops(mask, 'Centroid');
xy = vertcat(props.Centroid);
props = regionprops(mask, 'Centroid', 'Area'); % Add in 'Area' to also compute the area.
allAreas = [props.Area]
for k = 1 : size(xy, 1)
x = xy(k, 1);
y = xy(k, 2);
caption = sprintf(' %d', k);
plot(x, y, 'r+', 'MarkerSize', 20);
text(x, y, caption, 'Color', 'r', 'FontWeight', 'bold', 'FontSize', 20);
end
g = gcf;
g.WindowState = 'maximized';
distances = pdist2(xy, xy)
mmPerPixel = 1.716565;
distancesInMM = distances * mmPerPixel;
xInMM = x * mmPerPixel;
yInMM = y * mmPerPixel;
%distancesInPixels = pdist2(xy, xy);
%distancesInCm = distancesInPixels * cmPerPixel;
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 18-Feb-2021
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.049;
channel1Max = 0.160;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.000;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.000;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
Faiz Yusoff
2021 年 3 月 14 日
Ok now i think i get it, just need to drag it from the workspace isn't? It was there all the time.
Now that i converted the distance between those circles. How im going to convert the allAreasInMM and the xyInMM ?

They're in variables. Using them you can do anything you want with them, like typing the variable name into the command window to display it, or writing them to a file with writematrix(), or whatever you want to do.
To convert areas you need to multiply by mmPerPixel squared
areasInMm = areasInPixels * mmPerPixel ^2;
Faiz Yusoff
2021 年 3 月 14 日
So maybe i just put the variable into the code like this;
mmPerPixel = 1.716565;
distancesInMM = distances * mmPerPixel;
xInMM = x * mmPerPixel;
yInMM = y * mmPerPixel;
allAreasInMM = allAreas * mmPerPixel;
xyInMM = xy * mmPerPixel;
Faiz Yusoff
2021 年 3 月 14 日
oh i think i made mistake at areas.. Should just follow your code.
How about the xyInMM, is that correct?
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Image Processing Toolbox についてさらに検索
参考
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)
