首页 > 解决方案 > 检查轮廓的任何点是否与线相交的有效方法是什么?

问题描述

注意:虽然这个问题寻找直线和轮廓之间的交点解决了类似的问题,但我的偏好是尽可能不引入另一个依赖项。


我有一张图像,其中检测到多条线和多个轮廓。例如,下图检测到三条线和两条轮廓。我的任务是找出哪些轮廓与它们相交。在这种情况下,只有一个轮廓有一条与之相交的线。

例子

我拥有的收藏品如下。

lines = cv2.HoughLines(img,1,np.pi/180, 200)
contours, _ = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

我最初的思考过程是计算质心坐标到直线的距离,但可能存在轮廓非常大的边缘情况,因此这将是不可靠的,因为质心离直线太远了。

也许找到轮廓中所有可能的坐标,遍历每个点并检查该点到线的距离是否为零?

我写了一些代码来计算点和线之间的距离:

  def shortest_distance_to_line(point, line):
      x, y = point
      rho, theta = line
      a = np.cos(theta)
      b = np.sin(theta)
      x0 = a*rho
      y0 = b*rho
      x1 = int(x0 + 10000*(-b))
      y1 = int(y0 + 10000*(a))
      x2 = int(x0 - 10000*(-b))
      y2 = int(y0 - 10000*(a))

      if theta == 0: # vertical line
          return abs(x - x1)
      else:
          c = (y2 - y1) / (x2 - x1)
          return abs(a*x + b*y + c) / math.sqrt(a**2 + b**2)

什么是检测与它们相交的轮廓的有效方法?

如果循环遍历每个轮廓内的每个点是一种有效的方法,我如何生成轮廓的所有点?

标签: pythonopencv

解决方案


平面中的直线方程的形状为 $ax+by+c=0$,其中 (x,y) 是平面中的一个点。这条线将平面分成两个半平面,如果我们省略这条边界线,(开放的)半平面由以下等式给出:

ax + by + c > 0 ax + by + c < 0

我假设要交叉的域是连接的。

然后我将开始蒙特卡罗随机生成点,并每次记录函数 (x,y) -> ax + by + c 的符号。(可以实现一些错误。)在第一次检测到两个标志后,我们有一个交叉路口。否则,经过多次试验后,我们停下来并认为没有交叉点。

如果“域”只有几个点,我们当然循环,不需要蒙特卡洛。(如果我们已经有边界点,我们可以限制它们。)


推荐阅读