<p>OpenCV(以及pythonopencv绑定)有一个实现<a href="http://www.springerlink.com/content/ngx06074r126x362/" rel="nofollow">this algorithm</a>的<a href="http://opencv.willowgarage.com/documentation/cpp/feature_detection.html#stardetector" rel="nofollow">StarDetector</a>类。</p>
<p>作为替代方案,您可以查看OpenCV<a href="http://opencv.itseez.com/modules/features2d/doc/feature_detection_and_description.html#sift" rel="nofollow">SIFT</a>类,它代表比例不变的特征变换。</p>
<p><strong>更新</strong></p>
<p>关于您的评论,我理解“正确的”转换将最大化图像之间的互相关,但我不理解您如何选择最大化转换集。也许如果你知道三个匹配点的坐标(通过一些启发式方法或者通过手工选择),如果你希望有亲和力,你可以使用<a href="http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html#cv-getaffinetransform" rel="nofollow">cv2.getAffineTransform</a>这样的东西,为你的最大化过程有一个良好的初始转换。从这里开始,您可以使用小的附加转换来获得一个最大化的集合。但在我看来,这种方法就像是重新发明了SIFT可以处理的东西。</p>
<p>要实际转换测试图像,可以使用<a href="http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html#cv-warpaffine" rel="nofollow">cv2.warpAffine</a>,它还可以处理边界值(例如,使用0填充)。要计算互相关,可以使用<a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.correlate2d.html#scipy.signal.correlate2d" rel="nofollow">scipy.signal.correlate2d</a>。</p>
<p><strong>更新</strong></p>
<p>你最近的更新确实为我澄清了一些问题。但我认为位移向量场不是最自然的,这也是误解的来源。我想更多的是沿着<strong>全局</strong>变换T的线,它应用于左图像的任何点(x,y),在右侧给出(x',y')=T(x,y),但是T对每个像素都有相同的分析形式。例如,这可能是位移、旋转、缩放的组合,也可能是一些透视变换。我不能说希望找到这样的变换是否现实,这取决于你的设置,但如果场景在物理上是相同的,我会说,期望一些仿射变换是合理的。这就是我建议<a href="http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html#cv-getaffinetransform" rel="nofollow">cv2.getAffineTransform</a>的原因。从这样的T计算位移向量场当然很简单,因为这只是T(x,y)-(x,y)。</p>
<p>最大的优点是你的变换只有很少的自由度,而不是,我认为,位移向量场中的2N自由度,其中N是亮点的数量。</p>
<p>如果它确实是仿射变换,我建议使用如下算法:</p>
<ul>
<li>确定左侧三个明亮且隔离良好的点</li>
<li>对于这三个点中的每一个点,定义一个边界框,这样您就可以希望在正确的图像中识别其中相应的点</li>
<li>找到相应点的坐标,例如,使用<a href="http://opencv.itseez.com/modules/imgproc/doc/object_detection.html?highlight=matchtemplate#cv2.matchTemplate" rel="nofollow">cv2.matchTemplate</a>中实现的一些相关方法,或者也只通过在边界框中找到最亮的点。</li>
<li>一旦有了三对匹配的坐标,就可以计算仿射变换,它用<a href="http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html#cv-getaffinetransform" rel="nofollow">cv2.getAffineTransform</a>将一个集合转换为另一个集合。</li>
<li>将此仿射变换应用于左图像,作为检查是否找到右图像的方法,可以计算整体规格化互相关是否高于某个阈值,或者如果将一个图像相对于另一个图像进行置换,则会显著下降。</li>
<li>如果你想而且仍然需要它,从你的变换T中简单地计算出位移向量场</li>
</ul>
<p><strong>更新</strong></p>
<p>似乎<a href="http://opencv.willowgarage.com/documentation/cpp/imgproc_geometric_image_transformations.html#cv-getaffinetransform" rel="nofollow">cv2.getAffineTransform</a>需要一个笨拙的输入数据类型“float32”。假设源坐标是<code>(sxi,syi)</code>,目标坐标是<code>(dxi,dyi)</code>,需要的是</p>
<pre><code>src = np.array( ((sx0,sy0),(sx1,sy1),(sx2,sy2)), dtype='float32' )
dst = np.array( ((dx0,dy0),(dx1,dy1),(dx2,dy2)), dtype='float32' )
result = cv2.getAffineTransform(src,dst)
</code></pre>