如何使用编程语言 vb.net 或 C++ 或 C# 在相同的两个图像之间找到移位和旋转?
5 回答
您所说的问题称为运动检测(或运动补偿),是目前图像和视频处理中最重要的问题之一。除了一些非常琐碎的情况外,没有简单的“这里有十行代码可以做到”的解决方案。
即使您看似微不足道的情况也是一个相当困难的情况,因为未知角度的旋转可能会导致轻微的逐像素变化,如果没有专门定制的用于运动检测的算法,则无法轻松检测到这些变化。
如果图像非常相似,以至于相机只是稍微移动和旋转,那么问题可以在不使用高度复杂的技术的情况下解决。在这种情况下,我会做的是使用运动跟踪算法来获取图像序列的光流,这是一个“地图”,它近似于像素如何从图像 A“移动”到 B。OpenCV 这确实是一个非常好的库具有执行此操作的功能:CalcOpticalFlowLK和CalcOpticalFlowPyrLK。
棘手的一点是从光流到图像的总旋转。我会首先对光流进行大量低通滤波,以获得更平滑的地图。然后您需要使用一些逻辑来测试图像是否仅移动或旋转。如果它只是移动,那么整个地图应该是一种“颜色”,即所有流向量都指向同一方向。如果发生了旋转,则矢量将根据旋转指向不同的方向。
如果输入图像不如上述方法要求的那么好,那么我会查看特征描述符以找出第一张图像中的特定对象如何位于第二张图像中。然而,这将更加困难。
没有简短的答案。您可以尝试使用免费的OpenCV库来查找两个图像之间的关系。
旋转和平移这两个操作可以按任意顺序确定。首先检测旋转要容易得多,因为您可以对其进行补偿。一旦两个图像的方向相同,翻译就变成了一个简单的相关问题。
找到图像的相对旋转最好通过确定局部梯度来完成。对于每个邻域(例如 3x3 像素),将灰度值视为函数 z(x,y),通过 9 个像素拟合一个平面,并确定该平面的斜率或梯度。现在平均你在整个图像上找到的梯度,或者至少是它的中心。你的两张图片会产生不同的平均值。部分原因是因为对于非 90 度旋转,图像不会完全重叠,但通常平均梯度的差异是两者之间的旋转。
旋转回一张图像后,您可以确定相关性。这是一个相当标准的操作;您实际上是在确定每个可能的偏移量,这两个图像的重叠程度。这将为您提供对班次的估计。
一旦你得到了这两个,你可以通过旋转平移、移动第二个图像并仅确定两个图像共有的像素的平均梯度来优化你的旋转角度估计。
如果图像完全相同,那么提取一些特征点应该相当容易——例如使用SIFT——并匹配两个图像的特征。然后,您可以使用任意两个匹配特征来查找旋转和平移。平移只是两个匹配特征点之间的差异。您在一张图像中补偿平移并获得旋转角度作为由三个剩余点形成的角度。