opencv image 指针 像素

opencv image 指针 像素

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"<

output:

t0=255
t1=0
t2=0
t3=255
t4=0
t5=0
t6=255
t7=0
t8=0
t9=255
t10=0
t11=0

t=((float*)(img_32FC3.data + img_32FC3.step.p[0] * i))[ch*j+k];

这里有个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表示float4个字节,不过这里没用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;

你可能感兴趣的:(openCV,c++)