天天看點

OpenCV 圖像周遊方法

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;
//列印時間花銷

void timePrint(const char* mes)
{
 static long long begTime = 0;
 long long currTime = getTickCount();
 if (0 == begTime)
 {
  begTime = currTime;
  return;
 }
 long long interval = ((double)(currTime - begTime) / getTickFrequency()) * 1000;//機關ms
 if (0 != *mes)
 {
  printf("%s = %d ms\n", mes, interval);
 }
 begTime = getTickCount();
}

int main()
{
 Mat img(3000, 4000, CV_8UC3);
 //img.create(3000, 4000, CV_8UC3);
 int es = img.elemSize();
 
 timePrint("");
 //連續記憶體周遊
 for (int i = 0; i < img.rows*img.cols; i += es)
 {
  img.data[i] = 0; //B
  img.data[i + 1] = 0;//G
  img.data[i + 2] = 255;//R
 }
 timePrint("Continuation");
 
 不連續記憶體周遊
 for (int row = 0; row < img.rows; row++)
 {
  for (int col = 0; col < img.cols; col++)
  {
   (&img.data[row*img.step])[col*es] = 0;
   (&img.data[row*img.step])[col*es+1] = 0;
   (&img.data[row*img.step])[col*es + 2] = 255;
  }
 }
 timePrint("Discrete");
 
 //指針周遊,不會抛出異常,出錯程式直接崩潰
 for (int row = 0; row < img.rows; row++)
 {
  for (int col = 0; col < img.cols; col++)
  {
   Vec3b *ptr = img.ptr<Vec3b>(row, col);
   ptr->val[0] = 0;
   ptr->val[1] = 255;
   ptr->val[2] = 0;
  }
 }
 timePrint("Ptr");
 
 //at周遊,可以抛出異常
 try
 {
  for (int row = 0; row < img.rows; row++)
  {
   for (int col = 0; col < img.cols; col++)
   {
    Vec3b &pix = img.at<Vec3b>(row, col);
    pix[0] = 0;
    pix[1] = 255;
    pix[2] = 0;
   }
  }
 }
 catch(Exception &e)
 {
  cout << e.what() << endl;
 }
 timePrint("At");
 
 //疊代器周遊
 auto beg = img.begin<Vec3b>();
 auto end = img.end<Vec3b>();
 for (; beg != end; beg++)
 {
  (*beg).val[0] = 100;
  (*beg).val[1] = 100;
  (*beg).val[2] = 100;
 }
 timePrint("iterator");
 
 namedWindow("win");
 imshow("win", img);
 waitKey(0);
 return 0;
}