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

谢谢!

4

2 回答 2

2

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

于 2015-01-13T16:26:25.927 回答
2

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

其次,让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");

感谢大家的帮助!

于 2015-01-15T00:13:08.403 回答