从每个四个点的集合中对齐两个图像

3

我正在C#中使用accord.net进行尝试,想要对齐两张图片。由于我是计算机视觉方面的新手,所以想知道accord.net是否可以完成此任务,或者我需要自己编写代码。

我有两张图片,每张图片都有四个点。这些点按照逆时针方向从图像左上角开始分配,即(TL, TR, BR, BL)。

示例:

图片1

Point 1(221, 156)
Point 2(4740, 156)
Point 3(4740, 3347)
Point 4(221, 3347)

图片1 - 盒子

图片2

Point 1(157, 213)
Point 2(4572, 32)
Point 3(4697, 3221)
Point 4(282, 3402)

图片2-旋转并缩小的框

这两张图片中,图像1的点1与图像2的点1相对应,其他点也一样。

因此,我想要做的是将这两张图像对齐,使得它们之间的比例、旋转和对齐匹配,并最终得到两张重叠后看起来像这张图片的图像:

结果

到目前为止,我已经做到了这一点,可以进行旋转和对齐,但无法缩放图像。根据我的理解,RANSAC似乎过于复杂,因为我已经将点进行了相关性分析?此外,我希望将输出的图像分别处理以供进一步的图像处理。

// Images
var img1Path = Path.Combine(filePath, "image1.jpg");
var image1 = new[] { new PointF(221, 156), new PointF(4740, 156), new PointF(4740, 3347), new PointF(221, 3347) };

var img2Path = Path.Combine(filePath, "image2.jpg");
var image2 = new[] { new PointF(157, 213), new PointF(4572, 32), new PointF(4697, 3221), new PointF(282, 3402) };

// Create Bitmaps
var img1 = new Bitmap(img1Path);
var img2 = new Bitmap(img2Path);

var ransac = new RansacHomographyEstimator(0.001, 0.99);
var homographyMatrix = ransac.Estimate(image1, image2);

var blend = new Blend(homographyMatrix, img1) { Gradient = false };
var result = blend.Apply(img2);

result.Save("out.jpg", ImageFormat.Jpeg);

谢谢!


虽然我不确定Accord.net是否可行,但是您可以使用EmguCV,它基本上是流行的OpenCV的.NET版本。 - Damjan Dakic
嗨,Damjan,你有没有关于如何在EmguCV中完成这个任务的链接或详细信息? - Rtype
我相信ezfn已经恰当地解释了一切 :) - Damjan Dakic
2个回答

3
答案原来是一些点错误,导致图像内容不能按比例缩放,这是一个愚蠢但幸运的简单错误。
其次,要让accord.net将输出保存为单独的图像,使用以下代码:
var filter = new Rectification(homographyMatrix);
var result = filter.Apply(image);
result.Save("out.jpg", ImageFormat.Jpeg);

感谢ezfn,我也在emguCV中使这个工作起来了,但是论坛帖子不完整,我找到了这个缺失的代码并完成了它:

var srcImagePath = Path.Combine(FilePath, "image2.jpg");
var dstImagePath = Path.Combine(FilePath, "image1.jpg");

var srcImage = new Image<Bgr, int>(srcImagePath);
var dstImage = new Image<Bgr, int>(dstImagePath);

float[,] srcPoints = { { 221, 156 }, { 4740, 156 }, { 4740, 3347 }, { 221, 3347 } };
float[,] dstPoints = { { 371, 356 }, { 4478, 191 }, { 4595, 3092 }, { 487, 3257 } };

var srcMat = new Matrix<float>(srcPoints);
var dstMat = new Matrix<float>(dstPoints);

var homogMat = new Matrix<float>(3, 3);
var invertHomogMat = new Matrix<float>(3, 3);
var maskMat = new IntPtr();

var s = new MCvScalar(0, 0, 0);

// .Ptr?
CvInvoke.cvFindHomography(srcMat, dstMat, homogMat, HOMOGRAPHY_METHOD.DEFAULT, 3.0, maskMat);
CvInvoke.cvInvert(homogMat, invertHomogMat, SOLVE_METHOD.CV_LU);
CvInvoke.cvWarpPerspective(srcImage, dstImage, invertHomogMat, (int)INTER.CV_INTER_NN, s);

dstImage.Save("2.jpg");

感谢大家的帮助!

2
假设您已经准确地对应了这4个点,解决方案非常简单。您需要使用这4个对应点计算图像之间的同构透视变换(简称同态),然后可以使用计算出的同态将第二个图像变形,使其完全位于第一个图像上。 您可以轻松使用EmguCV完成此操作。您可以参考以下示例来计算同态并将其应用于图像: http://www.emgu.com/forum/viewtopic.php?f=7&t=4122 在此示例中,您可以将图像2视为源图像,将图像1视为目标图像。

谢谢ezfn,我今天下午会尝试一下。你知道如何在accord.net中实现这个吗?另外,你说很简单,你可能有一个简单的例子吗?正如我所说,我是计算机视觉方面的新手,真的很想了解它是如何工作的。 - Rtype
嗨,我引用的例子实际上将展示在您的情况下它有多简单。一旦您拥有相应的点,这是一个两行解决方案。让我们知道是否有任何困难。我不熟悉accord.net - 但对于计算机视觉,我认为EmguCV是合适的。 - ezfn
嗨,ezfn,那个论坛上发布的解决方案基本上都有了,但实际上缺少了一行关键代码:CvInvoke.cvInvert(homogMat,invertHomogMat,SOLVE_METHOD.CV_LU); - Rtype

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接