Image 光流的简单情况

Image 光流的简单情况,image,matlab,image-processing,opencv,opticalflow,Image,Matlab,Image Processing,Opencv,Opticalflow,概述:我希望我将要描述的用例是光流问题的一个简单例子,因为我对这个问题没有太多的知识,我想知道是否有人对我如何解决我的问题有任何建议 我已经做过的研究:我已经开始阅读这篇论文,并计划翻阅这篇论文。我找到了一个用MATLAB实现的光流。然而,这些论文(和代码)似乎描述了一些非常复杂的概念,我可能需要花很多时间来深入研究和理解。我希望我的问题的解决办法可能更简单 问题:我有一系列图像。这些图像描述了材料破损过程,其中材料和背景为黑色,裂纹为白色。我感兴趣的是反向遍历图像序列,试图将破损过程中形成的所

概述:我希望我将要描述的用例是光流问题的一个简单例子,因为我对这个问题没有太多的知识,我想知道是否有人对我如何解决我的问题有任何建议

我已经做过的研究:我已经开始阅读这篇论文,并计划翻阅这篇论文。我找到了一个用MATLAB实现的光流。然而,这些论文(和代码)似乎描述了一些非常复杂的概念,我可能需要花很多时间来深入研究和理解。我希望我的问题的解决办法可能更简单

问题:我有一系列图像。这些图像描述了材料破损过程,其中材料和背景为黑色,裂纹为白色。我感兴趣的是反向遍历图像序列,试图将破损过程中形成的所有裂缝映射到第一张黑色图像。你可以把这种材料想象成一个大拼图,我试着把这些碎片按照它们断裂的相反顺序重新拼起来

在每张图像中,可能有一些刚刚出现的裂缝和/或一些已经完全形成的裂缝(因此产生了碎片)。在整个破碎过程中,一些碎片可能会分离并进一步破碎。片段也可以彼此移动得更远(后续帧之间的变化很小)

所需输出:序列中映射到序列中第一个图像的所有裂纹/线

其他注意事项:图像有灰度格式(即原始图像)和二进制格式,其中裂纹轮廓为白色,背景为完全黑色。请参见下面的一些图像示例

顶行显示原始图像,底行显示二进制图像。正如您所看到的,随着图像序列的进行,中间的裂缝越来越宽。因此,底部裂纹与下部碎片一起移动。当以相反的方式遍历序列时,我希望通过算法实现中间裂纹作为一个整体聚集在一起(并将其正确映射到第一幅图像),同时正确映射底部裂纹,保持其与底部碎片的正确对应(大小和位置)

一个序列通常包含30~40个图像,所以我刚刚展示了开始的子集。此外,尽管这些图像未显示裂纹,但特定图像可能仅包含裂纹的开始(即其初始外观),在后续图像中,裂纹变得越来越长,并可能与其他裂纹接合

语言:虽然没有必要,但我希望使用MATLAB实现解决方案(因为与项目相关的大多数其他代码都是在MATLAB中完成的)。然而,如果OpenCV可能更容易,我在语言/库的使用上是灵活的


非常感谢您的任何想法。

向前移动而不是反向移动,并且不要使用光流。使用断裂线分割黑色零件,随时间跟踪每个黑色分段的质心。每当出现穿过黑色线段的新断裂线时,请将该线段拆分为两条,并继续分别跟踪每条线段


由此,您应该能够构建一个树结构,表示随着时间的推移黑色部分的分割。断裂线可以作为元数据添加到此树中,可能会将断裂线指定给它们首次出现的线段节点

我建议您按照您最初的想法回溯裂缝。你知道裂缝是什么样子的,这样你就可以追踪所有属于裂缝的点。你只要用光流跟踪器跟踪所有的白点,从Lukas Kanade跟踪器开始,看看你从哪里得到。高精度光流方法是一种全局方法,而且更为通用,我将跟踪图像中的所有像素,试图在所有地方保持一定的平滑度。LK是一种局部方法,仅在每个点周围使用一个小窗口进行跟踪。问题是,从裂缝处看,所有的像素都是纯黑色的,所以没有什么可跟踪的,你只需要花一点时间来跟踪一些你无法跟踪、也不需要跟踪的东西。
如果直线很直,你可能会得到所谓的结果,你会得到不准确的结果。你也可以尝试一些基于蛇的形状拟合/变形。

我同意达米安的观点。大多数光流方法(如HAOF)都依赖于强度恒常收缩方程I(x,t)=I(x+v,t+dt)的一阶泰勒近似。这意味着解决方案取决于图像导数,其中梯度决定了运动矢量的大小和角度,即需要一定数量的纹理。但是,非二值化图像的极低纹理就足够了。您可以尝试直方图均衡化来增加输入数据的对比度,但重要的是对两个输入图像应用相同的变换。e、 g.如下:

cv::Mat equalizeMat(grayInp1.rows, grayInp1.cols * 2 , CV_8UC1);
grayInp1.copyTo(equalizeMat(cv::Rect(0,0,grayInp1.cols,grayInp1.rows))); 
grayInp2.copyTo(equalizeMat(cv::Rect(grayInp1.cols,0,grayInp2.cols,grayInp2.rows)));
cv::equalizeHist(equalizeMat,equalizeMat);
equalizeMat(cv::Rect(0,0,grayInp1.cols,grayInp1.rows)).copyTo(grayInp1);
equalizeMat(cv::Rect(grayInp1.cols,0,grayInp2.cols,grayInp2.rows)).copyTo(grayInp2);
// estimate optical flow

光流不会为黑白图像提供有意义的结果。此外,您的问题没有明确说明-您希望的输出是什么?和往常一样,示例图像当然有助于理解设置。为什么最后一个图像不是期望的输出?碎片能否相互移动越来越大的间隙?请提供图像。一般来说,算法需要纹理,不太适合二值图像。如果你提供你读过的论文的名称而不是PDF的链接,我会很有帮助。@Andrey:是的,在整个序列中,片段通常会随着间隔的增加而移动@etarion:创建二进制图像是因为我认为它可能会使算法更简单。原始灰度图像可用(请参见编辑)@阿迪:见编辑。你的解释是