I'm playing around in accord.net in C# and am trying to align two images. I'm new to computer vision and wondered if accord.net can do this or if I will have to write something myself.
I have two images and for each image I have four points per image. The points are assigned anti clockwise around the image starting with 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 2
Point 1(157, 213)
Point 2(4572, 32)
Point 3(4697, 3221)
Point 4(282, 3402)
In the two images image 1's point 1 correlates to image 2's point 1 same with the remaining points.
So what I would like to do is align the two images so the scale, rotation and alignment matches between the two images and I end up with two images when overlayed should look like this image:
So far I have this, which works for rotation and alignment but doesn't scale the image. from my understanding RANSAC seems to be over kill for this job as I'm already correlating the points? Plus I'd like the images output 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);
Thanks!
The answer turns out to be a couple of the points were wrong causing the non-scaling of the image content, a stupid but thankfully simple mistake.
and secondly to have accord.net save the output 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 isn't complete, I worked out this missing code and here it is completed:
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 to everyone for the help!