20

我正在嘗試從來自「文檔」的圖像中找到水平線和垂直線。這些文檔是合同中的掃描頁面,因此這些行看起來像您在表格或合同塊中看到的內容。使用OpenCV進行水平線檢測

我一直在嘗試OpenCV的工作。 OpenCV中的Hough變換實現對於這項工作似乎很有用,但是我找不到任何允許它乾淨地找到垂直和水平線的參數組合。我嘗試了和沒有邊緣檢測。沒有運氣。如果有人做了類似的事情,我有興趣知道如何。

在這裏看到我的前後使用OpenCV中的HoughP實驗的圖像。這是我能做的最好的,http://dl.dropbox.com/u/3787481/Untitled%201.png

所以現在我想知道是否有另一種轉換我可以使用,這將允許我可靠地找到水平和垂直線(最好是虛線)。

我知道這個問題是可以解決的,因爲我有Nuance和ABBYY OCR工具,它們都可以可靠地提取水平線和垂直線,並返回線框的邊界框。

謝謝! Patrick。

回答

25

您是否看過HoughLinesP函數文檔中的代碼示例?

我認爲你可以用它作爲算法的起點。要選擇水平垂直線,您只需按行角度過濾掉其他線。

UPDATE:

當我看到你需要找到不是在頁面上線,但水平的垂直邊緣。對於這個任務,你需要結合幾個處理步驟來獲得好的結果。

對於您的圖片,我可以通過將Canny邊緣檢測與HoughLinesP相結合來獲得良好的效果。這裏是我的代碼(我用Python,但我認爲你看到的想法):

img = cv2.imread("C:/temp/1.png") 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
edges = cv2.Canny(gray, 80, 120) 
lines = cv2.HoughLinesP(edges, 1, math.pi/2, 2, None, 30, 1); 
for line in lines[0]: 
    pt1 = (line[0],line[1]) 
    pt2 = (line[2],line[3]) 
    cv2.line(img, pt1, pt2, (0,0,255), 3) 
cv2.imwrite("C:/temp/2.png", img) 

結果如下:

+0

嗨安德烈,謝謝。是的,我嘗試了許多不同變量的HoughLinesP。我已經調整了我的原始問題,並且包含了我可以從HoughLinesP中獲得的最佳圖像的鏈接。是的,我確實試圖限制只接近水平線。 –

+0

太棒了。顯然我錯過了Canny探測器。這是一個很好的結果。我還發現了一種稱爲Orthogonal Zig-Zag的算法,它可以提供這些線,然後擴展它們以確定線的寬度(這是HoughP無法做到的)。 –

+0

python中沒有分號;) – mak

5

你可能會考慮離開霍夫線檢測,因爲這方法查找「全局」線,不一定是線段。最近,我實施了一個確定「平行四邊形」的應用程序 - 基本上可以旋轉的正方形以及由於視角而縮小的視角。你可能會考慮類似的東西。我的管道是:從RGB

  1. 轉換爲灰度(cvCvtColor)
  2. 平滑(cvSmooth)
  3. 閾值(cvThreshold)
  4. 檢測邊緣(cvCanny)
  5. 查找輪廓(cvFindContours)
  6. 具有線性特徵的近似輪廓(cvApproxPoly)

在您的應用程序中,生成的輪廓列表可能很大(取決於Canny邊緣檢測器的平滑和特徵增強的「積極性」。您可以通過各種參數修剪該列表:從輪廓查找器返回的點數,輪廓區域(cvContourArea)等等。根據我的經驗,我希望應用程序中的「有效」行可以有明確的定義面積和頂點計數屬性。此外,您可以根據端點之間的距離,連接端點的線所定義的角度等來濾除輪廓。

根據您擁有多少CPU「時間」,可以始終將Hough算法與像上面這樣的算法來穩健地識別水平線和垂直線。

8

如果你只是想要「線」而不是「線段」,我會避免使用Canny,Hough,FindContours或任何其他此類功能,以防您希望代碼中有更多速度。如果你的圖像不旋轉,你想要找到的東西總是垂直或水平的,我只需使用cv :: Sobel(一個用於垂直,另一個用於水平),併爲列和行創建累加數組。然後,您可以在這些累積或配置文件中搜索最大值,例如通過設置閾值,並且您將知道存在垂直或水平邊緣線的行或列。

+1

您是否知道在cv :: sobel中爲水平線和垂直線設置的參數? –

4

不要將RGB轉換爲灰度。有時,RGB中的不同顏色可以合併爲相同的灰度值,因此可能會遺漏一些輪廓。您應該分別分析每個RGB通道。