我得到了两张图片,显示了同样的内容:二维高斯形状的斑点。我把这两个16位png文件称为“left.png”和“right.png”。但由于它们是通过稍微不同的光学设置获得的,相应的光斑(物理上相同)出现在稍微不同的位置。也就是说,右边的部分有轻微的拉伸,扭曲,或者说是非线性的。所以我想从左到右进行转换。
所以对于左边的每一个像素,它的x和y坐标,我想要一个函数,给我一个位移向量的分量,它指向右边对应的像素。
在前一种方法中,我试图得到相应点的位置,以获得deltaX和deltaY的相对距离。然后,我将这些距离拟合到泰勒展开式,直到T(x,y)的二阶,给出了左边每个像素(x,y)的位移向量的x和y分量,指向右边相应的像素(x',y')。
为了得到更一般的结果,我想使用归一化互相关。为此,我从左开始将每个像素值与从右开始的相应像素值相乘,并对这些乘积求和。我正在寻找的转换应该连接最大化总和的像素。所以当和最大化时,我知道我乘以了相应的像素。
我真的试了很多,但没成功。我的问题是你们中是否有人有过类似的想法或做过类似的事情。
import numpy as np
import Image
left = np.array(Image.open('left.png'))
right = np.array(Image.open('right.png'))
# for normalization (http://en.wikipedia.org/wiki/Cross-correlation#Normalized_cross-correlation)
left = (left - left.mean()) / left.std()
right = (right - right.mean()) / right.std()
如果我能把这个问题说清楚,请告诉我。我还得看看如何用乳胶发问。
非常感谢您的意见。
[左.png]http://i.stack.imgur.com/oSTER.png [右.png]http://i.stack.imgur.com/Njahj.png
恐怕,在大多数情况下,16位图像看起来只是黑色的(至少在我使用的系统上是这样的):(当然,里面有数据)。
我试图澄清我的问题。我正在寻找一个向量场,它的位移向量从left.png中的每个像素指向right.png中相应的像素。我的问题是,我不确定我有什么限制。
其中,向量r(分量x和y)指向left.png中的像素,向量r-prime(分量x-prime和y-prime)指向right.png中的相应像素。每r有一个位移矢量。
我之前所做的是,我手动找到向量场d的分量,并将它们拟合成一个二次多项式:
所以我适合:
这对你有意义吗?有可能得到所有具有互相关的delta-x(x,y)和delta-y(x,y)吗?如果对应的像素通过位移向量连接在一起,那么互相关应该最大化,对吧?
所以我想的算法如下:
关于变形:一个人可以先沿x和y方向移动以使互相关最大化,然后在第二步中拉伸或压缩x和y相关,在第三步中变形二次x和y相关,并重复此过程迭代??我真的有一个问题做这个整数坐标。你认为我需要插入图片以获得连续分布吗??我得再考虑一下:(谢谢大家的参与:)
我不认为互相关在这里会有帮助,因为它只会给你一个最佳的整体图像偏移。我可以考虑三种选择:
在点的子簇上做一个互相关。以右上角的三个点为例,通过互相关找到最佳的x-y偏移。这将为您提供左上角的粗略变换。对尽可能多的集群重复此操作,以获得转换的合理映射。把这个和你的泰勒展开匹配,你可能会得到相当接近的结果。但是,要以任何方式进行互相关工作,点之间的位移差必须小于点的延伸,否则永远无法使群集中的所有点与单个位移同时重叠。在这种情况下,选择2可能更合适。
如果位移相对较小(我认为这是选项1的一个条件),那么我们可以假设对于左图像中的给定点,右图像中最近的点是对应的点。因此,对于左图像中的每个点,我们找到右图像中最近的点,并将其用作该位置的位移。从40多个均匀分布的位移矢量中,我们可以通过拟合泰勒展开得到实际位移的合理近似值。
这可能是最慢的方法,但如果位移较大(因此选项2不起作用),则可能是最稳健的方法:使用类似于进化算法的方法来查找位移。应用随机变换,计算剩余误差(您可能需要将其定义为原始图像和变换图像中点之间最小距离的和),并使用这些结果改进变换。如果你的位移相当大,你可能需要一个非常广泛的搜索,因为你可能会在你的景观很多地方的最小值。
我会尝试选择2,因为看起来你的位移可能很小,可以很容易地将左图中的一个点与右图中的一个点关联起来。
更新
我假设你们的光学系统会导致非线性失真,并且有两个独立的光束路径(每个路径有不同的滤波器?)会使两幅图像之间的关系更加非线性。PiQuer提出的仿射变换可能给出一个合理的方法,但可能永远无法完全覆盖实际的失真。
我认为你拟合低阶泰勒多项式的方法很好。这适用于我所有有类似条件的应用程序。最高的阶数应该是xy^2和x^2y;任何高于这个值的都不会被注意到。
或者,您可以先校准每个图像的失真,然后再进行实验。这样你就不依赖于点的分布,而是可以使用高分辨率的参考图像来获得变换的最佳描述。
上面的选项2仍然是我的建议,让两个图像重叠。这可以是完全自动化的,我不知道你想要更一般的结果是什么意思。
更新2
你评论说你在匹配这两幅图像中的点时遇到了困难。如果是这样的话,我认为迭代互相关方法可能也不是很健壮。你有非常小的点,所以只有当两个图像之间的差异很小时,它们之间才会重叠。
原则上,你提出的解决方案没有错,但它是否有效在很大程度上取决于变形的大小和优化算法的稳健性。如果从很少的重叠开始,那么可能很难找到一个好的优化起点。然而,如果你有足够的重叠开始,那么你应该能够找到每个点的变形首先,但在一个com你说这不管用。
也许你可以选择一个混合的解决方案:找到点簇的互相关,为你的优化找到一个起点,然后像你在更新中描述的那样调整变形。因此:
OpenCV(以及pythonopencv绑定)有一个实现this algorithm的StarDetector类。
作为替代方案,您可以查看OpenCVSIFT类,它代表比例不变的特征变换。
更新
关于您的评论,我理解“正确的”转换将最大化图像之间的互相关,但我不理解您如何选择最大化转换集。也许如果你知道三个匹配点的坐标(通过一些启发式方法或者通过手工选择),如果你希望有亲和力,你可以使用cv2.getAffineTransform这样的东西,为你的最大化过程有一个良好的初始转换。从这里开始,您可以使用小的附加转换来获得一个最大化的集合。但在我看来,这种方法就像是重新发明了SIFT可以处理的东西。
要实际转换测试图像,可以使用cv2.warpAffine,它还可以处理边界值(例如,使用0填充)。要计算互相关,可以使用scipy.signal.correlate2d。
更新
你最近的更新确实为我澄清了一些问题。但我认为位移向量场不是最自然的,这也是误解的来源。我想更多的是沿着全局变换T的线,它应用于左图像的任何点(x,y),在右侧给出(x',y')=T(x,y),但是T对每个像素都有相同的分析形式。例如,这可能是位移、旋转、缩放的组合,也可能是一些透视变换。我不能说希望找到这样的变换是否现实,这取决于你的设置,但如果场景在物理上是相同的,我会说,期望一些仿射变换是合理的。这就是我建议cv2.getAffineTransform的原因。从这样的T计算位移向量场当然很简单,因为这只是T(x,y)-(x,y)。
最大的优点是你的变换只有很少的自由度,而不是,我认为,位移向量场中的2N自由度,其中N是亮点的数量。
如果它确实是仿射变换,我建议使用如下算法:
更新
似乎cv2.getAffineTransform需要一个笨拙的输入数据类型“float32”。假设源坐标是
(sxi,syi)
,目标坐标是(dxi,dyi)
,需要的是你可能想看看bunwarpj它已经做了你想做的事情。它不是python,但我正是在这个上下文中使用它的。您可以导出纯文本样条线转换,并在需要时使用它。
相关问题 更多 >
编程相关推荐