Search code examples
matlabimage-processingedge-detection

MATLAB: Smooth curves on tilted edges - Edge Detection (Polyfit or fitPolynomialRANSAC?)


i have images with bands. The bands are not always 100% straight and not always 100% horizontal. They can be tilted and bent. Each band has a constant width. I need the width of each band on the image and show the edges of each band as smooth as possible: Example_edge_detection.png Example_straight.png Example_tilted.png

I have already a solution for 100% straight-horizontal bands. But i dont know how to do it with tilted bands. Maybe Polyfit or houghlines are needed? Please help me. Thank You!

Here the working code for the straight-horizontal bands!

clc;    
close all;  
clear;  
workspace;  
format long g;
format compact;
fontSize = 20;

folder = pwd;
baseFileName = 'Example_straight.png';
grayImage = imread(baseFileName);
[rows, columns, numberOfColorChannels] = size(grayImage);

if numberOfColorChannels > 1
    grayImage = min(grayImage, [], 3);
end

hFig = gcf;
hFig.WindowState = 'maximized';
grayImage = adapthisteq(grayImage);
verticalProfile = mean(grayImage, 2);
threshold = 118;

binaryImage = imfill(grayImage < threshold, 'holes');
% Take the 3 largest blobs
binaryImage = bwareafilt(binaryImage, 3);
% Snip off small tendrils using imopen()
binaryImage = imopen(binaryImage, true(1, 3));
% Take the 3 largest blobs
binaryImage = bwareafilt(binaryImage, 3);
subplot(1, 1, 1);
imshow(baseFileName);
hFig = gcf;
hFig.WindowState = 'maximized'; % 
axis('on', 'image');
title('Edge Detection', 'FontSize', fontSize, 'Interpreter', 'None');

binaryProfile = (verticalProfile > threshold)';
bandStarts  = strfind(binaryProfile, [0, 1]);
bandStops = strfind(binaryProfile, [1, 0]);
for k = 1 : length(bandStarts)
    yline(bandStarts(k), 'Color', 'r', 'LineWidth', 1);
    yline(bandStops(k), 'Color', 'r', 'LineWidth', 1);
end

Solution

  • It looks like your algorithm currently just does a simple threshold to find horizontal lines, where the threshold is applied to the difference in the mean horizontal pixel value between two adjacent rows. If that's good enough to get the job done, that's good enough for me.

    As for non-horizontal lines, maybe you can try a routine like this to simply straighten out the image first.