赞
踩
简单粗暴的将两张图片水平或者垂直拼接
- var image1= Cv2.ImRead("mandrill.png", ImreadModes.Color);
- var image2 = Cv2.ImRead("lenna.png", ImreadModes.Color);
- //修改图片的尺寸
- Cv2.Resize(image1, image1, image2.Size());
- var Himagejoint = new Mat();
- var Vimagejoint = new Mat();
- var imagetuple = new Mat[] { image1, image2 };
- //水平拼接
- Cv2.HConcat(imagetuple, Himagejoint);
- //垂直拼接
- Cv2.VConcat(imagetuple, Vimagejoint);
-
- Cv2.ImShow("Himagejoint", Himagejoint);
- Cv2.ImShow("Vimagejoint", Vimagejoint);
参考C++版本https://www.jb51.net/article/255900.htm](https://www.jb51.net/article/255900.htm
参考Python版本https://www.jb51.net/article/214191.htm](https://www.jb51.net/article/214191.htm
- //Mat Left = Cv2.ImRead(System.Windows.Forms.Application.StartupPath + "\\ImageTest\\pingjie1.jpg", ImreadModes.AnyColor);
- //Mat Right = Cv2.ImRead(System.Windows.Forms.Application.StartupPath + "\\ImageTest\\pingjie2.jpg", ImreadModes.AnyColor);
- var sift = SIFT.Create();
- var descriptors1 = new Mat<float>();
- var descriptors2 = new Mat<float>();
- sift.DetectAndCompute(Left, null, out var keypoints1, descriptors1);
- sift.DetectAndCompute(Right, null, out var keypoints2, descriptors2);
- var bf = new BFMatcher();
- var Matchs = bf.Match(descriptors1, descriptors2);
- if (Matchs.Length > 10)
- {
- //冒泡排序
- for (int i = 0; i < Matchs.Length - 1; i++)
- {
- for (int j = 0; j < Matchs.Length - 1 - i; j++)
- {
- if (Matchs[j] > Matchs[j + 1])
- {
- var temp = Matchs[j];
- Matchs[j] = Matchs[j + 1];
- Matchs[j + 1] = temp;
- }
- }
- }
- List<DMatch> goodmatchs = new List<DMatch>();
- for (int i = 0; i < 50; i++)
- {
- goodmatchs.Add(Matchs[i]);
- }
- Mat Dst_Images = new Mat();
- Cv2.DrawMatches(Left, keypoints1, Right, keypoints2, goodmatchs, Dst_Images, Scalar.Red, Scalar.Green, null, DrawMatchesFlags.NotDrawSinglePoints);
- // Cv2.ImShow("goodmatchs", Dst_Images);
-
- //3特征点匹配
- List<Point2d> imagepoint1 = new List<Point2d> { };
- List<Point2d> imagepoint2 = new List<Point2d> { };
- for (int j = 0; j < goodmatchs.Count; j++)
- {
- //查找特征点可连接处 变形
- Point2d point2D = new Point2d(0, 0);
- if (goodmatchs[j].TrainIdx > Matchs.Length)
- {
- continue;
- }
- point2D.X = Convert.ToDouble(keypoints1[goodmatchs[j].QueryIdx].Pt.X);
- point2D.Y = Convert.ToDouble(keypoints1[goodmatchs[j].QueryIdx].Pt.Y);
- imagepoint1.Add(point2D);
- //查找特征点可连接处 查找基准线
- point2D.X = Convert.ToDouble(keypoints2[goodmatchs[j].TrainIdx].Pt.X);
- point2D.Y = Convert.ToDouble(keypoints2[goodmatchs[j].TrainIdx].Pt.Y);
- imagepoint2.Add(point2D);
- }
- //4 透视变换图形融合
- Mat homo = Cv2.FindHomography(imagepoint2, imagepoint1, HomographyMethods.Ransac);
- Mat imageTranForm = new Mat();
- CalcCorners(homo, Right);
- Cv2.WarpPerspective(Right, imageTranForm, homo, new Size(Left.Cols + Left.Cols - 40, Left.Rows));
- Cv2.WarpPerspective(Right, imageTranForm, homo, new Size(Math.Max(corners.right_top.X, corners.right_bottom.X), Left.Rows));
-
- // Cv2.ImShow("imageTranForm", imageTranForm);
- //创建拼接后的图,计算图的大小
- int dst_width = imageTranForm.Cols;//获取最右点为拼接图长度
- int dst_height = Left.Rows;
- Mat dst = new Mat(dst_height, dst_width, MatType.CV_8UC3);
- dst.SetTo(0);
- imageTranForm.CopyTo(new Mat(dst, (new Rect(0, 0, imageTranForm.Cols, imageTranForm.Rows))));
- Left.CopyTo(new Mat(dst, (new Rect(0, 0, Left.Cols, Left.Rows))));
- // Cv2.ImShow("imageTranForm3", dst);
- dst.CopyTo(dstimage);
-
- }
- else
- {
- //System.Windows.Forms.MessageBox.Show("特征点过少");
- }
- return;
-
- 增加矩阵计算功能,消除图像黑边 图像配准
-
-
- public struct four_corners_t
- {
- public Point2d left_top;
- public Point2d left_bottom;
- public Point2d right_top;
- public Point2d right_bottom;
- };
- public static four_corners_t corners = new four_corners_t();
- public static void CalcCorners(Mat H, Mat src)
- {
-
- double[,] matrix3x3 = new double[3, 3] {
- { H.Get<double>(0, 0), H.Get<double>(0, 1), H.Get<double>(0, 2) },
- { H.Get<double>(1, 0), H.Get<double>(1, 1), H.Get<double>(1, 2) },
- { H.Get<double>(2, 0), H.Get<double>(2, 1), H.Get<double>(2,2) }
- };
- // 左上角(0, 0, 1)
- double[,] result = new double[3, 1];
- double[,] matrix1x3 = new double[3, 1] { { 0.0 }, { 0.0 }, { 1.0 } };
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 1; j++)
- {
- double sum = 0;
- for (int k = 0; k < 3; k++)
- {
- sum += matrix3x3[i, k] * matrix1x3[k, j];
- }
- result[i, j] = sum;
- }
- }
- corners.left_top.X = result[0, 0] / result[2, 0];
- corners.left_top.Y = result[1, 0] / result[2, 0];
-
-
- //左下角(0,src.rows,1)
- result = new double[3, 1];
- matrix1x3 = new double[3, 1] { { 0.0 }, { src.Rows }, { 1.0 } };
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 1; j++)
- {
- double sum = 0;
- for (int k = 0; k < 3; k++)
- {
- sum += matrix3x3[i, k] * matrix1x3[k, j];
- }
- result[i, j] = sum;
- }
- }
- corners.left_bottom.X = result[0, 0] / result[2, 0];
- corners.left_bottom.Y = result[1, 0] / result[2, 0];
-
- //右上角(src.cols,0,1)
- result = new double[3, 1];
- matrix1x3 = new double[3, 1] { { src.Cols }, { 0.0 }, { 1.0 } };
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 1; j++)
- {
- double sum = 0;
- for (int k = 0; k < 3; k++)
- {
- sum += matrix3x3[i, k] * matrix1x3[k, j];
- }
- result[i, j] = sum;
- }
- }
- corners.right_top.X = result[0, 0] / result[2, 0];
- corners.right_top.Y = result[1, 0] / result[2, 0];
- //右下角(src.cols,src.rows,1)
- result = new double[3, 1];
- matrix1x3 = new double[3, 1] { { src.Cols }, { src.Rows }, { 1.0 } };
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 1; j++)
- {
- double sum = 0;
- for (int k = 0; k < 3; k++)
- {
- sum += matrix3x3[i, k] * matrix1x3[k, j];
- }
- result[i, j] = sum;
- }
- }
- corners.right_bottom.X = result[0, 0] / result[2, 0];
- corners.right_bottom.Y = result[1, 0] / result[2, 0];
- }
图片不要从这里下载哦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。