Mat 这个opencv2.0改版后,提出的结构由于会自己维护内存,基本不需要手动去将分配的空间释放,因此及其易用。
不过有的函数,在以前的版本中存在,而在新版中没有后续维护,那么就需要将Mat转换成IplImage去运算,然后转换回来。
一般的转换是:
Mat gray_src;
……
IplImage pImg= IplImage(gray_src);
IplImage * pImg_gray = &pImg;
发现源代码中最简单的代码是在需要的地方直接使用:
&IplImage(gray_src)
不过如果是跨平台,则有点编译器不接受这样的解析方式,那就要用上面的两行代码了。
做完运算后,可以用:
Mat gray_result(pImg_gray);
来获得对应的Mat类型。不过他们都是共用同一块内存的,所以你之后对pImg_gray做操作,gray_result也会发生改变。那么可以用拷贝构造的方法:
Mat gray_result(pImg_gray,1);
如果从另外一个Mat类型进行拷贝构造,则如下:
Mat img_fl_befor = img_fl.clone();
经常要对Mat进行初始化,
如果想建立一个和res图像一样大小,depth为1的图像,可以用
Mat img_detail = Mat::zeros(res.rows, res.cols, CV_8UC1);
将图像初始化为0;
如果想要一个初始化背景为白色,也就是每个通道都是255的图像,则
Mat mask_fl( img.rows, img.cols, CV_8UC1, Scalar::all(255) );
再如果,我们不想要白色,也不想要黑色的背景,而是想要某张图上某个像素点的颜色作为背景,这里直接用了以前的cvGet2D函数,获取img_src上坐标
为(1,1)点的像素值:
Mat img_result = Mat(dsize.height,dsize.width,img_src.type(),cvGet2D(&IplImage(img_src),1,1));
如果想要从图像中拷贝一部分到另外一部分:
拷贝矩形 很简单 ,从背景上选取一块和目标一样大小的矩形,然后将原图拷过去。 这里的img_src 我已经处理过,就是我选出来的目标。
其实 我这里实现的不仅仅是拷贝矩形目标,非矩形目标也可以成功提取到另外的简单背景中,而且不需要提取轮廓哦。嘿嘿 看明白没有呢。
Rect roi(x, y, img_src.cols, img_src.rows);//cols 对应w rows 对应h
Mat roi_of_image = img_result(roi);
img_src.copyTo(roi_of_image);
PS:
CvMat, Mat, IplImage之间的互相转换
IpIImage -> CvMat
CvMat matheader;
CvMat * mat = cvGetMat(img, &matheader);
CvMat * mat = cvCreateMat(img->height, img->width, CV_64FC3);
cvConvert(img, mat)
IplImage -> Mat
Mat::Mat(const IplImage* img, bool copyData=false);
例子:
IplImage* iplImg = cvLoadImage("greatwave.jpg", 1);
Mat mtx(iplImg);
Mat -> IplImage
Mat M
IplImage iplimage = M;
CvMat -> Mat
Mat::Mat(const CvMat* m, bool copyData=false);
Mat -> CvMat
例子(假设Mat类型的imgMat图像数据存在):
CvMat cvMat = imgMat;/*Mat -> CvMat, 类似转换到IplImage,不复制数据只创建矩阵头
Mat mat(3,4,CV_32FC2);
int channel = mat.channels();
mat.at<float>(1,1 * channel + 1) = 3; // 第1行第1列第1通道的元素,通道从0开始计数
mat.at<float>(i,j * channel + k);