Hough Transform back to original image

Hi,

 

I am working on identifying lines in an image.  The work flow thus far:

1. Bring in png image and convert it to gray scale.

2. Perform particle analysis to get the major features which are basically rectangles of varying length but the same width that may or may not overlap one another.

3. Use the M_particle wave from particle analysis as input into matrixfilter thin to create a skeleton.

4. Apply the image transform hough on the skeleton image.

 

What I want to do now is use the hot spots in the hough transform to impose the line back onto the skeleton image.  To get the line I use the code from the IP Tutorial (any you thought no-one read the manual -HA!).

Function drawHoughLine(rad,angle)
    Variable rad,angle
    
    wave/z yy
    if(WaveExists(yy)==0)
        Make/O/N=2 xx,yy
        xx=nan
        yy=nan
        AppendToGraph/W=Graph0 yy vs xx
    endif
    ModifyGraph/W=Graph0  lsize=2
    
    if(angle==0 || angle==360)
        xx=50+(rad-70)*50/70
        yy={0,99}
    elseif(angle==90 || angle==180)
        yy=50+(rad-70)*50/70
        xx={0,99}
    else
        Variable i
        xx={-50,49}
        yy=50+((rad-70)*50/70-xx*cos(pi*angle/180))/sin(pi*angle/180)
        xx+=50
    endif
End

 

So I put th cursor on a hot spot in the hough image and run

drawhoughLine(hcsr(a),vcsr(a))

And low and behold it draws a line on the skeleton image, but in no way does it seem to line up with any of the points in the skeleton image.

What is amiss?

I have attached a basic experiment with the skeleton and hough images and the drawhoughline code.

Andy

hough line Hough Test.pxp (8.41 MB)

First, I have no idea about Hough transformation. But the tutorial, including the drawHoughLine() function, is tailored to the specific example of an 100x100 image. See the manual:

If the input image has N rows and M columns then the number of rows in the M_Hough is set to 1+sqrt(N^2+M^2). The output radius should be read relative to the center row.

So in the drawHoughLine() function above the radius is re-centered by 70, which is correct for the IPtutorial example but wrong for your enormous image. Another issue is that your image is not square, and it is difficult to figure out the center in the equation (which was 50 in the tutorial). I tried to adapt drawHoughLine() for about an hour, but didn't succeed (there was always some offset; maybe I have another look later). So, I am afraid you need to rethink the function from scratch using the correct center points of both your input and the transformation matrix.

After two more coffee, I figured out a general form:

Function calcHoughLine(Wave/Z source, Variable rad, Variable angle)
    Wave/Z matrix = M_Hough
    if (!WaveExists(source) || !WaveExists(matrix))
        return 0
    endif
    
    Wave/z yy, xx
    if (!WaveExists(yy))
        Make/O/N=2 xx = NaN, yy = NaN
    endif
    
    variable xSize = DimSize(source,0)
    variable ySize = DimSize(source,1)
    variable xMid = xSize/2
    variable yMid = ySize/2
    variable radM = (DimSize(matrix,0)-1)/2
    xSize--
    ySize--
    
    rad -= radM
    
    if (angle==0 || angle==360)
        xx = xMid + rad
        yy = {0, ySize}
    elseif (angle==90 || angle==180)
        yy = yMid + rad
        xx = {0, xSize}
    else
        angle = pi*angle/180
            
        xx = {-xMid,+xMid}
        yy = ( rad - xx*cos(angle) )/sin(angle) + yMid-1
        xx += xMid
        
        Variable slope = (yy[1]-yy[0])/(xx[1]-xx[0])
        if (yy[0]<0)
            xx[0] -= yy[0]/slope
            yy[0]  = 0
        endif
        if (yy[1]<0)
            xx[1] -= yy[1]/slope
            yy[1]  = 0
        endif
        if (yy[0]>ySize)
            xx[0] += (ySize-yy[0])/slope
            yy[0]  = ySize
        endif
        if (yy[1]>ySize)
            xx[1] += (ySize-yy[1])/slope
            yy[1]  = ySize
        endif
    endif
End

Run via:

calcHoughLine(base_skeleton, hcsr(a,"Graph1"), vcsr(a,"Graph1"))