从一组四个点中对齐两个图像

Align two images from a set of four points each

我在 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)

图 2

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

在两个图像中,图像 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);

谢谢!

嗯, 假设你有 4 个点准确对应 - 解决方案非常简单。您必须使用 4 个对应关系计算图像之间的单应性透视变换(简而言之 - 单应性)。然后,您可以使用计算出的单应性来扭曲第二张图像,使其正好位于第一张图像上。 您可以使用 EmguCV 轻松完成。你有一个很好的例子来说明如何计算单应性并将其应用于图像: http://www.emgu.com/forum/viewtopic.php?f=7&t=4122 您可以将图像 2 视为源图像,将图像 1 视为目标图像。

答案是有几点是错误的,导致图像内容无法缩放,这是一个愚蠢但值得庆幸的简单错误。

其次要accord.net将输出保存为单独的图像,您可以使用以下代码:

var filter = new Rectification(homographyMatrix);
var result = filter.Apply(image);
result.Save("out.jpg", ImageFormat.Jpeg);

感谢 ezfn,我也在 emguCV 中实现了这个功能,但是论坛 post 还不完整,我解决了这个缺失的代码并在此处完成:

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");

感谢大家的帮助!