如果要實現兩個圖片橫向拼接一起,若通過遍歷每個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; } }