在OCR實際開發中,證件照采集角度有很大的偏差,需要將圖片進行旋轉校正,
效果圖:
在應用中發現應該加入高斯模糊,可以極大減少誤差線條.
知道線條后 通過求斜率 得旋轉角度 .(x1-x2)/(y1-y2)
結果
結果還行吧 ! 當然還有直方圖也可以判斷,有待研究!
霍夫變換
Hough變換是經典的檢測直線的算法。其最初用來檢測圖像中的直線,同時也可以將其擴展,以用來檢測圖像中簡單的結構。
OpenCV提供了兩種用於直線檢測的Hough變換形式。其中基本的版本是cv2.HoughLines。其輸入一幅含有點集的二值圖(由非0像素表示),其中一些點互相聯系組成直線。通常這是通過如Canny算子獲得的一幅邊緣圖像。cv2.HoughLines函數輸出的是[float, float]形式的ndarray,其中每個值表示檢測到的線(ρ , θ)中浮點點值的參數。下面的例子首先使用Canny算子獲得圖像邊緣,然后使用Hough變換檢測直線。其中HoughLines函數的參數3和4對應直線搜索的步長。在本例中,函數將通過步長為1的半徑和步長為π/180的角來搜索所有可能的直線。最后一個參數是經過某一點曲線的數量的閾值,超過這個閾值,就表示這個交點所代表的參數對(rho, theta)在原圖像中為一條直線。具體理論可參考這篇文章。
1 #coding=utf-8 2 import cv2 3 import numpy as np 4 5 img = cv2.imread("/home/sunny/workspace/images/road.jpg", 0) 6 7 img = cv2.GaussianBlur(img,(3,3),0) 8 edges = cv2.Canny(img, 50, 150, apertureSize = 3) 9 lines = cv2.HoughLines(edges,1,np.pi/180,118) #這里對最后一個參數使用了經驗型的值 10 result = img.copy() 11 for line in lines[0]: 12 rho = line[0] #第一個元素是距離rho 13 theta= line[1] #第二個元素是角度theta 14 print rho 15 print theta 16 if (theta < (np.pi/4. )) or (theta > (3.*np.pi/4.0)): #垂直直線 17 #該直線與第一行的交點 18 pt1 = (int(rho/np.cos(theta)),0) 19 #該直線與最后一行的焦點 20 pt2 = (int((rho-result.shape[0]*np.sin(theta))/np.cos(theta)),result.shape[0]) 21 #繪制一條白線 22 cv2.line( result, pt1, pt2, (255)) 23 else: #水平直線 24 # 該直線與第一列的交點 25 pt1 = (0,int(rho/np.sin(theta))) 26 #該直線與最后一列的交點 27 pt2 = (result.shape[1], int((rho-result.shape[1]*np.cos(theta))/np.sin(theta))) 28 #繪制一條直線 29 cv2.line(result, pt1, pt2, (255), 1) 30 31 cv2.imshow('Canny', edges ) 32 cv2.imshow('Result', result) 33 cv2.waitKey(0) 34 cv2.destroyAllWindows()
概率霍夫變換
觀察前面的例子得到的結果圖片,其中Hough變換看起來就像在圖像中查找對齊的邊界像素點集合。但這樣會在一些情況下導致虛假檢測,如像素偶然對齊或多條直線穿過同樣的對齊像素造成的多重檢測。
要避免這樣的問題,並檢測圖像中分段的直線(而不是貫穿整個圖像的直線),就誕生了Hough變化的改進版,即概率Hough變換(Probabilistic Hough)。在OpenCV中用函數cv::HoughLinesP 實現。如下:
#coding=utf-8 import cv2 import numpy as np img = cv2.imread("/home/sunny/workspace/images/road.jpg") img = cv2.GaussianBlur(img,(3,3),0) edges = cv2.Canny(img, 50, 150, apertureSize = 3) lines = cv2.HoughLines(edges,1,np.pi/180,118) result = img.copy() #經驗參數 minLineLength = 200 maxLineGap = 15 lines = cv2.HoughLinesP(edges,1,np.pi/180,80,minLineLength,maxLineGap) for x1,y1,x2,y2 in lines[0]: cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) cv2.imshow('Result', img) cv2.waitKey(0) cv2.destroyAllWindows()
參考:
https://blog.csdn.net/sunny2038/article/details/9253823
CODE GITHUB :