边缘跟随相机

Mat*_*haq 9 computer-vision edge-detection

我想按照机器人后面的一行跟随下图中最右边的边缘.

source9

我尝试过简单的"阈值处理",但不幸的是,它包含了模糊的白色光环:

posterized9

我阈值的原因是从Sobel边缘探测器获得一条干净的线:

edge9

有没有一个好的算法可以用来隔离这个边缘/沿着这个边缘移动?我目前使用的那个似乎容易出错,但它是迄今为止我能够弄清楚的最好的一个.

注意:边缘可能在任何方向上弯曲或对齐,但边缘上的点始终非常靠近图像的中心.这是我正在尝试做的视频.由于光晕拧紧了阈值,它在(1:35)之后不会跟随边缘.


这是另一个例子:

source6

posterized6

edge6

在这里,我将中心边缘填充,将其与右下角的小凹凸分开:

final6

Luk*_*uke 1

最简单的方法(垂直线)

如果您知道图像的线条右侧为黑色,则有一个简单的方法:

1)应用Sobel算子求x方向的一阶导数。结果将是梯度最强的地方负值最大的图像。(使用较大的内核大小来平均光晕效应。如果 7x7 内核不够,您甚至可以先对图像应用高斯模糊,以获得更多平均效果。)

2) 对于图像的每一行,找到最小值(即最大负值)的索引。这是您对该行中行位置的估计。

3)用它做任何你想做的事。(也许取图像上半部分和下半部分这些线位置的中位数,以获得描述该线的 2 个点的估计值。)

稍微高级一点(任意线)

如果您不知道线的方向,但您知道它足够直,可以用直线近似它,请使用此选项。

1)

dx = cv2.Sobel(grayscaleImg,cv2.cv.CV_32F,1,0,ksize=7)
dy = cv2.Sobel(grayscaleImg,cv2.cv.CV_32F,0,1,ksize=7)
angle = np.atan2(dy,dx)
magnitudeSquared = np.square(dx)+np.square(dy)
Run Code Online (Sandbox Code Playgroud)

现在,您已获得图像中每个点的角度(以弧度为单位)和梯度大小。

2)从这里您可以使用基本的 numpy 操作来查找线:过滤点以仅保留幅度平方>某个阈值的点。然后获取最常见的角度(np.bincount()对此很有用)。现在您知道了线的角度。

3)进一步过滤点以仅保留接近该角度的点。现在您已经拥有了线上的所有点。通过这些点的坐标拟合一条线。

最先进、最脆弱(任意曲线)

如果您确实需要处理曲线,这里有一种方法:

1)使用上面的方法对图像进行阈值设置。手动调整阈值,直到白/黑划分大致发生在您想要的位置。(可能 127 不是正确的阈值。但如果您的照明条件一致,您也许能够找到有效的阈值。确认它适用于多个图像。)

2)使用OpenCV的findcontours()将曲线拟合到白/黑边界。如果它太不稳定,请使用approxPolyDP()来简化它。