2017-07-25 334 views
1

我正嘗試在opencv(Python)中使用Hough變換去除方塊(垂直和水平線)。問題是沒有檢測到垂直線。我試圖通過輪廓和層次結構來查看,但是圖像中有太多的輪廓,我很困惑如何使用它們。在opencv中使用Hough變換檢測垂直線

看過相關帖子後,我已經玩過門檻和rho參數,但沒有幫助。 我已附上代碼以獲取更多詳細信息。爲什麼Hough變換不能在圖像中找到垂直線?歡迎任何解決此任務的建議。謝謝。

輸入圖像: enter image description here

霍夫變換的圖像:enter image description here

繪製輪廓: enter image description here

import cv2 
import numpy as np 
import pdb 


img = cv2.imread('/home/user/Downloads/cropped/robust_blaze_cpp-300-0000046A-02-HW.jpg') 

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
ret, thresh = cv2.threshold(gray, 140, 255, 0) 
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
cv2.drawContours(img, contours, -1, (0,0,255), 2) 

edges = cv2.Canny(gray,50,150,apertureSize = 3) 
minLineLength = 5 
maxLineGap = 100 
lines = cv2.HoughLinesP(edges,rho=1,theta=np.pi/180,threshold=100,minLineLength=minLineLength,maxLineGap=maxLineGap) 
for x1,y1,x2,y2 in lines[0]: 
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2) 

cv2.imwrite('probHough.jpg',img) 
+1

部分可以初始閾值,這似乎太低。檢查中間圖像。我沒有真正回答你原來的問題,但我已經發布了一個可行的替代方法。 –

回答

6

說實話,而不是找線,我不是看爲白色框。

  1. 製備

    import cv2 
    import numpy as np 
    
  2. 裝入圖像

    img = cv2.imread("digitbox.jpg", 0) 
    
  3. 二值化,所以,無論是框和數字是黑,其餘的是白

    _, thresh = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY) 
    cv2.imwrite('digitbox_step1.png', thresh) 
    

    Step 1 -- thresholded input

  4. 查找輪廓。在這個示例圖像中,只需查找外部輪廓即可。

    _, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 
    
  5. 處理輪廓,過濾掉任何面積太小的區域。找到每個輪廓的凸包,創建輪廓外所有區域的蒙版。存儲每個找到的輪廓的邊界框,按x座標排序。

    Step 2 -- the mask

  6. 擴張掩模(收縮黑色部分),夾斷任何殘留在灰框。

    mask = cv2.dilate(mask, np.ones((5,5),np.uint8)) 
    
    cv2.imwrite('digitbox_step3.png', mask) 
    

    Step 3 -- dilated mask

  7. 填寫所有的蒙面像素,白,刪除這些畫面。

    img[mask != 0] = 255 
    
    cv2.imwrite('digitbox_step4.png', img) 
    

    Step 4 - cleaned up input

  8. 過程中的數字,你的願望 - 我得繪製邊框。

    result = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) 
    
    for n,box in enumerate(boxes): 
        x,y,w,h = box 
        cv2.rectangle(result,(x,y),(x+w,y+h),(255,0,0),2) 
        cv2.putText(result, str(n),(x+5,y+17), cv2.FONT_HERSHEY_SIMPLEX, 0.6,(255,0,0),2,cv2.LINE_AA) 
    
    cv2.imwrite('digitbox_step5.png', result) 
    

    Enumerated bounding boxes


一體的整個腳本:問題的

import cv2 
import numpy as np 

img = cv2.imread("digitbox.jpg", 0) 

_, thresh = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY) 
_, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 

mask = np.ones_like(img) * 255 
boxes = [] 

for contour in contours: 
    if cv2.contourArea(contour) > 100: 
     hull = cv2.convexHull(contour) 
     cv2.drawContours(mask, [hull], -1, 0, -1) 
     x,y,w,h = cv2.boundingRect(contour) 
     boxes.append((x,y,w,h)) 

boxes = sorted(boxes, key=lambda box: box[0]) 

mask = cv2.dilate(mask, np.ones((5,5),np.uint8)) 

img[mask != 0] = 255 

result = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) 

for n,box in enumerate(boxes): 
    x,y,w,h = box 
    cv2.rectangle(result,(x,y),(x+w,y+h),(255,0,0),2) 
    cv2.putText(result, str(n),(x+5,y+17), cv2.FONT_HERSHEY_SIMPLEX, 0.6,(255,0,0),2,cv2.LINE_AA) 

cv2.imwrite('digitbox_result.png', result) 
+0

這是完美的。這是一個很好的例子,可以瞭解opencv中的凸包和輪廓如何工作。謝謝 !! –