我想使用某种机器学习来测量(直径)并计算通过皮带的土豆。我从opencv开始,已经开始训练带有正负图像的级联,这是我捕获的一段短视频的打印屏幕:
在此框架中,它只能识别出一些土豆,但我认为我可以添加更多的正负图像以做出更好的标识符。
问题,
您认为我在正确的轨道上吗?
我知道如何继续测量直径吗?
我应该如何跟踪每个马铃薯,使其只被计数一次?
(这是我用来识别土豆的代码)
import numpy as np
import cv2
pot_cascade = cv2.CascadeClassifier('cascade.xml')
cap = cv2.VideoCapture('potatoe_video.mp4')
while 1:
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
potatoes = pot_cascade.detectMultiScale(gray, 5, 5)
for (x, y, w, h) in potatoes:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
cv2.imshow('img', img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
答案 0 :(得分:1)
您认为我走上正轨吗?
是,不是。机器学习绝对是解决土豆问题的正确工具,但是到目前为止显示的结果根本不是很好。还有很长的路要走。
还有什么想法,我将如何继续测量直径?
如果您只对测量土豆的平均直径感兴趣,那么这可能比真正跟踪单个土豆要容易得多。
首先,您需要估计透视图(运输带相对于相机的位置),以便知道图像空间与运输带上的实际空间之间的关系。找出从实空间到像空间的转换可能会帮助您的是,在皮带上放置规则的网格(例如带有规则的黑点的薄片)并观察其运动。在顶视图模式下安装相机可能会使事情变得简单得多。
仅测量平均直径就意味着您不需要正确处理每个马铃薯,标准的边缘检测算法可能足以检测大多数马铃薯,然后将椭圆拟合到它们上,绘制直径的直方图并查看中间值值。
或者计算马铃薯的光度的自相关(在马铃薯变暗之间,马铃薯本身正在反射光),并拟合自相关峰的宽度。或计算图像的傅立叶变换,并在一个频带内将平均幅度归一化,在该频带上,您期望土豆的大小与另一个频带的平均幅度一致。如果您可以用已知大小的土豆校准该方法,则效果最好。这意味着您可以记录已知大小不同的土豆,从而校准自相关或基于FFT的量度。
我会选择机器学习方法,因为它可能为您提供单个马铃薯测量结果。
我应该如何跟踪每个马铃薯,使其只被计数一次?
在视频中的时间范围内,每个马铃薯(可能)都是可见的,这是通过视野将皮带上的马铃薯运输所需的。建立透视图后,您可以将图像中的位置和记录时间与传送带上的位置相关联,只要土豆不改变传送带上的位置,您就可以轻松地在整个时间内对其进行识别可见的范围。
您基本上必须知道(估计)输送带的运动,然后才能(通过计算)“撤消”该输送带,并在看到相同马铃薯的所有事件中求平均值。
我建议以下常规工作流程: