Align two images from a set of four points each

I am playing accord.net in C # and am trying to align two images. I'm new to computer vision and wondering if I can do it or if I have to write something myself.

I have two images and for each image I have four dots per image. Points are assigned counterclockwise around the image, starting from the top left, so (TL, TR, BR, BL)

Example:

Image 1

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

      

Image 1 - Box

Image 2

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

      

Image 2 - Box rotated and scaled down

In the two images, image 1 point 1 correlates with image 2 of point 1 with the rest of the points.

So what I would like to do is align the two images so that the scale, rotation and alignment are the same between the two images, and I end up with two images, when they overlap should look like this:

Result

So far I have this, which works for rotation and alignment, but does not scale the image. from my understanding RANSAC seems to be killing more for this job as I am already matching scores? Plus I would like the images to be released separately for further image processing.

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

      

Thank!

+3


source to share


2 answers


The answer turns out to be wrong because it is not, because not scaling the content of the image, silly but thankfully simple mistake.

and secondly, to ensure compatibility with share.net as separate images, you use this code:

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

      



Thanks to ezfn I also got this working in emguCV, but the forum post was not complete, I worked out this missing code and here it is complete:

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

      

Thanks everyone for the help!

+1


source


Well, assuming you have 4 points that match exactly - the solution is very simple. You must calculate the homographic perspective transformation (in short, homography) between images using 4 matches. You can then use the calculated homography to transform the second image so that it is exactly on the first image. You can do this easily using EmguCV. You have a great example of how to calculate homography and apply it to an image: http://www.emgu.com/forum/viewtopic.php?f=7&t=4122 Where you can treat image 2 as a sourceImage and image 1 - as dest.



+2


source







All Articles