方法一:用指针访问像素
Mat img=imread("E:\\Users\\lihao\\CLionProjects\\work1test\\b.bmp");
if(img.empty()){
cout<<"The picture is null!"<<endl;
}
int rowNumber=img.rows;
int colNumber=img.cols*img.channels();
for(int i=0;i<rowNumber;i++){
uchar* data=img.ptr<uchar >(i); //第i行的首地址
for (int j = 0; j < colNumber; ++j) {
int value=data[j];
}
}
方法二:用迭代器
Mat img=imread("E:\\Users\\lihao\\CLionProjects\\work1test\\b.bmp");
if(img.empty()){
cout<<"The picture is null!"<<endl;
}
Mat_<Vec3b>::iterator start=img.begin<Vec3b>(); //初始位置
Mat_<Vec3b>::iterator end=img.end<Vec3b>(); //结束位置
for (; start!=end; ++start) {
int b=(*start)[0];
int g=(*start)[1];
int r=(*start)[2];
}
方法三:动态地址计算
Mat img=imread("E:\\Users\\lihao\\CLionProjects\\work1test\\b.bmp");
if(img.empty()){
cout<<"The picture is null!"<<endl;
}
int rowNumber=img.rows;
int colNumber=img.cols;
for (int i = 0; i < rowNumber; ++i) {
for (int j = 0; j < colNumber; ++j) {
int b=img.at<Vec3b>(i,j)[0];
int g=img.at<Vec3b>(i,j)[1];
int r=img.at<Vec3b>(i,j)[2];
}
}
在debug模式下,图像大小为4096*256的尺寸下,三种方法的执行时间见下表:
次数/方法 | 1 | 2 | 3 | 4 | 5 |
指针 | 5ms | 5ms | 5ms | 4ms | 5ms |
迭代器 | 58ms | 59ms | 58ms | 59ms | 58ms |
动态地址 | 93ms | 96ms | 99ms | 98ms | 95ms |
可见,指针的执行时间最短,但相比它,迭代器使用起来会更安全一点,避免了使用不当引起的指针越界问题,而动态地址简单明了,符合我们对像素的直观认识。
在release模式下,三者的执行时间相差无几。