当前位置:   article > 正文

关于OpenCV的Mat图像拼接(Java版本)_opencv for java 拼接

opencv for java 拼接

项目需求中需要把两个图片横向拼接到一起,最初的想法是遍历每个Mat的每个元素值,拷贝到新的Mat中,但是测试发现:性能问题堪忧啊,两个1920x1080的图片拼接就要耗时500多毫秒。所以就要另辟蹊径了~

正文

这个拼接函数可以实现两个相同类型(如:同为单通道灰度图、或者3通道彩色图、或4通道argb图)、尺寸不同的两个图片(Mat)的水平方向的拼接。

这里使用了Mat类的 colRange() copyTo().

colRange方法是指定一个区域范围作为选区,返回这个选区,它也是Mat类型。

copyTo方法就一目了然了,不多介绍。

下面是我测试的代码:

  1. package com.blc.face;
  2. import org.opencv.core.Mat;
  3. import org.opencv.core.Range;
  4. public class Test {
  5. /**
  6. * 横向拼接两个图像的数据(Mat),该两个图像的类型必须是相同的类型,如:均为CvType.CV_8UC3类型
  7. * @author bailichun
  8. * @since 2020.02.20 15:00
  9. * @param m1 要合并的图像1(左图)
  10. * @param m2 要合并的图像2(右图)
  11. * @return 拼接好的Mat图像数据集。其高度等于两个图像中高度较大者的高度;其宽度等于两个图像的宽度之和。类型与两个输入图像相同。
  12. * @throws Exception 当两个图像数据的类型不同时,抛出异常
  13. */
  14. public Mat concat(Mat m1, Mat m2) throws Exception{
  15. System.out.println("图1 width="+m1.size().width);
  16. System.out.println("图1 height="+m1.size().height);
  17. System.out.println("图2 width="+m2.size().width);
  18. System.out.println("图2 height="+m2.size().height);
  19. if(m1.type() != m2.type()){
  20. throw new Exception("concat:两个图像数据的类型不同!");
  21. }
  22. long time = System.currentTimeMillis();
  23. //宽度为两图的宽度之和
  24. double w = m1.size().width + m2.size().width;
  25. //高度取两个矩阵中的较大者的高度
  26. double h = m1.size().height > m2.size().height ? m1.size().height : m2.size().height;
  27. //创建一个大矩阵对象
  28. Mat des = Mat.zeros((int)h, (int)w, m1.type());
  29. //在最终的大图上标记一块区域,用于存放复制图1(左图)的数据,大小为从第0列到m1.cols()列
  30. Mat rectForM1 = des.colRange(new Range(0, m1.cols()));
  31. //标记出位于rectForM1的垂直方向上中间位置的区域,高度为图1的高度,此时该区域的大小已经和图1的大小相同。(用于存放复制图1(左图)的数据)
  32. int rowOffset1 = (int)(rectForM1.size().height-m1.rows())/2;
  33. rectForM1 = rectForM1.rowRange(rowOffset1, rowOffset1 + m1.rows());
  34. //在最终的大图上标记一块区域,用于存放复制图2(右图)的数据
  35. Mat rectForM2 = des.colRange(new Range(m1.cols(), des.cols()));
  36. //标记出位于rectForM2的垂直方向上中间位置的区域,高度为图2的高度,此时该区域的大小已经和图2的大小相同。(用于存放复制图2(右图)的数据)
  37. int rowOffset2 = (int)(rectForM2.size().height-m2.rows())/2;
  38. rectForM2 = rectForM2.rowRange(rowOffset2, rowOffset2 + m2.rows());
  39. //将图1拷贝到des的指定区域 rectForM1
  40. m1.copyTo(rectForM1);
  41. //将图2拷贝到des的指定区域 rectForM2
  42. m2.copyTo(rectForM2);
  43. System.out.println("图片合并耗时:"+(System.currentTimeMillis()-time)+"ms");
  44. return des;
  45. }
  46. }

 

效果图1(两个大小相同的图片拼接):

 

效果图2(两个宽度相同,高度不同的图片拼接):

 

效果图3(两个高度相同,宽度不同的图片拼接):

 

这是控制台打印的数据:

  1. 1 width=1920.0
  2. 1 height=1080.0
  3. 2 width=1920.0
  4. 2 height=1080.0
  5. 图片合并耗时:8ms

 

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

闽ICP备14008679号