1. 程式人生 > >OpenCV Mat轉IplImage的陷阱

OpenCV Mat轉IplImage的陷阱

自OpenCV2.0.0以後,引進了Mat型別。Mat使用更為方便,且和Android的Bitmap轉換也方便。(此處指的是Android在java層轉int[]後再傳給jni裡,在jni裡將int[]轉為Mat.) 但有時候新舊工程為了對接,不得已要將Mat轉為IplImage。關於Mat轉為IplImage,常見的方法有以下幾種:

第一種方式:

	//第一種轉換方式
	IplImage *imgIpl1 = cvCreateImage(cvSize(w, h), 8, 3);
	Mat temp = preMat.clone();
	imgIpl1->imageData = (char *)temp.data;

第二種方式:
	//第二種轉換方式
	IplImage imgIpl2 = preMat.operator _IplImage();

第三種方式:
	//第三種轉換方式
	IplImage imgIpl3 = (IplImage)(preMat);

完整測試程式如下:
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main() {
	string s = "Hello world!";
	s.c_str();
	s.data();
	cout << s << endl;

	Mat preMat = imread("F:\\1.jpg");
	int w = preMat.cols;
	int h = preMat.rows;
	cout<<"原始尺寸 w = "<<w<<"h = "<<h<<endl;

	//第一種轉換方式
	IplImage *imgIpl1 = cvCreateImage(cvSize(w, h), 8, 3);
	Mat temp = preMat.clone();
	imgIpl1->imageData = (char *)temp.data;

	//第二種轉換方式
	IplImage imgIpl2 = preMat.operator _IplImage();

	//第三種轉換方式
	IplImage imgIpl3 = (IplImage)(preMat);


	cvNamedWindow("imgIpl1");
	cvShowImage("imgIpl1", imgIpl1);

	namedWindow("imgIpl2", 1);
	cvShowImage("imgIpl2", &imgIpl2);

	namedWindow("imgIpl3", 1);
	cvShowImage("imgIpl3", &imgIpl3);

	waitKey(0);
	return 0;
}
測試結果:


可以看到,第一種方法轉出來的結果圖片錯誤了,左右倒置了。這是我在移植OpenCV到JNI層中無意發現的,貼出來供大家參考。個人推薦第二種方法進行轉換。