關於OpenCV的Mat影象拼接
阿新 • • 發佈:2022-03-01
如果要實現兩個圖片橫向拼接一起,若通過遍歷每個Mat的每個元素值,拷貝到新的Mat中,效能問題突出。
- colRange 方法是指定一個區域範圍作為選區,返回這個選區,它也是Mat型別。
package com.test.face; import org.opencv.core.Mat; import org.opencv.core.Range; public class Test { /** * 橫向拼接兩個影象的資料(Mat),該兩個影象的型別必須是相同的型別,如:均為CvType.CV_8UC3型別 * @param m1 要合併的影象1(左圖) * @param m2 要合併的影象2(右圖) * @return 拼接好的Mat影象資料集。其高度等於兩個影象中高度較大者的高度;其寬度等於兩個影象的寬度之和。型別與兩個輸入影象相同。 * @throws Exception 當兩個影象資料的型別不同時,丟擲異常 */ public Mat concat(Mat m1, Mat m2) throws Exception{ System.out.println("圖1 width="+m1.size().width); System.out.println("圖1 height="+m1.size().height); System.out.println("圖2 width="+m2.size().width); System.out.println("圖2 height="+m2.size().height); if(m1.type() != m2.type()){ throw new Exception("concat:兩個影象資料的型別不同!"); } long time = System.currentTimeMillis(); //寬度為兩圖的寬度之和 double w = m1.size().width + m2.size().width; //高度取兩個矩陣中的較大者的高度 double h = m1.size().height > m2.size().height ? m1.size().height : m2.size().height; //建立一個大矩陣物件 Mat des = Mat.zeros((int)h, (int)w, m1.type()); //在最終的大圖上標記一塊區域,用於存放複製圖1(左圖)的資料,大小為從第0列到m1.cols()列 Mat rectForM1 = des.colRange(new Range(0, m1.cols())); //標記出位於rectForM1的垂直方向上中間位置的區域,高度為圖1的高度,此時該區域的大小已經和圖1的大小相同。(用於存放複製圖1(左圖)的資料) int rowOffset1 = (int)(rectForM1.size().height-m1.rows())/2; rectForM1 = rectForM1.rowRange(rowOffset1, rowOffset1 + m1.rows()); //在最終的大圖上標記一塊區域,用於存放複製圖2(右圖)的資料 Mat rectForM2 = des.colRange(new Range(m1.cols(), des.cols())); //標記出位於rectForM2的垂直方向上中間位置的區域,高度為圖2的高度,此時該區域的大小已經和圖2的大小相同。(用於存放複製圖2(右圖)的資料) int rowOffset2 = (int)(rectForM2.size().height-m2.rows())/2; rectForM2 = rectForM2.rowRange(rowOffset2, rowOffset2 + m2.rows()); //將圖1拷貝到des的指定區域 rectForM1 m1.copyTo(rectForM1); //將圖2拷貝到des的指定區域 rectForM2 m2.copyTo(rectForM2); System.out.println("圖片合併耗時:"+(System.currentTimeMillis()-time)+"ms"); return des; } }