Recognize edges in mosaic-like background - draw horizontal lines and save line coordinates

1 view (last 30 days)
Hello,
I am looking for a good automated method to find the edges of the horizontal gray surfaces in the mosaic background. The edges should be displayed with horizontal lines (like Sample.jpg). The gray surfaces could be a little tilted, but it's enough for me if the lines are displayed horizontally,
Thx

Accepted Answer

Image Analyst
Image Analyst on 8 Nov 2023
Try this. (Similar to @Les Beckham's solution but developed before I saw his answer):
% Demo by Image Analyst
% https://www.mathworks.com/matlabcentral/answers/2044247-recognize-edges-in-mosaic-like-background-draw-horizontal-lines-and-save-line-coordinates?s_tid=srchtitle
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 = [];
baseFileName = 'sample 1.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);
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% 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)
if numberOfColorChannels == 3
grayImage = rgb2gray(grayImage);
end
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
g.Name = 'Demo by Image Analyst';
g.NumberTitle = 'off';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get the mean vertical profile of the standard deviation of each row.
verticalProfile = std(single(grayImage), 0, 2);
% Smooth out noise but leave big dips
verticalProfile = movmedian(verticalProfile,61);
subplot(2, 2, 2);
plot(verticalProfile, 'b-', 'LineWidth', 2);
title('Standard Deviation Row-by-Row', 'FontSize', fontSize, 'Interpreter', 'None');
xlabel('Row of Image', 'FontSize', fontSize, 'Interpreter', 'None');
ylabel('Standard Deviation', 'FontSize', fontSize, 'Interpreter', 'None');
grid on;
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get mask by thresholding at 62.
grayRegions = verticalProfile' <= 62;
% Get tops
topLines = strfind(grayRegions, [0, 1])
% Get bottoms
bottomLines = strfind(grayRegions, [1, 0])
subplot(2, 2, 3);
imshow(grayImage, []);
axis('on', 'image');
hold on;
% Draw line at edges
for k = 1 : numel(topLines)
yline(topLines(k), 'Color', 'y', 'LineWidth', 3);
end
for k = 1 : numel(bottomLines)
yline(bottomLines(k), 'Color', 'y', 'LineWidth', 3);
end
title('Edges Identified', 'FontSize', fontSize, 'Interpreter', 'None');
  4 Comments
Les Beckham
Les Beckham on 10 Nov 2023
Thanks for all of your excellent contributions to this forum and for teaching me (and, hopefully, the OP).
It was gratifying to see that my naive thoughts about how to approach this were not to far off the mark (probably from all of the reading I have done on this forum).

Sign in to comment.

More Answers (1)

Les Beckham
Les Beckham on 7 Nov 2023
Big caveat: I'm not even close to an image processing expert so there is probably a smarter way to do this.
I noticed that the two bands seem to have a more uniform grey, while the rest of the fabric (?) is more black and white, so I decided to use the standard deviations of the rows to look for the edges.
im = imread('1.jpg');
img = im2gray(im);
ims = imshow(img);
rowmean = mean(img, 2);
rowstd = std(double(img), 0, 2);
plot(rowstd)
xline([280 385 805 930]) % <<< I experimented with changing these numbers to line up on the "edges"
grid on
Now I've found the row numbers in the image that define the "edges".
Unfortunately, I couldn't figure out how to draw the lines on top of the image.
  1 Comment
Tommy Schumacher
Tommy Schumacher on 8 Nov 2023
its a good idea with the mean function but its not a automated solution. With your approach I have to determine the line coordinates manually. I am looking for an solution that automatically determines the lines (coordinates)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!