首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenCV:检测有缺陷的矩形

OpenCV:检测有缺陷的矩形
EN

Stack Overflow用户
提问于 2017-03-07 23:17:58
回答 2查看 1.7K关注 0票数 3

目前,我正在进行一个项目,尝试使用OpenCV (Python或C++)在照片中找到矩形表面的角。

我通过过滤颜色选择了想要的表面,然后我得到了掩码,并将它传递给了cv2.findContours

代码语言:javascript
复制
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)

这给了我一个不准确的结果:

使用cv2.HoughLines,我成功地得到了4条直线,精确地描述了表面。他们的交叉口正是我所需要的:

代码语言:javascript
复制
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]])

问题是:是否有可能以某种方式调整findContours

另一种解决办法是找到交叉口的坐标。欢迎提供任何有关此方法的线索:)

有人能给我一个如何解决这个问题的提示吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-12 13:21:56

求交并不是看上去那么简单,但在找到交点之前,应该考虑以下问题:

  1. 最重要的是为HoughLines函数选择正确的参数,因为它可以从0返回到无限多的直线(我们需要4条并行)。
  2. 由于我们不知道这些线是按什么顺序排列的,所以它们需要相互比较。
  3. 由于透视,平行线不再是平行的,所以每条线都有一个交点。一个简单的解决方案是过滤位于照片外部的坐标。但这可能会发生,一个不受欢迎的交叉口将在照片内。
  4. 坐标应该排序。根据任务的不同,它可以以不同的方式完成。

cv2.HoughLines将为每一行返回一个值为rho和theta的数组。现在,这个问题成了成对的所有行的方程组:

代码语言:javascript
复制
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

结果如下:

票数 0
EN

Stack Overflow用户

发布于 2017-03-08 02:21:12

可以:

  1. 选择最长的轮廓
  2. 将其分割成分段,并按梯度对它们进行分组。
  3. 适合最大的四组线
  4. 求交点

但是,Hough变换几乎做了同样的事情。有什么特别的理由不使用它吗?

直线的交点很容易计算。高中坐标几何课可以为你提供算法.

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42660184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档