将两个图像从每组四个点对齐

时间:2015-01-12 08:27:02

标签: c# image image-processing accord.net image-registration

我正在使用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)

Image 1 - Box

图片2

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

Image 2 - Box rotated and scaled down

在两个图像中,图像1的点1与图像2的点1相关,与剩余的点相同。

所以我想要做的是对齐两个图像,使两个图像之间的比例,旋转和对齐匹配,并且当叠加时我最终得到两个图像应该看起来像这个图像:

Result

到目前为止,我有这个,它适用于旋转和对齐,但不会缩放图像。根据我的理解,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);

谢谢!

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

答案结果证明是一些错误导致图像内容不可缩放,这是一个愚蠢但幸亏的简单错误。

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

感谢大家的帮助!