Identify specific rectangular shape in image and measure distance
10 ビュー (過去 30 日間)
古いコメントを表示
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.
0 件のコメント
採用された回答
Image Analyst
2024 年 1 月 4 日
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)
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')
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')
% 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 件のコメント
Image Analyst
2024 年 1 月 13 日
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
その他の回答 (0 件)
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!