# MATLAB: Pixel to Area conversion accruacy issue with Matlab and im2bw function

digital image processingimage analysisimage processingImage Processing ToolboxMATLABpixel area

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 1000×1000 with 20×20, 100×100, 100×200, and 200×200 squares that I use as a reference.
I assumed the reference image in reality was 1mx1m and scaled accordingly, but the 200×200 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.

• 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?
	BW = rgbImage(:, :, 1) < 255;	imshow(BW);% 	BW2 = imcomplement(BW);% 	BW3 = imfill(BW2,4,'holes');	BW3 = imfill(BW,4,'holes');