opencv 中3通道image,image中每个点包含3个值
,这上个值分别是B G R
例如:2x2 CV_8UC3(uchar channels=3)的图像
Mat img_8UC3(2, 2, CV_8UC3, Scalar(0, 255, 255)); //初始化为(B G R)=(0, 255, 255)
数据排列方式:
(0,255,255)(0,255,255)
(0,255,255)(0,255,255)
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/utility.hpp" // #include "opencv2/core.hpp"
#include
#include//标准输入输出
//命名空间
using namespace cv;
using namespace std;
int main(int argc, char const *argv[])
{
//创建一个2*2 类型为8位的uchar类型三通道的 颜色为黄色
Mat img_8UC3(2, 2, CV_8UC3, Scalar(0, 255, 255));
imshow("img_8UC3",img_8UC3);
Mat img_32FC3(2,2,CV_32FC3,Scalar(255,0,0));
imshow("img_32FC3",img_32FC3);
for (int i = 0; i(i,j)[k];
//t=((Vec3f*)(img_32FC3.data + img_32FC3.step.p[0] * i))[j][k];
t=((float*)(img_32FC3.data + img_32FC3.step.p[0] * i))[ch*j+k];
cout<<"t"<
t0=255
t1=0
t2=0
t3=255
t4=0
t5=0
t6=255
t7=0
t8=0
t9=255
t10=0
t11=0
这里有个Mat.data
的Mat类成员,是指向图像数据的首地址,地址类型是uchar
。在上面个的例子中是img_32FC3
的首地址。
Mat.step.p[0]
代表图像每一行所占的字节数,而Mat.step.p[1]
和Mat.elemSize()
一样,表示image中每个点所占的字节数,对于img_32FC3
, img_32FC3.step.p[1]
=3*4
=12
,3
表示3
通道,4
表示float
有4
个字节,不过这里没用Mat.step.p[1]
.
img_32FC3.data + img_32FC3.step.p[0] * i)
表示第i+1
行的首地址,img_32FC3.data + img_32FC3.step.p[0] * i)
地址类型还是uchar
,而(float*)
表示强制转换,因为图像img_32FC3
是3通道的float
类型
[ch*j+k]
表示第j列第k(0,1,2)个通道的值。
也可以通过vec
的方式操作:
t=((Vec3f*)(img_32FC3.data + img_32FC3.step.p[0] * i))[j][0];
t=((Vec3f*)(img_32FC3.data + img_32FC3.step.p[0] * i))[j][1];
t=((Vec3f*)(img_32FC3.data + img_32FC3.step.p[0] * i))[j][2];
或者使用Mat.at
的方式,和vec
的方式等价
at操作要比指针的操作慢很多,所以对于不连续数据或者单个点处理,可以考虑at操作,对于连续的大量数据,不要使用它
img_32FC3.at(i,j)[0]
img_32FC3.at(i,j)[1]
img_32FC3.at(i,j)[2]
CV_8UC3
,Mat img_8UC3;
类似的:
//(i,j)表示行列
t=(img_8UC3.data + img_8UC3.step.p[0] * i)[ch*j+k]//k=0,1,2
t=((Vec3b*)(img_8UC3.data + img_8UC3.step.p[0] * i))[j][k];//k=0,1,2
t=img_8UC3.at(i,j)[k];//k=0,1,2
- If matrix is of type `CV_8U` then use `Mat.at(y,x)`.
- If matrix is of type `CV_8S` then use `Mat.at(y,x)`.
- If matrix is of type `CV_16U` then use `Mat.at(y,x)`.
- If matrix is of type `CV_16S` then use `Mat.at(y,x)`.
- If matrix is of type `CV_32S` then use `Mat.at(y,x)`.
- If matrix is of type `CV_32F` then use `Mat.at(y,x)`.
- If matrix is of type `CV_64F` then use `Mat.at(y,x)`.
typedef Mat_ Mat1b;
typedef Mat_ Mat2b;
typedef Mat_ Mat3b;
typedef Mat_ Mat4b;
typedef Mat_ Mat1s;
typedef Mat_ Mat2s;
typedef Mat_ Mat3s;
typedef Mat_ Mat4s;
typedef Mat_ Mat1w;
typedef Mat_ Mat2w;
typedef Mat_ Mat3w;
typedef Mat_ Mat4w;
typedef Mat_ Mat1i;
typedef Mat_ Mat2i;
typedef Mat_ Mat3i;
typedef Mat_ Mat4i;
typedef Mat_ Mat1f;
typedef Mat_ Mat2f;
typedef Mat_ Mat3f;
typedef Mat_ Mat4f;
typedef Mat_ Mat1d;
typedef Mat_ Mat2d;
typedef Mat_ Mat3d;
typedef Mat_ Mat4d;