3
votes

Problem: Find an unwanted line in an image using Hough transform.

enter image description here

I have done the following,

  1. Apply directional filter to analyze 12 different directions, rotated with respect to 15° each other.
  2. Apply thresholding to obtain 12 binary images.

enter image description here

Now, I need to select either of those two images marked in yellow. Coz, the lines in those two images are the most prominent.

I have tried the following code. It doesn't seem to be working.

MATLAB Code

    %   Read 12 images into workspace.
input_images  = {imread('1.png'),imread('2.png'),imread('3.png'),...
    imread('4.png'),imread('5.png'),imread('6.png'),...
    imread('7.png'),imread('8.png'),imread('9.png'),...
    imread('10.png'),imread('11.png'),imread('12.png')};

longest_line = struct('point1',[0 0], 'point2',[0 0], 'theta', 0, 'rho', 0);

for n=1:12
    %Create a binary image.
    binary_image = edge(input_images{n},'canny');

    %Create the Hough transform using the binary image.
    [H,T,R] = hough(binary_image);

    %Find peaks in the Hough transform of the image.
    P  = houghpeaks(H,3,'threshold',ceil(0.3*max(H(:))));

    %Find lines
    hough_lines = houghlines(binary_image,T,R,P,'FillGap',5,'MinLength',7);         
    longest_line = FindTheLongestLine(hough_lines, longest_line);
end


% Highlight the longest line segment by coloring it cyan.
plot(longest_line.point1, longest_line.point2,'LineWidth',2,'Color','cyan');

.

Relevant Source Code

function longest_line = FindTheLongestLine( hough_lines , old_longest_line)
%FINDTHELONGESTLINE Summary of this function goes here
%   Detailed explanation goes here
    longest_line = struct('point1',[0 0] ,'point2',[0 0],'theta', 0, 'rho', 0);

    max_len = 0;

    N = length(hough_lines);

    for i = 1:N
       % Determine the endpoints of the longest line segment
       len = LenthOfLine(hough_lines(i));

       if ( len > max_len)
          max_len = len;
          longest_line = hough_lines(i);
       end
    end

    old_len = LenthOfLine(old_longest_line);
    new_len = LenthOfLine(longest_line);

    if(old_len > new_len)
       longest_line =  old_longest_line;
    end
end

function length = LenthOfLine( linex )
%LENTHOFLINE Summary of this function goes here
%   Detailed explanation goes here

    length = norm(linex.point1 - linex.point2);
end

Test Images

Here are the 12 images, drive.google.com/open?id=0B-2FDw63ZNTnRnEzYlNyS0V4YVE

2
Can you explain the problem with your code and/or the provided answer? - m7913d
@m7913d, my code is failing to select the desired specific line. I couldn't make the given answer work also. - user366312
What is the output of your algorithm? Can you upload the binary images separately? Instead of looking for the longest line, it may be useful to select the line with the highest hough transform value. - m7913d
As perhaps an aside, I'm not sure if it's just the captions which are wrong, but you are not rotating by 15° if your angles are pi/1, pi/2, pi/3, ..., pi/12. Instead you want to use pi*(1/12), pi*(2/12), pi*(3/12), ..., pi*(12/12). Also "I couldn't make the given answer work" is very loose. It seems to do exactly what you want, so show us perhaps how you implemented it and why it doesn't work. - Wolfie

2 Answers

1
votes

The problem with your code is the FillGap property of houghlines. You should allow larger gaps in the returned lines, because the searched line does not need to be continuous, e.g. 500:

hough_lines = houghlines(binary_image,T,R,P,'FillGap',500,'MinLength',7);

This finds the largest line in image 7 as desired.

Visualisation

To plot the found line on top of the image, you can use the following code:

figure
imshow(input_images{7});
hold on
% Highlight the longest line segment by coloring it cyan.
plot([longest_line.point1(1) longest_line.point2(1)], [longest_line.point1(2) longest_line.point2(2)],'LineWidth',2,'Color','cyan');

enter image description here

Finding maximum peak in Hough Transform

As an alternative, you may consider to select the line corresponding to the largest Hough Transform value, instead of the longest line. This can be done by selecting the longest_line as follows:

longest_line = ...
largest_H = 0; % init value

for n=1:12
    binary_image = edge(input_images{n},'canny');
    [H,T,R] = hough(binary_image);
    P  = houghpeaks(H,1,'threshold',ceil(0.3*max(H(:))));
    hough_lines = houghlines(binary_image,T,R,P,'FillGap',500,'MinLength',7);         

    if (largest_H < H(P(1, 1), P(1, 2)))
        largest_H = H(P(1, 1), P(1, 2));
        longest_line = hough_lines(1);
        longest_line.image = n;
    end
end

This selects the following line in image 6, which is the other allowed outcome:

enter image description here

1
votes

you can try changing the Hough functions' parameters according to your specific problem, it's not a perfect solution but it may be good enough for you:

img = im2double(rgb2gray(imread('line.jpg')));
% edge image
BW = edge(img,'canny');
% relevant angles (degrees) interval for the line you want
thetaInterval = -80:-70;
% run hough transform and take single peak
[H,T,R] = hough(BW,'Theta',thetaInterval);
npeaks = 1;
P = houghpeaks(H,npeaks);
% generate lines
minLen = 150; % you want the long line which is ~250 pixels long
% merge smaller lines (same direction) within gaps of 30 pixels
fillGap = 30; 
lines = houghlines(BW,T,R,P,'FillGap',fillGap,'MinLength',minLen );
% plot
imshow(img);
hold on
xy = [lines.point1; lines.point2];
plot(xy(:,1),xy(:,2),'g','LineWidth',2);

enter image description here