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
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
Image Analyst 2021년 2월 21일

0 개 추천

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
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
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
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.
Do you know your field of view? Or the distance between any of the spots?
Faiz Yusoff
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
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
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
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
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
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
Faiz Yusoff
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;
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
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에 대해 자세히 알아보기

질문:

2021년 2월 21일

댓글:

2021년 3월 14일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by