Distance between bubble and tube

1 vue (au cours des 30 derniers jours)
Rhandrey Maestri
Rhandrey Maestri le 17 Sep 2022
Commenté : Image Analyst le 4 Oct 2022
hi there!
I am currently doing project on image processing in matlab, in which I'm assigned to calculate the distance between two object automatically. Following the image. Can you tell me how to detect the bubble border(black region) and the tube wall(this black line near the bubble). And then calculate the distance between the border of the bubble and the closest wall pixel near this bubble?
Also if I know that the inside diameter is 15 mm. Can I have this distances in mm? I'd very appreciate your suggestions
Sincrely

Réponse acceptée

Image Analyst
Image Analyst le 17 Sep 2022
Hopefully you tried it and got something like I did:
% 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 = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = [];
baseFileName = 'bubble.jpg';
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
grayImage = 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)
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
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 = grayImage(:, :, 3);
end
% Update 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)
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Display the histogram.
subplot(2, 2, 2);
histogram(grayImage(grayImage>0), 256);
grid on;
title('Histogram of Image Gray Levels', 'FontSize', fontSize, 'Interpreter', 'None');
% Threshold the image to get the dark stuff.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
lowThreshold = 0;
highThreshold = 125;
% [lowThreshold, highThreshold, lastThresholdedBand] = threshold(lowThreshold, highThreshold, grayImage)
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Take 5 largest blobs
mask = bwareafilt(mask, 5, 'largest');
% Take 3 smallest blobs
mask = bwareafilt(mask, 3, 'smallest');
% Fill in the bubble so that it will have only 3 sides.
mask = imfill(mask, 'holes');
subplot(2, 2, 3);
imshow(mask)
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Label the mask so that we can get leftmost and rightmost columns of each blob.
labeledImage = bwlabel(mask);
% Scan down getting right edge of left tube wall
% and left edge of right tube wall.
leftTubeEdgeColumn = nan(rows, 1);
rightTubeEdgeColumn = nan(rows, 1);
rightBubbleEdgeColumn = nan(rows, 1);
leftBubbleEdgeColumn = nan(rows, 1);
for row = 1 : rows
% Find left wall of tube.
col = find(labeledImage(row, :) == 1, 1, 'last');
if ~isempty(col)
leftTubeEdgeColumn(row) = col;
end
% Find right wall of tube.
col = find(labeledImage(row, :) == 3, 1, 'last');
if ~isempty(col)
rightTubeEdgeColumn(row) = col;
end
% Find left wall of bubble.
col = find(labeledImage(row, :) == 2, 1, 'first');
if ~isempty(col)
leftBubbleEdgeColumn(row) = col;
end
% Find right wall of bubble.
col = find(labeledImage(row, :) == 2, 1, 'last');
if ~isempty(col)
rightBubbleEdgeColumn(row) = col;
end
end
% Display lines over original image.
subplot(2, 2, 1);
hold on;
y = 1 : rows;
plot(leftTubeEdgeColumn, y, 'r-', 'LineWidth',2);
plot(rightTubeEdgeColumn, y, 'r-', 'LineWidth',2);
plot(leftBubbleEdgeColumn, y, 'r-', 'LineWidth',2);
plot(rightBubbleEdgeColumn, y, 'r-', 'LineWidth',2);
% Get the tube widths
tubeWidths = rightTubeEdgeColumn - leftTubeEdgeColumn;
% Get the mean
meanTubeWidth = mean(tubeWidths);
% It's 15 mm so compute spatial calibration factor.
mmPerPixel = 15 / meanTubeWidth
% Get the widths to the left and right of the bubble in millimeters.
leftWidths = (leftBubbleEdgeColumn - leftTubeEdgeColumn) * mmPerPixel;
rightWidths = (rightTubeEdgeColumn - rightBubbleEdgeColumn) * mmPerPixel;
% Combine to get all widths.
allWidths = [leftWidths; rightWidths];
% Show histogram of widths.
subplot(2, 2, 4);
numberOfBins = 20;
histogram(allWidths, numberOfBins, "Normalization","pdf");
grid on;
title('Histogram of bubble-to-tube spacings', 'FontSize',fontSize);
xlabel('Spacing in millimeters', 'FontSize',fontSize);
ylabel('Relative Frequency', 'FontSize',fontSize);
  4 commentaires
