python-3.xopencvgoogle-colaboratoryhough-transformhoughlines

Transform Plates into Horizontal Using Hough transform


I am trying to transform images that are not horizontal, because they may be slanted.

It turns out that when testing 2 images, this photo that is horizontal, and this one that is not. It gives me good results with the horizontal photo, however when trying to change the second photo that is tilted, it does not do what was expected.

The fist image it's works fine like below with a theta 1.6406095. For now it looks bad because I'm trying to make the 2 photos look horizontally correct.

enter image description here

The second image say that theta is just 1.9198622

enter image description here

I think the error it is at this line:

lines= cv2.HoughLines(edges, 1, np.pi/90.0, 60, np.array([]))

I have done a little simulation on this link with colab.

Any help is welcome.


Solution

  • So far this is what I got.

    import cv2
    import numpy as np
    
    img=cv2.imread('test.jpg',1)
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    imgBlur=cv2.GaussianBlur(imgGray,(5,5),0)
    imgCanny=cv2.Canny(imgBlur,90,200)
    contours,hierarchy =cv2.findContours(imgCanny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    
    rectCon=[]
    for cont in contours:
        area=cv2.contourArea(cont)
        if area >100:
            #print(area) #prints all the area of the contours
            peri=cv2.arcLength(cont,True)
            approx=cv2.approxPolyDP(cont,0.01*peri,True)
            #print(len(approx)) #prints the how many corner points does the contours have
            if len(approx)==4:
                rectCon.append(cont)
                #print(len(rectCon))
                
    rectCon=sorted(rectCon,key=cv2.contourArea,reverse=True) # Sort out the contours based on largest area to smallest
    
    
    bigPeri=cv2.arcLength(rectCon[0],True)
    cornerPoints=cv2.approxPolyDP(rectCon[0],0.01*peri,True)
    
    # Reorder bigCornerPoints so I can prepare it for warp transform (bird eyes view)
    cornerPoints=cornerPoints.reshape((4,2))
    mynewpoints=np.zeros((4,1,2),np.int32)
    add=cornerPoints.sum(1)
    
    mynewpoints[0]=cornerPoints[np.argmin(add)]
    mynewpoints[3]=cornerPoints[np.argmax(add)]
    diff=np.diff(cornerPoints,axis=1)
    mynewpoints[1]=cornerPoints[np.argmin(diff)]
    mynewpoints[2]=cornerPoints[np.argmax(diff)]
    
    # Draw my corner points 
    #cv2.drawContours(img,mynewpoints,-1,(0,0,255),10)
    
    ##cv2.imshow('Corner Points in Red',img)
    ##print(mynewpoints)
    
    # Bird Eye view of your region of interest
    pt1=np.float32(mynewpoints) #What are your corner points
    pt2=np.float32([[0,0],[300,0],[0,200],[300,200]]) 
    matrix=cv2.getPerspectiveTransform(pt1,pt2) 
    imgWarpPers=cv2.warpPerspective(img,matrix,(300,200)) 
    cv2.imshow('Result',imgWarpPers)
    

    Result

    Now you just have to fix the tilt (opencv has skew) and then use some threshold to detect the letters and then recognise each letter.

    As for a general purpose, I think images need to be normalised first so that we can easily detect the edges.