opencv获取mat的指针_opencv中Mat类型数据操作与遍历Mat作为opencv中⼀种数据类型常常⽤来存储图像,相对与以前的IplImgae类型来说,Mat类型省去了⼈⼯的对内存的分配与释放,转⽽⾃动分配释放。Mat Class主要包括两部个数据部分:⼀个是matrix header(包括matrix的⼤⼩尺⼨,储存⽅法,储存地址等等..),另⼀个是指向存储像素值的矩阵的指针。
Opencv中对Mat的复制分为两种,
Mat A, C; //creates just the header parts
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); //here we'll know the method used (allocate matrix)
Mat B(A);//Use the copy constructor
C= A; //Assignment operator
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries
上⾯⼀类仅仅新建了matrix header,对与像素矩阵A,B,C共有,修改其中⼀项的像素值,其他的也都会改变,可以理解为他们提供了对相同底层数据的不同读取⽅法。 这么做的好处是为了减少计算成本。
如果仅仅想操作其中的⼀部分像素,可以创建⼀个读取部分的header matrix
当然Opencv也提供深度复制的⽅法
Mat F =A.clone();
Mat G;
Mat的创建
cv::Mat::Mat Constructor:
Mat M(2,2, CV_8UC3, Scalar(0,0,255));
cout << "M = " << endl << " " << M << endl << endl;
cout << "M = "<< endl << " " << M << endl << endl;
Mat E = Mat::eye(4, 4, CV_64F);
cout << "E = " << endl << " " << E << endl << endl;
Mat O = Mat::ones(2, 2, CV_32F);
cout << "O = " << endl << " " << O << endl << endl;
Mat Z = Mat::zeros(3,3, CV_8UC1);
cout << "Z = " << endl << " " << Z << endl << endl;
对于⼀些⼩的kernel可以⾃定义如下:
Mat C = (Mat_(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
cout << "C = " << endl << " " << C << endl << endl;
在对图像进⾏分析及操作时往往需要进⾏遍历或对某⼀区域的像素值进⾏操作。总结了⼀下⽐较常⽤的有以下⼏种⽅法。
1.利⽤ptr指针访问Mat像素
for(int j = 1; j < ws - 1; ++j)
{
const uchar* previous = myImage.ptr(j - 1);
const uchar* current = myImage.ptr(j );
const uchar* next = myImage.ptr(j + 1);
uchar* output = Result.ptr(j);
for(int i = nChannels; i < nChannels * (ls - 1); ++i)
{
*output++ = saturate_cast(5 * current[i]
-current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
}
}
2.使⽤ Mat::at 函数
int main()
{
Mat img = imread("lena.jpg");
imshow("Lena Original", img);
if(img.channel() > 1)
{
for (int row = 0; row < ws; row++)
{
for (int col = 0; col < ls; col++)
rectangle函数opencv
{
/* 注意 Mat::at 函数是个模板函数, 需要指明参数类型, 因为这张图是具有红蓝绿三通道的图,
所以它的参数类型可以传递⼀个 Vec3b, 这是⼀个存放 3 个 uchar 数据的 Vec(向量). 这⾥
提供了索引重载, [2]表⽰的是返回第三个通道, 在这⾥是 Red 通道, 第⼀个通道(Blue)⽤[0]返回 */
if(img.at(row, col)[2] > 128)
img.at(row, col) = Vec3b(255, 255, 255);
}
}
}
else
{
for (int row = 0; row < ws; row++) {
for (int col = 0; col < ls; col++)
{
if(img.at(row, col) > 128)
img.at(row, col) = 255;
}
}
}
imshow("Lena Modified", img); cvWaitKey();
return 0;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论