2017-03-07 240 views
1

目前我工作的一個項目,我嘗試使用OpenCV中找到矩形表面的照片的角落(的Python,Java或C++)OpenCV的:檢測有缺陷的矩形

我選擇所需表面通過過濾顏色,然後我有面具和它傳遞給cv2.findContours

cnts, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
cnt = sorted(cnts, key = cv2.contourArea, reverse = True)[0] 
peri = cv2.arcLength(cnt, True) 
approx = cv2.approxPolyDP(cnt, 0.02*peri, True) 
if len(approx) == 4: 
    cv2.drawContours(mask, [approx], -1, (255, 0, 0), 2) 

這給了我一個不準確的結果: findContours result

使用cv2.HoughLines我已經成功地得到4條直線準確地描述表面。它們的交叉點正是我需要的:

edged = cv2.Canny(mask, 10, 200) 
hLines = cv2.HoughLines(edged, 2, np.pi/180, 200) 
lines = [] 
for rho,theta in hLines[0]: 
    a = np.cos(theta) 
    b = np.sin(theta) 
    x0 = a*rho 
    y0 = b*rho 
    x1 = int(x0 + 1000*(-b)) 
    y1 = int(y0 + 1000*(a)) 
    x2 = int(x0 - 1000*(-b)) 
    y2 = int(y0 - 1000*(a)) 
    cv2.line(mask, (x1,y1), (x2,y2), (255, 0, 0), 2) 
    lines.append([[x1,y1],[x2,y2]]) 

HoughLines result

的問題是:是否有可能以某種方式調整findContours

另一種解決辦法是找到交叉點的座標。這種方法的任何線索,歡迎:)

任何人可以給我一個提示如何解決這個問題呢?

+0

「他們的交點正是我需要的」 - - 在這種情況下計算它們的交點。 –

+0

你能給我一個線索我怎麼能做到這一點? – Aray

+1

已經有很多線索可用,例如http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect或https://en.wikipedia.org/ wiki/Line%E2%80%93line_intersection或http://stackoverflow.com/a/7448287/3962537 –

回答

0

的發現,因爲它似乎是路口也不是那麼瑣碎的問題,而是會被發現的交叉點之前,以下問題需要考慮:

  1. 最重要的是要選擇對合適的參數HoughLines功能,因爲它可以從0回到線的無限數字(我們需要4個平行)
  2. 由於我們沒有在這些線路走,他們需要什麼才能知道彼此
  3. 由於進行比較透視,平行線不再平行,因此每條線都會有一個相交點與其他人一起。一個簡單的解決方案是過濾照片外的座標。但可能會發生照片內出現不希望的交叉路口。
  4. 座標應進行排序。根據任務的不同,可以通過不同的方式完成。

cv2.HoughLines將爲每行返回值爲rho and theta的數組。 現在的問題變成方程的所有行的成對系統:

system of equations

def intersections(edged): 
    # Height and width of a photo with a contour obtained by Canny 
    h, w = edged.shape 

    hl = cv2.HoughLines(edged,2,np.pi/180,190)[0] 
    # Number of lines. If n!=4, the parameters should be tuned 
    n = hl.shape[0]  

    # Matrix with the values of cos(theta) and sin(theta) for each line 
    T = np.zeros((n,2),dtype=np.float32) 
    # Vector with values of rho 
    R = np.zeros((n),dtype=np.float32) 

    T[:,0] = np.cos(hl[:,1]) 
    T[:,1] = np.sin(hl[:,1]) 
    R = hl[:,0] 

    # Number of combinations of all lines 
    c = n*(n-1)/2 
    # Matrix with the obtained intersections (x, y) 
    XY = np.zeros((c,2)) 
    # Finding intersections between all lines 
    for i in range(n): 
     for j in range(i+1, n): 
      XY[i+j-1, :] = np.linalg.inv(T[[i,j],:]).dot(R[[i,j]]) 

    # filtering out the coordinates outside the photo 
    XY = XY[(XY[:,0] > 0) & (XY[:,0] <= w) & (XY[:,1] > 0) & (XY[:,1] <= h)] 
    # XY = order_points(XY) # obtained points should be sorted 
    return XY 

這裏是結果:

enter image description here

-1

是可能的:

  1. 選擇最長的輪廓
  2. 斷裂成片段,並將它們組由梯度
  3. 擬合線到最大的四組
  4. 查找交點

但隨後,Hough變換做幾乎同樣的事情。有沒有特別的理由不使用它?

線的交叉點是很容易計算。高中座標幾何課可以爲您提供算法。

+0

其實我使用Hough變換來檢測線條(第二個例子) – Aray

+0

在這種情況下,這種情況的最佳解決方案是找到交點,因爲您已經在更新後的問題中完成了。在實際情況下,您需要一種方法來爲線路選擇最佳的四位候選人。 – Totoro

+1

我只是使用while循環,直到我只有4行。不是最好的解決方案,但工作 – Aray