部分内容转自:
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/core/mat%20-%20the%20basic%20image%20container/mat%20-%20the%20basic%20image%20container.html#matthebasicimagecontainer
http://ggicci.blog.163.com/blog/static/210364096201261052543349/
Mat本质上是由两个数据部分组成的类:
矩阵头部的大小是恒定的。然而,矩阵本身的大小因图像的不同而不同,通常是较大的数量级。因此,当你在您的程序中传递图像并在有些时候创建图像副本您需要花费很大的代价生成图像矩阵本身,而不是图像的头部。为了解决这一问题 OpenCV 使用引用计数系统。其思想是Mat的每个对象具有其自己的头,但可能他们通过让他们矩阵指针指向同一地址的两个实例之间共享该矩阵。此外,拷贝运算符将只能复制矩阵头部,也还将复制指针到大型矩阵,但不是矩阵本身。
1
2
3
4
5
6
7
8
9 |
//image1属于shallow copy,而image2是赋值了一个副本,当result发生变化时,image1同时发生变化,而image2不变 cv::Mat image1, image2, result=cv::imread( "image.jpg" ); image1 = result; result.copyTo(image2); cv::flip(result, result, 1); cv::namedWindow( "IMAGE1" ); cv::imshow( "IMAGE1" , image1); cv::namedWindow( "IMAGE2" ); cv::imshow( "IMAGE2" , image2); |
注意,这个特性要求OpenCV中的类应该返回副本copyTo(returnMat),否则当某个类的实体发生改变时,该类的其余实体都会发生改变。
灰度图的每个像素都是0~255的8 bit值。彩色图有BGR三通道,其像素可视为一个三维向量,每个分量也是一个0~255的8 bit值。代码中有时存在第四维alpha,表示透明度。
最小的数据类型可能是 char 类型,这意味着一个字节或 8 位。这可能是有符号(值-127 到 + 127)或无符号(以便可以存储从 0 到 255 之间的值)。虽然这三个组件的情况下已经给 16 万可能的颜色来表示 (如 RGB 的情况下),我们可通过使用浮点数 (4 字节 = 32 位) 或double(8 字节 = 64 位) 数据类型的每个组件获得甚至更精细的控制。
注意:当目标为ROI时,地址计算失效。
addr(Mi0,i1,…im-1)=M.data + M.step[0] * i0 + M.step[1] * i1 + … + M.step[m-1] * im-1
(其中 m = M.dims M的维度)
考虑二维情况(stored row by row)按行存储:
![]() |
当数据类型为 CV_8U单通道的 uchar 时:
当数据类型是 CV_8UC3三通道:
|
![]() |
当数据类型为 CV_16SC4,也就是 short 类型:
|
P.S.1
在OpenCV1中采用的IplImage(Intel Image
Processing Library)类型应尽量不再使用。可用以下方法将IplImage转为Mat:
1
2
3 |
IplImage* iplImage = cvLoadImage( "c:\\img.jpg" ); cv::Mat image(iplImage, false ); //false是默认参数,表示浅拷贝,即image指向同一区域,不额外占用空间。 |
若确实需要使用IplImage时,应注意dangling pointer的问题,可选择:
P.S.2
Mat 中的channel是BGR,在Qt中显示的图像需是QImage类型(通道为RGB),可通过以下方式转换:
1
2
3
4
5
6
7
8 |
// change color channel ordering cv::cvtColor(image,image,CV_BGR2RGB); // Qt image QImage img= QImage(( const
unsigned char *)(image.data), image.cols,image.rows,QImage::Format_RGB888); // display on label ui->label->setPixmap(QPixmap::fromImage(img)); // resize the label to fit the image ui->label->resize(ui->label->pixmap()->size()); |
OpenCV学习笔记(二) cv::Mat,布布扣,bubuko.com
原文:http://www.cnblogs.com/ericxing/p/3575541.html