![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/650870/image.png)
What changes should I make to get binary images correctly in order for BoundingBox to grab the ROI correctly?
1 次查看(过去 30 天)
显示 更早的评论
I am not getting the correct binary images of the attached images in order for the BoundingBox to capture the ROI properly. It happens only for a few images most likely due to the pixel values that are thresholded. What modifications would have to be done in the code to get the correct binary image in order to capture the ROI properly for these images. The original images attached are in RGB color. The corresponding binary image are displayed below.
folder = 'I:\converted images\0.5\0.5 2 mm offset';
baseFileName = '0.5 cmc 2mm off0590.tif';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~isfile(fullFileName)
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
fullFileName = fullFileNameOnSearchPath;
end
[grayImage,map] = imread(fullFileName);
grayImage = rgb2gray(grayImage);
imshow(grayImage,map)
binaryImage = ~imbinarize(grayImage);
% Erase from line 758 down:
binaryImage(758:end, :) = false;
% Fill holes.
binaryImage = imfill(binaryImage, 'holes');
% Get rid of any msall noise blobs.
binaryImage = bwareafilt(binaryImage, 1); % Take largest blob only.
imshow(binaryImage)
impixelinfo;
props = regionprops(binaryImage, 'BoundingBox');
spreadingWidth = props.BoundingBox(3)
rectangle('Position', props.BoundingBox, 'Edgecolor', 'g', 'LineWidth', 2)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/650255/image.jpeg)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/650260/image.jpeg)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/650265/image.jpeg)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/650270/image.jpeg)
0 个评论
采纳的回答
Image Analyst
2021-6-12
This seems to work for all the images you attached.
% Demo by Image Analyst
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 = 20;
folder = pwd; 'I:\converted images\0.5\0.5 2 mm offset';
baseFileName = 'image 4.jpg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~isfile(fullFileName)
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
fullFileName = fullFileNameOnSearchPath;
end
[grayImage,map] = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Extract the red channel (so the magenta lines will be white).
grayImage = grayImage(:, :, 1);
end
subplot(2, 3, 1);
imshow(grayImage,map)
axis('on', 'image');
impixelinfo;
title('Original Image', 'FontSize', fontSize);
g = gcf;
g.WindowState = 'maximized';
% Flatten the image
grayImage = adapthisteq(grayImage);
subplot(2, 3, 2);
imshow(grayImage,map)
axis('on', 'image');
impixelinfo;
title('Background Corrected Image', 'FontSize', fontSize);
% Find the top of the bottom dark stripe
leftStrip = grayImage(:, 1:200);
bw = imbinarize(leftStrip);
bw = bwareaopen(bw, 2000);
verticalProfile = mean(bw, 2);
subplot(2, 3, 3);
% imshow(bw);
plot(verticalProfile, 'b-', 'LineWidth', 2);
grid on;
title('Vertical Profile over left-most 200 columns', 'FontSize', fontSize);
xlabel('Row', 'FontSize', fontSize);
ylabel('Gray Level', 'FontSize', fontSize);
% image 1 seems to have a black line at the top, so whiten the first few lines.
meanGL = mean2(grayImage(2 : round(rows/2)))
grayImage(1 : 3, :) = meanGL;
% Now need to recompute vertical profile.
% verticalProfile = mean(grayImage(:, 1:200), 2);
% Erase from line down:
rowToErase = find(verticalProfile > 0.1, 1, 'last')
grayImage(rowToErase:end, :) = meanGL;
subplot(2, 3, 1);
% imshow(grayImage,map)
yline(rowToErase, 'Color', 'y', 'LineWidth', 2);
subplot(2, 3, 2);
yline(rowToErase, 'Color', 'y', 'LineWidth', 2);
% Get histogram between lines 647 and rowToErase
subplot(2, 3, 4);
imhist(grayImage(647:rowToErase, :));
grid on;
title('Histogram of corrected image', 'FontSize', fontSize);
xlabel('Gray Level', 'FontSize', fontSize);
ylabel('PixelCount', 'FontSize', fontSize);
% Binarize the image.
binaryImage = grayImage < 75;
% Fill holes.
binaryImage = imfill(binaryImage, 'holes');
% Get rid of any small noise blobs.
% Don't use bwareafilt() to take largest blob because sometimes the blob is split into two big chunks.
props = regionprops(binaryImage, 'Area');
allAreas = [props.Area]
binaryImage = bwareaopen(binaryImage, 6000); % Take only blobs larger than 5000 pixels.
subplot(2, 3, 5);
imshow(binaryImage)
axis('on', 'image');
impixelinfo;
title('Mask Image', 'FontSize', fontSize);
% Find bounding box.
[r, c] = find(binaryImage);
row1 = min(r)
row2 = max(r)
col1 = min(c)
col2 = max(c)
xline(col1, 'Color', 'r', 'LineWidth', 2);
xline(col2, 'Color', 'r', 'LineWidth', 2);
spreadingWidth = col2 - col1
caption = sprintf('Mask Image. SpreadingWidth = %.1f pixels', spreadingWidth);
title(caption, 'FontSize', fontSize);
% Find the bottom row as the lowest row where the blob hits the side of the bounding box.
% This will let us ignore parts of the blob that are below the outer edges of the blob,
% which seems to be like a reflection of the droplet.
lastRowLeft = find(binaryImage(:, col1), 1, 'last')
lastRowRight = find(binaryImage(:, col2), 1, 'last')
% Draw red lines to edges.
line([1, col1], [lastRowLeft, lastRowLeft], 'Color', 'r', 'LineWidth', 2);
line([col2, columns], [lastRowRight, lastRowRight], 'Color', 'r', 'LineWidth', 2);
% Find the lowest of the two rows.
lastRow = max(lastRowLeft, lastRowRight)
spreadingHeight = lastRow - row1
% Make up a rectangle vector in the form [x, y, width, height]
rectPosition = [col1, row1, spreadingWidth, spreadingHeight]
rectangle('Position', rectPosition, 'Edgecolor', 'g', 'LineWidth', 2)
subplot(2, 3, 2);
rectangle('Position', rectPosition, 'Edgecolor', 'g', 'LineWidth', 2)
g = gcf;
g.WindowState = 'maximized';
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/650870/image.png)
10 个评论
Image Analyst
2021-6-15
It's a 16 bit image in the range 0-65535, not an 8 bit image in the range 0-255, so you need to change the threshold used in getting the binary image from 75 to something that works.
更多回答(1 个)
Image Analyst
2021-6-12
Looks like it's working for the images you gave it, however you gave it improperly segmented images. Sometimes you need to adjust the parameters to imbinarize, threshold it manually, or use a more sophisticated algorithm. Or improve your image capture method to get a better image in the first place.
3 个评论
Image Analyst
2021-6-12
The original ones you posted don't open in Firefox, but these do. I'll try to remember to check them later today. I need to go do something now.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Image Processing and Computer Vision 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!