Identify specific rectangular shape in image and measure distance

9 Ansichten (letzte 30 Tage)
I'd like to be able to identify a specific rectangle within my image, because I would then like to meake a measurement from the edge of the image to the upper boundary of this rectangle.
I will have several images of the same object containing the rectangle from several differnet imaging systems. The orientation and position of the object should always be very close to as it appears in these examples, but it will be aligned by hand so there may be some small differences.
My image looks like this, and I am after the long thin horizontal band in the center of the image:
Ultimately, I want to make the measurement in yellow- from the top of the image to the top of the horizontal rectangle in the center of the image drawn in red.
I am having trouble segmenting out the rectangle- I don't have much expereince and have tried some simple thresholding and morphology but have not been succressful. I've attached a couple different example images. Perhaps I need to look into some sort of edge detection? If the object is grossly misaligned, the measurement is useless anyway, so perhps an inital crop could work. Thaniks for any help or insights.

Akzeptierte Antwort

Image Analyst
Image Analyst am 4 Jan. 2024
Try this. Adapt as needed.
% 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 = 20;
%--------------------------------------------------------------------------------------------------------
% READ IN TEST IMAGE
folder = pwd;
baseFileName = "marcus.png";
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
end
% Read in image file.
grayImage = imread(fullFileName);
% Get size
[rows, columns, numberOfColorChannels] = size(grayImage)
rows = 650
columns = 649
numberOfColorChannels = 3
if numberOfColorChannels == 3
% If it's color, convert to gray scale.
grayImage = rgb2gray(grayImage);
end
% Display the image.
subplot(2, 1, 1);
imshow(grayImage);
axis('on', 'image');
impixelinfo;
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
g.Name = 'Demo by Image Analyst';
g.NumberTitle = 'off';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get the mean across columns
verticalProfile = mean(grayImage, 2);
% Erase top and bottom parts.
line1 = 262;
line2 = 362;
maxGL = max(grayImage(line1:line2, :), [], 'all')
maxGL = uint8 255
verticalProfile(1 : line1) = maxGL;
verticalProfile(line2 : end) = maxGL;
y = 1 : rows;
subplot(2, 1, 2);
plot(verticalProfile, y, 'b-', 'LineWidth', 2);
grid on;
title('Vertical Profile', 'FontSize',fontSize);
xlabel('Mean Intensity', 'FontSize',fontSize);
ylabel('Row', 'FontSize',fontSize);
%--------------------------------------------------------------------------------------------------------
% Find the first place where the mean drops below 140.
threshold = 140;
topRow = find(verticalProfile < threshold, 1, 'first')
topRow = 313
% Draw a red line at the threshold.
xline(threshold, 'Color', 'r', 'LineWidth', 2)
% Draw a red line going across the average black lines height.
subplot(2, 1, 1);
yline(topRow, 'Color', 'r', 'LineWidth', 2)
% Draw a yellow line there
xMid = columns/2;
line([xMid, xMid], [1, topRow], 'Color', 'y', 'LineWidth', 2);
  3 Kommentare
Image Analyst
Image Analyst am 13 Jan. 2024
One thing to try is to find the mean of the first image we used. Then for other images, standardize the intensity by dividing the image by it's mean intensity (to get it to the range 0-1) and then multiply by the intensity of the first image. That way all images should have the same intensity.
Or you could try imhistmatch
Marcus Glover
Marcus Glover am 18 Jan. 2024
Thank you. The mean approach did not work for all cases, but I was able to get things working using imhistmatch. I am using it on the entire image but I may try to crop a smaller section out of thr center of the image and see if that improves the matching.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by