Different thresholds for binarization of image

8 views (last 30 days)
Hello, guys! The problem is as following:
I have to binarize image of an ice droplet (image 1), however simple thresholding with function graytresh (see image 2) does not meet all the complexities of the case. As you see from the image 2 in the bottom part conturs of the droplet are lost. As far as I can understand, the contrast of ice and background/surface is different at top and bottom, that is why automatic thresholding does not help. However, I am beginner and I am kinda confused and don't know how to solve this problem. I think that I have to divide image into the blocks with manually set borders and for each block give different threshold for the binarization. Could you explain how can I do that?

Answers (2)

Image Analyst
Image Analyst on 28 Mar 2022
Try this:
% 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 = 16;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'ice.png';
% baseFileName = 'image_2732.png';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% 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
end
rgbImage = 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(rgbImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgbImage(:, :, 3);
else
grayImage = rgbImage;
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 1, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Binarize the image to get a mask.
mask = imbinarize(grayImage);
% Erase everything outside +/- 50 pixels from the center.
middleColumn = columns/2;
column1 = middleColumn - 50;
column2 = middleColumn + 50;
mask(:, 1:column1) = false;
mask(:, column2:end) = false;
% Display mask image.
subplot(2, 1, 2);
imshow(mask);
hold on;
impixelinfo;
axis('on', 'image');
drawnow;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Find the top-most pixel
[y, x] = find(mask);
[yTop, indexOfTop] = min(y)
xTop = x(indexOfTop)
% Draw red lines
yline(yTop, 'Color', 'r', 'LineWidth', 2);
xline(xTop, 'Color', 'r', 'LineWidth', 2);
caption = sprintf('Binary Image. Top at (x,y) = (%d, %d)', xTop, yTop);
title(caption, 'FontSize', fontSize);
% Tell the user
message = sprintf('Done!\n');
uiwait(helpdlg(message))
  4 Comments
Nijat Azimzade
Nijat Azimzade on 30 Mar 2022
Sorry, I did not mention it, because I was not expecting such a complicated code, but I will also need points in the vicinity of the tip point, as I will also calculate tip angle. Does your code preserve the accuracy of the droplet over the line y=200? If not, do not worry, your code anyway gives very interesting approach that I can use at some point. Thank you for your effort!
Image Analyst
Image Analyst on 30 Mar 2022
Not sure what you mean by accuracy of the droplet near the tip. It's as accurate as your threshold is. My code. You can find the coordinates on each side of the tip and use polyfit() to fit them to lines.

Sign in to comment.


Image Analyst
Image Analyst on 27 Mar 2022
Can you get rid of the background clutter? If not, is your camera in a fixed position with respect to the scene so that you could use a fixed mask to basically erase the parts of the image that are background?
I don't think you need to find separate thresholds with blocks. I see no reason why that would help. In fact if a block was inside the droplet, if you forced it to find a threshold there automatically, like with graythresh() it may well pick the wrong one.
What are you going to do assuming you had the droplet well separated? Get the height, width, area, or what?
Another option is to use SegNet to do Deep Learning training on it, but you'd have to have lots (dozens or hundreds) or images where you've drawn/painted the "true" region of interest for each training image.
  1 Comment
Nijat Azimzade
Nijat Azimzade on 28 Mar 2022
Thanks, I will try to remove the background!
After the binarization I want to write a code that will pick minimum (the one on the top) y value for a (given by me) x value from the line of contour of the droplet. Basically it must give me the position of tip.

Sign in to comment.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!