【從零學習openCV】opecv操作畫素
阿新 • • 發佈:2019-02-16
//at方法 void colorReduce1(Mat&image, int div = 64) { int nl = image.rows; //影象的行數 //影象每行的畫素數 int nc = image.cols * image.channels(); for(int j =0;j<nl-2;j++) { for(int i =0;i<nc-2;i++) { image.at<Vec3b>(j,i)[0] = image.at<Vec3b>(j,i)[0]/div*div; image.at<Vec3b>(j,i)[1] = image.at<Vec3b>(j,i)[1]/div*div; image.at<Vec3b>(j,i)[2] = image.at<Vec3b>(j,i)[2]/div*div; } } } //行首指標方法 void colorReduce2(Mat&image, int div = 64) { int nl = image.rows; //影象的行數 //影象每行的畫素數 int nc = image.cols * image.channels(); for(int j =0;j<nl;j++) { //得到第j行的首地址 uchar* data = image.ptr<uchar>(j); //遍歷每行的畫素 for(int i =0;i<nc;i++) { data[i] = data[i]/div*div; //將每個畫素值都變為div的倍數,即將顏色數縮減了div倍 } } } //一維陣列 void colorReduce3(Mat&image, int div = 64) { int nl = image.rows; //影象的行數 //影象每行的畫素數 int nc = image.cols * image.channels(); //如果影象連續 if(image.isContinuous()) { //reshape函式用於改變矩陣維度 //影象行數為1,列數為原先的行數乘上列數 image.reshape(1,image.cols*image.rows); } for(int j =0;j<nl;j++) { //得到第j行的首地址 uchar* data = image.ptr<uchar>(j); //遍歷每行的畫素 for(int i =0;i<nc;i++) { data[i] = data[i]/div*div; //將每個畫素值都變為div的倍數,即將顏色數縮減了div倍 } } } //迭代器方法 void colorReduce4(Mat&image, int div = 64) { //得到初始位置的迭代器 Mat_<Vec3b>::iterator it = image.begin<Vec3b>(); //得到終止位置的迭代器 Mat_<Vec3b>::iterator itend = image.end<Vec3b>(); //遍歷所有畫素 for(; it != itend; ++it){ (*it)[0] = (*it)[0]/div*div; (*it)[1] = (*it)[1]/div*div; (*it)[2] = (*it)[2]/div*div; } } //測試4種畫素遍歷方式執行時間 void calrunTime(int v,Mat&image) { double duration; duration = static_cast<double>(getTickCount()); for(int i = 0;i<10;i++) //執行十次取平均值 { switch(v) { case 1: colorReduce1(image); break; case 2: colorReduce2(image); break; case 3: colorReduce3(image); break; case 4: colorReduce4(image); break; default: break; } } duration = static_cast<double>(getTickCount()) - duration; duration /= getTickFrequency()/100; //執行時間,以ms為單位 qDebug()<<"duration"<<v<<":"<<duration<<"ms"; }