Rhandrey Maestri
Rhandrey Maestri le 4 Oct 2022
Hi again, Would have time to explain me why doesn´t work with this image?
With some images I just had to change the Threshold levels by try and error (btw, How to choose the best levels?)
Also, Why did you choose 5 largest blobs then 3 smallest blobs?
I'd very appreciate your suggestion
Image Analyst
Image Analyst le 4 Oct 2022
There is lots of noise in there. Lots of small dark specks. Your original image also had big dark regions on the side, outside the thick dark lines. So I can't just take the largest blob, or 3 largest blobs because I'd get those large outer regions. So I get the 5 largest, and then the 3 smallest to throw out the two large outer regions. Just display the mask after each change in mask and see how it looks as you step through it.
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
imshow(mask)
% Take 5 largest blobs
mask = bwareafilt(mask, 5, 'largest');
imshow(mask)
% Take 3 smallest blobs
mask = bwareafilt(mask, 3, 'smallest');
imshow(mask)
% Fill in the bubble so that it will have only 3 sides.
mask = imfill(mask, 'holes');
subplot(2, 2, 3);
imshow(mask)
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');

Connectez-vous pour commenter.

Plus de réponses (1)

Image Analyst
Image Analyst le 17 Sep 2022
Did you try the algorithm I suggested? Looks like not. OK, here try this first.
  1. Threshold with imbinarize to get black areas as "true" and light areas as false.
  2. Use bwareafilt(mask, 5) to get the 5 largest blobs.
  3. Use bwareafilt() again to extract the 3 smallest blobs.
  4. Call imfill(mask, 'holes');
  5. Scan down the image row by row finding the edges of the lines and bubble.
  6. Compute the distances you want. The distance at the top where there is no bubble will let you compute a spatial calibration factor.
I might have time later today if you still need help.
  2 commentaires
Rhandrey Maestri
Rhandrey Maestri le 17 Sep 2022
Sorry, I posted here before I see your other comment. I'll try it now.
Thanks for your suggestions
Rhandrey Maestri
Rhandrey Maestri le 17 Sep 2022
I followed your algorithm and it seems I managed to get the wall and the bubble. Thanks It is helping me a lot.
But it seems there is some information on the right part of the image that is been considered wall. I could not go forward yet.
Can you tell me how to remove this information of the wall variable?
Thanks
clear all
%% Read in Images
img1 = imread ('ImageOriginal.jpg');
%% Display Color Images
figure
imshow(img1)
%% Threshold with imbinarize to get black areas as "true" and light areas as false.
img1BW = rgb2gray(img1);
BW = imbinarize(img1BW);
imtool(BW)
%% Use bwareafilt(mask, 5) to get the 5 largest blobs.
BW2 = bwareafilt(BW, 5);
%imtool(BW2)
%% Use bwareafilt() again to extract the 3 smallest blobs.
BW3 = bwareafilt(BW2,3,'smallest');
%imtool(BW3)
%% Call imfill(mask, 'holes');
Walls = imfill(BW3, 'holes');
%% bubble
Bubble = -BW3 + Walls;
Bubble2 = imfill(Bubble, 'holes');
BubbleFilled = bwareaopen (Bubble2, 15);
figure
imshow (BubbleFilled)
%imtool(Bubble2)
%% Scan down the image row by row finding the edges of the lines and bubble.
E = edge(Walls,'Canny');
Eb = edge(BubbleFilled,'Canny');
[x, y] = find(E);
[xb, yb] = find(Eb);
%% Compute the distances you want.
%The distance at the top where there is no
%bubble will let you compute a spatial calibration factor.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by