MATLAB Answers

Pixel to Area conversion accruacy issue with Matlab and im2bw function

19 views (last 30 days)
Mahdi Tlemsani
Mahdi Tlemsani on 5 Jul 2020 at 22:16
Answered: Image Analyst on 5 Jul 2020 at 22:42
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.

  0 Comments

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 5 Jul 2020 at 22:42
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.

  0 Comments

Sign in to comment.

More Answers (0)


Translated by