如何在opencv中使用光流跟踪来分割图像?

Posted

技术标签:

【中文标题】如何在opencv中使用光流跟踪来分割图像?【英文标题】:How to use optical flow tracking in opencv to segment an image? 【发布时间】:2019-05-22 12:54:53 【问题描述】:

使用来自 opencv2 的calcopticalflowpyrlk 来跟踪我在第一帧(绿点)上拾取的对象的运动流:

我在提供给calcopticalflowpyrlk 的旧点和calcopticalflowpyrlk 输出的点之间画了一条线

最后我得到了这首好听的曲目


引用@rotating_image answer 到一个类似的问题:

您可以测量位移的方向和大小 每个感兴趣的像素在两个连续的帧中经历一个 他们的运动模式的想法


确实,使用被跟踪对象的先前和当前点,我可以找到流向量的角度和大小。

但我仍然看不到它如何帮助我分割图像?

我是否应该计算所有像素的向量,而那些先前发现的具有“相同”角度和大小的那些是对象,而其他一切都是背景?

或者我错过了什么?

【问题讨论】:

您到底想细分什么? @Micka 来自背景的被跟踪对象,甚至是未被跟踪的对象。不仅仅是我用绿点标记的 3 辆车。 1.最小切割:pointclouds.org/documentation/tutorials/… 2. 欧几里得聚类提取:pointclouds.org/documentation/tutorials/cluster_extraction.php @Nuzhny 我在之前的项目中使用了grabcut进行分割,我现在需要找到如何使用运动流来分割我的图像...... 如果你想分割帧中的每个对象,那为什么需要使用光流呢?也许DeepMask 是你想要的。 【参考方案1】:

假设您有流图像,并且您想自动跟踪流向同一方向的流的 blob。

所以你得到的是稀疏流,如下所示

您可以为此使用 opencv 分区。分区就像基于距离的聚类算法,它比 kmean 更好,因为您不必输入数字 k。问题是它受到噪音和错误联想的影响。所以我更喜欢在大于阈值的流向量集上使用它。

您可以在下面找到示例

int th_distance = 18; // radius tolerance

int th2 = th_distance * th_distance; // squared radius tolerance
vector<int> labels;

int n_labels = partition(pts, labels, [th2](const Point& lhs, const Point& rhs) 
    return ((lhs.x - rhs.x)*(lhs.x - rhs.x) + (lhs.y - rhs.y)*(lhs.y - rhs.y)) < th2; 
);

->

其中每种颜色表示一个片段。您可以调整视频的参数

然后基于初始聚类,使用凸包得到每辆汽车的正确形状。

这里是示例https://docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/hull/hull.html

最后,将运动向量聚合成最终向量K,并在船体中心表示最终向量K。

然后将每张图像的最终向量K连接起来,形成一个轨迹。

【讨论】:

以上是关于如何在opencv中使用光流跟踪来分割图像?的主要内容,如果未能解决你的问题,请参考以下文章

基于光流的图像分割

基于 OpenCV 图像的光流场

如何在openCV python中将背景减法与密集光流跟踪相结合

图像稳定光流

OpenCV中的光流及视频特征点追踪

光流和手指跟踪