python - 检测机器人在作物行之间可以走的路径
问题描述
我正在解决一个问题,我需要找到机器人可以在不碰到任何作物行的情况下采取的路径。原始图像
我最初的方法是将其转换为鸟瞰图,然后使用精明和骨架化技术。然后我应用霍夫变换来提出裁剪行。当行是直的时这很好用,但如果我将图像旋转 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函数可以更好地做到这一点。有人可以帮助我或以正确的方式指导我。
这是我正在寻找的最终输出 最终预期结果,绿色显示路径中心
解决方案
所以,这是我使用 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
.
我希望这符合您的需求:)
推荐阅读
- php - Laravel 访问 hasMany 的 hasOne
- javascript - Material Design 组件文本字段的标签不浮动到左上角
- c# - C# 使用 Directory.GetDirectories() 枚举文件 2 个文件夹
- javascript - 如何清除中间件加载以进行动态路由加载?
- java - 我可以为不同的应用程序活动设置隐式意图横向吗?
- java - Wiiremock http失败错误
- c# - 无法通过 C# 使用 Selenium 检查复选框控件
- python - 如何使用带有 Flask-AppBuilder 的自定义表单更改选择字段的默认选择?
- authentication - 401.2 出现在本地主机上
- actionscript-3 - 调整窗口大小 AS3