扫描图像的像素
在 opencv 中获取图像的像素有三种方式:
先加载图像:
Mat image=imread(image_path);
一、最高效的方式
这种方式只需要一个指针便可访问图像的所有像素,用法如下:
1 int i=0,j=0; 2 //单通道; 3 uchar *p; 4 for( i = 0; i < image.rows; ++i) 5 {
//获取该行的首指针; 6 p = image.ptr<uchar>(i); 7 for ( j = 0; j < image.cols; ++j) 8 { 9 p[j]=..........//访问图像像素; 10 } 11 } 12 //3通道; 13 Vec3b *p; 14 for( i = 0; i < image.rows; ++i) 15 { 16 p = image.ptr<Vec3b>(i); 17 for ( j = 0; j < image.cols; ++j) 18 { 19 p[j][0]=..........//访问图像像素 G分量; 20 p[j][1]=..........//访问图像像素 B分量; 21 p[j][2]=..........//访问图像像素 R分量; 22 } 23 }
这是扫描像素速度最快的方法。
这个方法还有另一个版本,Mat 对象有一个成员变量 data ,data 是一个指针,它指向图像数据第一行第一列,我们可以用它来访问所有的图像数据。
如果 data 的值为 null ,则表明图像加载失败,因此,可以用该变量来检测图像是否加载成功。
uchar* p = image.data; for( unsigned int i =0; i < image.cols*image.rows; ++i) *p++ =........;
二、最安全的方法
上一种方法需要自己控制索引的范围,这种方法则不需要。
const int channels = image.channels(); switch(channels) { case 1: { MatIterator_<uchar> it, end; for( it = image.begin<uchar>(), end = image.end<uchar>(); it !=end; ++it) *it =....; break;
} case 3: { MatIterator_<Vec3b> it, end; for( it = image.begin<Vec3b>(), end = image.end<Vec3b>(); it != end; ++it) { (*it)[0] = .....; (*it)[1] = .....; (*it)[2] = .....; } } }
三、直接索引(最慢)
const int channels = image.channels(); switch(channels) { case 1: { for( int i = 0; i < image.rows; ++i) for( int j = 0; j < image.cols; ++j ) image.at<uchar>(i,j) = ......; break; } case 3: {
for( int i = 0; i < image.rows; ++i) for( int j = 0; j < image.cols; ++j ) { image.at<Vec3b>(i,j)[0] = ......; image.at<Vec3b>(i,j)[1] = ......; image.at<Vec3b>(i,j)[2] = ......; }
break; } }
浙公网安备 33010602011771号