【OpenCV】三种方式操作图像像素
OpenCV中,有3种访问每个像素的方法:使用at方法、使用迭代器方法、使用指针
运行如下程序后可以发现使用at方法速度最快。
代码如下:
//操作图像像素 #include <opencv2/opencv.hpp> #include <iostream> #include <cstdio> using namespace std; using namespace cv; void colorReduce(Mat &a, Mat &b, int div) {//at方法 b = a.clone(); int row = b.rows, col = b.cols; for(int i = 0; i < row; ++i) { for(int j = 0; j < col; ++j) { b.at<Vec3b>(i, j)[0] = b.at<Vec3b>(i, j)[0] / div * div + div/2; b.at<Vec3b>(i, j)[1] = b.at<Vec3b>(i, j)[1] / div * div + div/2; b.at<Vec3b>(i, j)[2] = b.at<Vec3b>(i, j)[2] / div * div + div/2; } } } void colorReduce1(Mat &a, Mat &b, int div) {//指针 b = a.clone(); int row = b.rows, col = b.cols * b.channels(); uchar *c = b.data; for(int i = 0; i < row; ++i) { for(int j = 0; j < col; ++j) { *c = *c / div * div + div / 2; c++; } } } void colorReduce2(Mat &a, Mat &b, int div) {//迭代器 b = a.clone(); Mat_<Vec3b>::iterator it = a.begin<Vec3b>(); Mat_<Vec3b>::iterator itend = a.end<Vec3b>(); Mat_<Vec3b>cimg = b; Mat_<Vec3b>::iterator itout = cimg.begin(); Mat_<Vec3b>::iterator itoutend = cimg.end(); for(; it != itend; it ++,itout++) { (*itout)[0] = (*it)[0]/div * div + div / 2; (*itout)[1] = (*it)[1]/div * div + div / 2; (*itout)[2] = (*it)[2]/div * div + div / 2; } } int main() { Mat img, res, temp; img = imread("PIC1.jpg"); if(!img.data) {cout<<"read image file wrong!"<<endl; getchar(); return 0;} //cout << "height = " << img.size().height << ",width = " << img.size().width << endl; getchar(); imshow("PIC", img); double t1=(double)getTickCount(); //colorReduce(img, res, 128);//at colorReduce1(img, res, 128);//指针 //colorReduce2(img, res, 128);//迭代器 double t2=(double)getTickCount(); double time = (t2-t1)/getTickFrequency()*1000; cout<<"Time = " << time << "ms" <<endl; namedWindow("Picture"); imshow("Picture", res); waitKey(0); return 0; }