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
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]
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);
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.
Do you know your field of view? Or the distance between any of the spots?
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);
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
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?
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.
@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.
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
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;
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;
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!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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)
