图像数据的方式总结"/>
opencv读取图像数据的方式总结
引言
opencv是计算机视觉中使用最广泛同时也是功能最全的一个开源库,为图像处理以及计算机视觉工作者提供了极大的方便,本文就opencv读取图像数据文件做一个总结,高年级同学以及大牛请无视。
opencv中图像的结构
图像的结构可以看作是一个2维矩阵,opencv在对图像的结构定义中也采用了这一方式。在总结之前,有必要对opencv中图像结构定义的一些成员变量意义进行说明,更详细的请参考opencv官方文档。
nChannels:图像通道数,可取1、2、3、4;
widthStep:可理解成相邻行,同列数据之间的字节数,为了高速的处理效率,图像在存储时会进行填充,保证每行是一个固定字节数,且通常维4的倍数;
width:图像宽;
height:图像高;
数据读取
1.点读取
// 单通道
uchar value = grayim.at<uchar>(i,j);
for( int i = 0; i < grayim.rows; ++i)for( int j = 0; j < grayim.cols; ++j )grayim.at<uchar>(i,j) = (i+j)%255;//3通道 Vec3b可看作一个结构体,包含三个元素,分别对应彩色图像的B\G\R,且只能对8U的数据类型使用,如果是float数据的值,可以用Vec3ffor( int i = 0; i < colorim.rows; ++i)for( int j = 0; j < colorim.cols; ++j ){Vec3b pixel;pixel[0] = i%255; //Bluepixel[1] = j%255; //Greenpixel[2] = 0; //Redcolorim.at<Vec3b>(i,j) = pixel;
}
2.图像迭代器
// 单通道
cv::MatIterator_<uchar> grayit, grayend;
for( grayit = grayim.begin<uchar>(), grayend =
grayim.end<uchar>(); grayit != grayend; ++grayit)*grayit = rand()%255;//3通道
cv::MatIterator_<Vec3b> colorit, colorend;
for( colorit = colorim.begin<Vec3b>(), colorend = colorim.end<Vec3b>(); colorit!=colorend; colorit++)
{(*colorit)[0]=rand()%255; //B(*colorit)[1]=rand()%255; //G(*colorit)[2]=rand()%255; //R
}
3.指针读取
for( int i = 0; i < grayim.rows; ++i)
{//获取第 i 行首像素指针uchar * p = grayim.ptr<uchar>(i);//对第 i 行的每个像素(byte)操作for( int j = 0; j < grayim.cols; ++j )p[j] = (i+j)%255;
}
4.按结构读取
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的维度)
扩展到3维
单通道:
3通道:
5.Mat_读取
考虑下面一段代码:
// 由于数据类型转换,最后的像素值会发生改变
Mat M(600, 800, CV_8UC1);
for( int i = 0; i < M.rows; ++i)
{uchar * p = M.ptr<uchar>(i);for( int j = 0; j < M.cols; ++j ){double d1 = (double) ((i+j)%255);M.at<uchar>(i,j) = d1;double d2 = M.at<double>(i,j);}
}
如果采用Mat_模板类则可以避免这种情况:
Mat_<uchar> M1 = (Mat_<uchar>&)M; // 内存地址共享
for( int i = 0; i < M1.rows; ++i)
{uchar * p = M1.ptr(i);for( int j = 0; j < M1.cols; ++j ){double d1 = (double) ((i+j)%255);M1(i,j) = d1;double d2 = M1(i,j);}
}
更多推荐
opencv读取图像数据的方式总结
发布评论