I want to follow the rightmost edge in the following picture with a line following robot.
I tried simple "thresholding", but unfortunately, it includes the blurry white halo:
The reason I threshold is to obtain a clean line from the Sobel edge detector:
Is there a good algorithm which I can use to isolate this edge/move along this edge? The one I am using currently seems error prone, but it's the best one I've been able to figure out so far.
Note: The edge may curve or be aligned in any direction, but a point on the edge will always lie very close to the center of the image. Here's a video of what I'm trying to do. It doesn't follow the edge after (1:35) properly due to the halo screwing up the thresholding.
Here's another sample:
Here, I floodfill the centermost edge to separate it from the little bump in the bottom right corner:
答案 0 :(得分: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)
现在,您拥有图像中每个点的渐变角度(以弧度表示)和幅度。
2)从这里你可以使用基本的numpy操作来找到这条线:过滤点只保留在scaleSquared>的点。一些门槛。然后抓住最常见的角度(np.bincount()对此有用)。现在你知道了你的直线角度。
3)进一步过滤点以仅保留接近该角度的点。你现在拥有所有要点。在这些点的坐标处插入一条线。
如果真的需要处理曲线,可以采用以下方式:
1)使用上面的方法来阈值图像。手动调整阈值,直到白/黑分区大致发生在您想要的位置。 (可能127不是正确的阈值。但是如果你的光照条件一致,你可能找到一个有效的阈值。确认它适用于多个图像。)
2)使用OpenCV的findcontours()将曲线拟合到白/黑边界。如果它太不连贯,请使用approxPolyDP()来简化它。