1. 程式人生 > 其它 >關於OpenCV的Mat影象拼接

關於OpenCV的Mat影象拼接

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