使用opencv跟踪皮带上的土豆,最好的替代方法是?

时间:2019-04-06 07:31:23

标签: python opencv image-processing

我想使用某种机器学习来测量(直径)并计算通过皮带的土豆。我从opencv开始,已经开始训练带有正负图像的级联,这是我捕获的一段短视频的打印屏幕:

potatoes on a belt

在此框架中,它只能识别出一些土豆,但我认为我可以添加更多的正负图像以做出更好的标识符。

问题,

  1. 您认为我在正确的轨道上吗?

  2. 我知道如何继续测量直径吗?

  3. 我应该如何跟踪每个马铃薯,使其只被计数一次?

(这是我用来识别土豆的代码)

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()

1 个答案:

答案 0 :(得分:1)

  

您认为我走上正轨吗?

是,不是。机器学习绝对是解决土豆问题的正确工具,但是到目前为止显示的结果根本不是很好。还有很长的路要走。

  

还有什么想法,我将如何继续测量直径?

如果您只对测量土豆的平均直径感兴趣,那么这可能比真正跟踪单个土豆要容易得多。

首先,您需要估计透视图(运输带相对于相机的位置),以便知道图像空间与运输带上的实际空间之间的关系。找出从实空间到像空间的转换可能会帮助您的是,在皮带上放置规则的网格(例如带有规则的黑点的薄片)并观察其运动。在顶视图模式下安装相机可能会使事情变得简单得多。

仅测量平均直径就意味着您不需要正确处理每个马铃薯,标准的边缘检测算法可能足以检测大多数马铃薯,然后将椭圆拟合到它们上,绘制直径的直方图并查看中间值值。

或者计算马铃薯的光度的自相关(在马铃薯变暗之间,马铃薯本身正在反射光),并拟合自相关峰的宽度。或计算图像的傅立叶变换,并在一个频带内将平均幅度归一化,在该频带上,您期望土豆的大小与另一个频带的平均幅度一致。如果您可以用已知大小的土豆校准该方法,则效果最好。这意味着您可以记录已知大小不同的土豆,从而校准自相关或基于FFT的量度。

我会选择机器学习方法,因为它可能为您提供单个马铃薯测量结果。

  

我应该如何跟踪每个马铃薯,使其只被计数一次?

在视频中的时间范围内,每个马铃薯(可能)都是可见的,这是通过视野将皮带上的马铃薯运输所需的。建立透视图后,您可以将图像中的位置和记录时间与传送带上的位置相关联,只要土豆不改变传送带上的位置,您就可以轻松地在整个时间内对其进行识别可见的范围。

您基本上必须知道(估计)输送带的运动,然后才能(通过计算)“撤消”该输送带,并在看到相同马铃薯的所有事件中求平均值。

我建议以下常规工作流程:

  • 考虑将相机放置在更有利的位置(顶视图)。
  • 通过跟踪更容易检测到皮带上已知距离的物体来测量从真实空间到图像时空的转换。
  • 应用逆变换,并根据需要对同一对象的所有图像进行平均(如果单个图像有噪点,对比度低,则可以提供帮助)
  • 或者使用简单的边缘检测并进行一些统计以获得马铃薯的平均直径(可能用已知大小的马铃薯进行校准)。
  • ..使用机器学习来识别(并跟踪,如果您不求平均)单个土豆
  • 如果您在途中遇到问题,将其分解成一些小片段,并在一个单独的问题中寻求解决方案。