首页 > 解决方案 > 检测机器人在作物行之间可以走的路径

问题描述

我正在解决一个问题,我需要找到机器人可以在不碰到任何作物行的情况下采取的路径。原始图像

我最初的方法是将其转换为鸟瞰图,然后使用精明和骨架化技术。然后我应用霍夫变换来提出裁剪行。当行是直的时这很好用,但如果我将图像旋转 45 度,我使用霍夫变换找不到任何行。所以我决定使用另一种方法。

首先我只选择了绿色区域并应用了形态过滤器来去除出现的小分支

img = cv2.imread('''')
min_green2 = np.array([45, 50, 50])
max_green2 = np.array([75, 250, 250])
image_blur = cv2.GaussianBlur(img, (5, 5), 0)
image_blur_hsv = cv2.cvtColor(image_blur, cv2.COLOR_BGR2HSV)
image_green = cv2.inRange(image_blur_hsv, min_red2, max_red2)
se1 = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
se2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
mask = cv2.morphologyEx(image_green, cv2.MORPH_OPEN, se1)

我最终得到了这个Final_output

现在我想检测机器人可以走的路径是黑色区域。所以只有第一行是我感兴趣的区域,我尝试了不同的方法在行的中心画一条线,但在 opencv 中找不到任何帮助.我确实设法通过将图像垂直分成两部分并使用 cv2.fitline 函数来获得一条连接行一侧的线并与行的另一侧做同样的事情,最后我绘制了中心线。但是这个不是一种理想的方法,我觉得可能有一些opencv函数可以更好地做到这一点。有人可以帮助我或以正确的方式指导我。

这是我正在寻找的最终输出 最终预期结果,绿色显示路径中心

标签: pythonimageopencvcomputer-vision

解决方案


所以,这是我使用 numpy 和 scipy 的方法,它产生了这个结果 最终图像

不做任何模糊或形态学操作,使用 Canny 边缘检测器:

edges = cv2.Canny(image, 100, 200, None, 3, cv2.DIST_L2)

边缘检测 请注意,大部分边缘都围绕着您的机器人想要遵循的轨道。由于每条边都是白色像素的集合,我们可以计算一列的总强度:

normalized = cv2.normalize(edges, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
column_intensity = normalized.sum(axis=0)

绘制结果,我们得到像素强度

如果我们要找到图的最小值,那么我们将找到 x 方向,其中大部分边都被避开了。但首先,让我们平滑函数以避免一些噪音。

# smooth function through moving average
window_size = 30
window = np.ones((window_size,)) / window_size
smoothed = np.convolve(column_intensity, window, mode="valid")

平滑图

由于有很多局部最小值,我们的额外约束是机器人应该采用的 x 方向最接近图像的中心。

# find indices of local minima and select the one closest to the center
indices = scipy.signal.argrelmin(smoothed)[0]
distances = np.abs(indices - int(width / 2))
x = indices[np.argmin(distances)]

现在我们有了 x 方向,我们需要确定 y 坐标以估计机器人应该旋转的角度 (tan(angle)=y/x)。图像中有多少行就有多少选择,这意味着需要手动设置y坐标。如果我们选择离机器人更近的 y,随着机器人的前进,角度会更加不稳定。相反,如果我们选择离机器人较远的ay,那么它的波动性会更小,但准确度也会更低。那取决于你; 最终图像是使用y = 400.

我希望这符合您的需求:)


推荐阅读