Pixel to Area conversion accruacy issue with Matlab and im2bw function

1 visualización (últimos 30 días)
I am reformatting and reposting this question to hopefully make it easier for more people to help.
I am writing a short Matlab script to use im2bw to calculate the area of objects in the image. I am trying to validate that the areas are being calculated correctly, but on the reference image I am using the last square's area is 2% off and I cannot figure out why.
myFolder = 'Your Directory';
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, '*.png'); % Change to whatever pattern you need.
theFiles = dir(filePattern);
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(theFiles(k).folder, baseFileName);
J = imread(fullFileName);
%J = imcrop(I,[500,200,4400,3500]);
BW = im2bw(J,0.3);
BW2 = imcomplement(BW);
BW3 = imfill(BW2,4,'holes');
%figure(1)
%imshowpair(I,BW3,'montage')
stats = regionprops(BW3,'area','PixelList','majoraxislength','minoraxislength');
area = zeros(size(stats));
for i = 1:size(stats,1)
area(i) = stats(i).Area;
end
scale = 1e-6;
%scale = 3.134755344e-8;
cutoff = 0;
area = area*scale;
stats(area<cutoff)=[];
area(area<cutoff)=[];
writematrix(area,'Your Directory','WriteMode','append')
end
figure(1)
imshowpair(J,BW3,'montage')
The image is 1000x1000 with 20x20, 100x100, 100x200, and 200x200 squares that I use as a reference.
I assumed the reference image in reality was 1mx1m and scaled accordingly, but the 200x200 square seems to not come out exactly right. The result is 0.0392 when it should be 0.04.
Additionally I have some issues overall with the accuracy of the im2bw function when trying to calculate area using other images, where I get 10-20% error. Any insights into this issue would be awesome as well.

Respuesta aceptada

Image Analyst
Image Analyst el 5 de Jul. de 2020
As you can see from this corrected code:
clc; % Clear the command window.
fprintf('Beginning to run %s.m ...\n', mfilename);
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 22;
myFolder = pwd; % 'Your Directory';
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, 'ar*.png'); % Change to whatever pattern you need.
theFiles = dir(filePattern)
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(theFiles(k).folder, baseFileName);
rgbImage = imread(fullFileName);
%J = imcrop(I,[500,200,4400,3500]);
BW = im2bw(rgbImage,0.3);
BW2 = imcomplement(BW);
BW3 = imfill(BW2,4,'holes');
stats = regionprops(BW3,'area','PixelList','BoundingBox');
areaInPixels = [stats.Area]
bb = vertcat(stats.BoundingBox);
allWidthsInPixels = bb(:, 3)
allHeightInPixels = bb(:, 4)
scale = 1e-6;
areaInMm = areaInPixels * scale
% %scale = 3.134755344e-8;
% cutoff = 0;
% stats(areaInMm<cutoff)=[];
% areaInMm(areaInMm<cutoff)=[];
%
% writematrix(areaInMm,'Your Directory','WriteMode','append')
end
% figure(1)
% imshowpair(rgbImage,BW3,'montage')
fprintf('Done running %s.m ...\n', mfilename);
The areas, widths, and heights are
areaInPixels =
400 10000 20000 39204
allWidthsInPixels =
20
100
200
198
allHeightInPixels =
20
100
100
198
areaInMm =
0.0004 0.01 0.02 0.039204
so your last rectangle is not 200x200, it's 198x198.
It is probably because your large rectangle is ringed with a value of 127, unlike the other rectangles, and that 127 is below the threshold so it's not considered part of the blob. Why does only that one blob have a one pixel wide layer of 127 surrounding it?
Try a manual threshold instead.
BW = rgbImage(:, :, 1) < 255;
imshow(BW);
% BW2 = imcomplement(BW);
% BW3 = imfill(BW2,4,'holes');
BW3 = imfill(BW,4,'holes');
That will work.

Más respuestas (0)

Productos


Versión

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by