当前位置:   article > 正文

C#联合OpenCV进行图像拼接_opencv c#实现图像合并和融合

opencv c#实现图像合并和融合

CsharpOpencv图像拼接

简单的图像拼接

简单粗暴的将两张图片水平或者垂直拼接

                                                                

  1. var image1= Cv2.ImRead("mandrill.png", ImreadModes.Color);
  2. var image2 = Cv2.ImRead("lenna.png", ImreadModes.Color);
  3. //修改图片的尺寸
  4. Cv2.Resize(image1, image1, image2.Size());
  5. var Himagejoint = new Mat();
  6. var Vimagejoint = new Mat();
  7. var imagetuple = new Mat[] { image1, image2 };
  8. //水平拼接
  9. Cv2.HConcat(imagetuple, Himagejoint);
  10. //垂直拼接
  11. Cv2.VConcat(imagetuple, Vimagejoint);
  12. Cv2.ImShow("Himagejoint", Himagejoint);
  13. 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

使用C#代码进行(20230223代码更新)

  1. //Mat Left = Cv2.ImRead(System.Windows.Forms.Application.StartupPath + "\\ImageTest\\pingjie1.jpg", ImreadModes.AnyColor);
  2. //Mat Right = Cv2.ImRead(System.Windows.Forms.Application.StartupPath + "\\ImageTest\\pingjie2.jpg", ImreadModes.AnyColor);
  3. var sift = SIFT.Create();
  4. var descriptors1 = new Mat<float>();
  5. var descriptors2 = new Mat<float>();
  6. sift.DetectAndCompute(Left, null, out var keypoints1, descriptors1);
  7. sift.DetectAndCompute(Right, null, out var keypoints2, descriptors2);
  8. var bf = new BFMatcher();
  9. var Matchs = bf.Match(descriptors1, descriptors2);
  10. if (Matchs.Length > 10)
  11. {
  12. //冒泡排序
  13. for (int i = 0; i < Matchs.Length - 1; i++)
  14. {
  15. for (int j = 0; j < Matchs.Length - 1 - i; j++)
  16. {
  17. if (Matchs[j] > Matchs[j + 1])
  18. {
  19. var temp = Matchs[j];
  20. Matchs[j] = Matchs[j + 1];
  21. Matchs[j + 1] = temp;
  22. }
  23. }
  24. }
  25. List<DMatch> goodmatchs = new List<DMatch>();
  26. for (int i = 0; i < 50; i++)
  27. {
  28. goodmatchs.Add(Matchs[i]);
  29. }
  30. Mat Dst_Images = new Mat();
  31. Cv2.DrawMatches(Left, keypoints1, Right, keypoints2, goodmatchs, Dst_Images, Scalar.Red, Scalar.Green, null, DrawMatchesFlags.NotDrawSinglePoints);
  32. // Cv2.ImShow("goodmatchs", Dst_Images);
  33. //3特征点匹配
  34. List<Point2d> imagepoint1 = new List<Point2d> { };
  35. List<Point2d> imagepoint2 = new List<Point2d> { };
  36. for (int j = 0; j < goodmatchs.Count; j++)
  37. {
  38. //查找特征点可连接处 变形
  39. Point2d point2D = new Point2d(0, 0);
  40. if (goodmatchs[j].TrainIdx > Matchs.Length)
  41. {
  42. continue;
  43. }
  44. point2D.X = Convert.ToDouble(keypoints1[goodmatchs[j].QueryIdx].Pt.X);
  45. point2D.Y = Convert.ToDouble(keypoints1[goodmatchs[j].QueryIdx].Pt.Y);
  46. imagepoint1.Add(point2D);
  47. //查找特征点可连接处 查找基准线
  48. point2D.X = Convert.ToDouble(keypoints2[goodmatchs[j].TrainIdx].Pt.X);
  49. point2D.Y = Convert.ToDouble(keypoints2[goodmatchs[j].TrainIdx].Pt.Y);
  50. imagepoint2.Add(point2D);
  51. }
  52. //4 透视变换图形融合
  53. Mat homo = Cv2.FindHomography(imagepoint2, imagepoint1, HomographyMethods.Ransac);
  54. Mat imageTranForm = new Mat();
  55. CalcCorners(homo, Right);
  56. Cv2.WarpPerspective(Right, imageTranForm, homo, new Size(Left.Cols + Left.Cols - 40, Left.Rows));
  57. Cv2.WarpPerspective(Right, imageTranForm, homo, new Size(Math.Max(corners.right_top.X, corners.right_bottom.X), Left.Rows));
  58. // Cv2.ImShow("imageTranForm", imageTranForm);
  59. //创建拼接后的图,计算图的大小
  60. int dst_width = imageTranForm.Cols;//获取最右点为拼接图长度
  61. int dst_height = Left.Rows;
  62. Mat dst = new Mat(dst_height, dst_width, MatType.CV_8UC3);
  63. dst.SetTo(0);
  64. imageTranForm.CopyTo(new Mat(dst, (new Rect(0, 0, imageTranForm.Cols, imageTranForm.Rows))));
  65. Left.CopyTo(new Mat(dst, (new Rect(0, 0, Left.Cols, Left.Rows))));
  66. // Cv2.ImShow("imageTranForm3", dst);
  67. dst.CopyTo(dstimage);
  68. }
  69. else
  70. {
  71. //System.Windows.Forms.MessageBox.Show("特征点过少");
  72. }
  73. return;

  1. 增加矩阵计算功能,消除图像黑边 图像配准
  2. public struct four_corners_t
  3. {
  4. public Point2d left_top;
  5. public Point2d left_bottom;
  6. public Point2d right_top;
  7. public Point2d right_bottom;
  8. };
  9. public static four_corners_t corners = new four_corners_t();
  10. public static void CalcCorners(Mat H, Mat src)
  11. {
  12. double[,] matrix3x3 = new double[3, 3] {
  13. { H.Get<double>(0, 0), H.Get<double>(0, 1), H.Get<double>(0, 2) },
  14. { H.Get<double>(1, 0), H.Get<double>(1, 1), H.Get<double>(1, 2) },
  15. { H.Get<double>(2, 0), H.Get<double>(2, 1), H.Get<double>(2,2) }
  16. };
  17. // 左上角(0, 0, 1)
  18. double[,] result = new double[3, 1];
  19. double[,] matrix1x3 = new double[3, 1] { { 0.0 }, { 0.0 }, { 1.0 } };
  20. for (int i = 0; i < 3; i++)
  21. {
  22. for (int j = 0; j < 1; j++)
  23. {
  24. double sum = 0;
  25. for (int k = 0; k < 3; k++)
  26. {
  27. sum += matrix3x3[i, k] * matrix1x3[k, j];
  28. }
  29. result[i, j] = sum;
  30. }
  31. }
  32. corners.left_top.X = result[0, 0] / result[2, 0];
  33. corners.left_top.Y = result[1, 0] / result[2, 0];
  34. //左下角(0,src.rows,1)
  35. result = new double[3, 1];
  36. matrix1x3 = new double[3, 1] { { 0.0 }, { src.Rows }, { 1.0 } };
  37. for (int i = 0; i < 3; i++)
  38. {
  39. for (int j = 0; j < 1; j++)
  40. {
  41. double sum = 0;
  42. for (int k = 0; k < 3; k++)
  43. {
  44. sum += matrix3x3[i, k] * matrix1x3[k, j];
  45. }
  46. result[i, j] = sum;
  47. }
  48. }
  49. corners.left_bottom.X = result[0, 0] / result[2, 0];
  50. corners.left_bottom.Y = result[1, 0] / result[2, 0];
  51. //右上角(src.cols,0,1)
  52. result = new double[3, 1];
  53. matrix1x3 = new double[3, 1] { { src.Cols }, { 0.0 }, { 1.0 } };
  54. for (int i = 0; i < 3; i++)
  55. {
  56. for (int j = 0; j < 1; j++)
  57. {
  58. double sum = 0;
  59. for (int k = 0; k < 3; k++)
  60. {
  61. sum += matrix3x3[i, k] * matrix1x3[k, j];
  62. }
  63. result[i, j] = sum;
  64. }
  65. }
  66. corners.right_top.X = result[0, 0] / result[2, 0];
  67. corners.right_top.Y = result[1, 0] / result[2, 0];
  68. //右下角(src.cols,src.rows,1)
  69. result = new double[3, 1];
  70. matrix1x3 = new double[3, 1] { { src.Cols }, { src.Rows }, { 1.0 } };
  71. for (int i = 0; i < 3; i++)
  72. {
  73. for (int j = 0; j < 1; j++)
  74. {
  75. double sum = 0;
  76. for (int k = 0; k < 3; k++)
  77. {
  78. sum += matrix3x3[i, k] * matrix1x3[k, j];
  79. }
  80. result[i, j] = sum;
  81. }
  82. }
  83. corners.right_bottom.X = result[0, 0] / result[2, 0];
  84. corners.right_bottom.Y = result[1, 0] / result[2, 0];
  85. }

拼接效果图

图片不要从这里下载哦!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/81503
推荐阅读
相关标签
  

闽ICP备14008679号