matlabhough-transformhoughlines

Houghlines not reaching edge of image


I am trying to detect all the lines in the following image:

enter image description here

Using the following code I am able to detect almost all lines:

%Find the line detected
I = imread('img3.png');
J = histeq(I);
BW = edge(J,'canny');
[H,T,R] = hough(BW);
P = houghpeaks(H,30,'Threshold',0.7*max(H(:)),'nhoodsize',[5 5]);
lines = houghlines(BW,T,R,P );
figure, imshow(I, []), hold on, max_len = 0;
for k = 1:length(lines)
 xy = [lines(k).point1; lines(k).point2];
 plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
 plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
 plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
 len = norm(lines(k).point1 - lines(k).point2);
 if ( len > max_len)
 max_len = len;
 xy_long = xy;
 end
end
% highlight the longest line segment
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','red');

This gives the following image

enter image description here

However as you can see the lines do not go all the way to the edge of the image. I have tried shrinking the nhood size but this meant double detection of some lines and no extension of lines to the edge. Also is it possible to detect the very top and bottom lines? I understand that these lines won't have as many votes due to them being shorter, I've modified the threshold but end up with spurious diagonal lines and still no detection of the top and bottom lines.

Also how would I set the Houghlines parameter on an unknown image. Here it's quite simple, being able to estimate (roughly) the number of lines I'd expect to see and then moderate around that number.

Thanks in advance


Solution

  • The issue stems from the houghpeaks properties being too restrictive to find the smaller lines segments. The approach I used is to:

    1. use your current code to obtain the angle that the detected lines are at (I just did [lines.theta] and found that theta will be equal to -84)

    2. use again your code but only with that angle included, while relaxing the houghpeaks properties to allow many more lines to be detected.

    3. you'll get many more lines detected that overlap, and we'll discard those by setting a similarity threshold based on their coefficients.

    here's the implementation

    angleList = -84; 
    [H,T,R] = hough(BW, 'Theta', angleList);
    P = houghpeaks(H,80,'Threshold', 0.1*max(H(:)),'nhoodsize',[1 1]);
    lines = houghlines(BW,T,R,P,'FillGap',500,'MinLength',5 );
    
    % just get the eq of the line coef a,b using polyfit (y=a*x+b)
    line_coef= @(x) polyfit([lines(x).point1(1) lines(x).point2(1)],...
                            [lines(x).point1(2) lines(x).point2(2)],1);
    
    for n=1:numel(lines)
        p(:,n)=line_coef(n);
    end
    

    we collect for which line there is a similar one such that the coef distance is below a thershold

    for n=1:numel(lines)-1
         d(:,n) = sum(abs(p(:,n)-p)) <2 ;
    end
    

    d is a symmetric binary correlation matrix, we find all the points in the upper triangular above the diagonal, this are the lines id# that repeat on the same line so we discard them.

    id=find(sum(triu(d,1)));
    lines(id)=[];
    
    %... plot the lines using your code 
    

    enter image description here