opencv 霍夫變換 實現圖片旋轉角度計算


在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 :

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM