程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> LINUX 下Open cv練習使用小記(2),cv小記

LINUX 下Open cv練習使用小記(2),cv小記

編輯:C++入門知識

LINUX 下Open cv練習使用小記(2),cv小記


第二節記錄一下自己學習圖像遍歷的一點點代碼,摘自《opencv2編程手冊》(張靜譯)

第一個代碼是最簡單的強行修改像素(添加椒鹽噪聲)

 1 #include <opencv2/core/core.hpp>
 2 #include <opencv2/highgui/highgui.hpp>
 3 
 4 void salt(cv::Mat &image, int n) {
 5 
 6     int i,j;
 7     for (int k=0; k<n; k++) {
 8 
 9         // rand() is the MFC random number generator
10         i= rand()%image.cols;
11         j= rand()%image.rows;
12 
13 
14         if (image.channels() == 1) { // gray-level image
15 
16             image.at<uchar>(j,i)= 255; 
17 
18         } else if (image.channels() == 3) { // color image
19 
20             image.at<cv::Vec3b>(j,i)[0]= 255; 
21             image.at<cv::Vec3b>(j,i)[1]= 255; 
22             image.at<cv::Vec3b>(j,i)[2]= 255; 
23         }
24     }
25 }
26 
27 int main()
28 {
29     srand(cv::getTickCount()); // init random number generator
30 
31     cv::Mat image= cv::imread("../cat.jpg",0);
32 
33     salt(image,3000);
34 
35     cv::namedWindow("Image");
36     cv::imshow("Image",image);
37 
38     cv::imwrite("salted.bmp",image);
39 
40     cv::waitKey(5000);
41 
42     return 0;
43 }

書上的注釋為image.<unchar>(j,i)=255,將i行j列的數據變為白色。

第二個程序才開始真正的遍歷

 

 1 #include <opencv2/core/core.hpp>
 2 #include <opencv2/highgui/highgui.hpp>
 3 
 4 void colorReduce0(cv::Mat &image, int div=64) {
 5 
 6       int nl= image.rows; // 每行的像素數目
 7       int nc= image.cols * image.channels(); // total number of elements per line
 8               
 9       for (int j=0; j<nl; j++) {
10 
11           uchar* data= image.ptr<uchar>(j);//此句返回j行的首地址
12 
13           for (int i=0; i<nc; i++) {
14  
15             // process each pixel ---------------------
16                  
17                   data[i]= data[i]/div*div + div/2;
18  
19             // end of pixel processing ----------------
20  
21             } // end of line                   
22       }
23 }
24 
25 int main()
26 {
27     //srand(cv::getTickCount()); // init random number generator
28 
29     cv::Mat image= cv::imread("../cat.jpg");
30 
31     colorReduce0(image);
32 
33     cv::namedWindow("Image");
34     cv::imshow("Image",image);
35 
36     cv::imwrite("cat.jpg",image);
37 
38     cv::waitKey(5000);
39 
40     return 0;
41 }

這個程序寫的是對小貓的顏色進行縮減,效果如下

另,對像素的操作可以采用

*data++ =*data/div*div + div/2

來書寫

 接下來,我就繼續看第二種顏色縮進的算法

 1 void colorReduce1(cv::Mat &image, int div=64) {
 2 
 3       int nl= image.rows; // number of lines
 4       int nc= image.cols * image.channels(); // total number of elements per line
 5               
 6       for (int j=0; j<nl; j++) {
 7 
 8           uchar* data= image.ptr<uchar>(j);
 9 
10           for (int i=0; i<nc; i++) {
11  
12             // process each pixel ---------------------
13                  
14                  *data++= *data/div*div + div/2;
15  
16             // end of pixel processing ----------------
17  
18             } // end of line                   
19       }
20 }

效果如下

到這裡我就整個人變傻了。兩個算法不是一樣的嗎-  -,為什麼效果差別這麼大-  -

算了,還是將人家給的代碼放出吧,希望有大神指正

#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

// using .ptr and []
void colorReduce0(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols * image.channels(); // total number of elements per line
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
                  data[i]= data[i]/div*div + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

// using .ptr and * ++ 
void colorReduce1(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols * image.channels(); // total number of elements per line
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
                 *data++= *data/div*div + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

// using .ptr and * ++ and modulo
void colorReduce2(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols * image.channels(); // total number of elements per line
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
       
                  int v= *data;
                  *data++= v - v%div + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

// using .ptr and * ++ and bitwise
void colorReduce3(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols * image.channels(); // total number of elements per line
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *data++= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}


// direct pointer arithmetic
void colorReduce4(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols * image.channels(); // total number of elements per line
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      int step= image.step; // effective width
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      // get the pointer to the image buffer
      uchar *data= image.data;

      for (int j=0; j<nl; j++) {

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *(data+i)= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   

            data+= step;  // next line
      }
}

// using .ptr and * ++ and bitwise with image.cols * image.channels()
void colorReduce5(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<image.cols * image.channels(); i++) {
 
            // process each pixel ---------------------
                 
            *data++= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

// using .ptr and * ++ and bitwise (continuous)
void colorReduce6(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols * image.channels(); // total number of elements per line

      if (image.isContinuous())  {
          // then no padded pixels
          nc= nc*nl; 
          nl= 1;  // it is now a 1D array
       }

      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *data++= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

// using .ptr and * ++ and bitwise (continuous+channels)
void colorReduce7(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols ; // number of columns

      if (image.isContinuous())  {
          // then no padded pixels
          nc= nc*nl; 
          nl= 1;  // it is now a 1D array
       }

      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
            *data++= *data&mask + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}


// using Mat_ iterator 
void colorReduce8(cv::Mat &image, int div=64) {

      // get iterators
      cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
      cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();

      for ( ; it!= itend; ++it) {
        
        // process each pixel ---------------------

        (*it)[0]= (*it)[0]/div*div + div/2;
        (*it)[1]= (*it)[1]/div*div + div/2;
        (*it)[2]= (*it)[2]/div*div + div/2;

        // end of pixel processing ----------------
      }
}

// using Mat_ iterator and bitwise
void colorReduce9(cv::Mat &image, int div=64) {

      // div must be a power of 2
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0

      // get iterators
      cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
      cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();

      // scan all pixels
      for ( ; it!= itend; ++it) {
        
        // process each pixel ---------------------

        (*it)[0]= (*it)[0]&mask + div/2;
        (*it)[1]= (*it)[1]&mask + div/2;
        (*it)[2]= (*it)[2]&mask + div/2;

        // end of pixel processing ----------------
      }
}

// using MatIterator_ 
void colorReduce10(cv::Mat &image, int div=64) {

      // get iterators
      cv::Mat_<cv::Vec3b> cimage= image;
      cv::Mat_<cv::Vec3b>::iterator it=cimage.begin();
      cv::Mat_<cv::Vec3b>::iterator itend=cimage.end();

      for ( ; it!= itend; it++) { 
        
        // process each pixel ---------------------

        (*it)[0]= (*it)[0]/div*div + div/2;
        (*it)[1]= (*it)[1]/div*div + div/2;
        (*it)[2]= (*it)[2]/div*div + div/2;

        // end of pixel processing ----------------
      }
}


void colorReduce11(cv::Mat &image, int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols; // number of columns
              
      for (int j=0; j<nl; j++) {
          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
                  image.at<cv::Vec3b>(j,i)[0]=     image.at<cv::Vec3b>(j,i)[0]/div*div + div/2;
                  image.at<cv::Vec3b>(j,i)[1]=     image.at<cv::Vec3b>(j,i)[1]/div*div + div/2;
                  image.at<cv::Vec3b>(j,i)[2]=     image.at<cv::Vec3b>(j,i)[2]/div*div + div/2;
 
            // end of pixel processing ----------------
 
            } // end of line                   
      }
}

// with input/ouput images
void colorReduce12(const cv::Mat &image, // input image 
                 cv::Mat &result,      // output image
                 int div=64) {

      int nl= image.rows; // number of lines
      int nc= image.cols ; // number of columns

      // allocate output image if necessary
      result.create(image.rows,image.cols,image.type());

      // created images have no padded pixels
      nc= nc*nl; 
      nl= 1;  // it is now a 1D array

      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
              
      for (int j=0; j<nl; j++) {

          uchar* data= result.ptr<uchar>(j);
          const uchar* idata= image.ptr<uchar>(j);

          for (int i=0; i<nc; i++) {
 
            // process each pixel ---------------------
                 
            *data++= (*idata++)&mask + div/2;
            *data++= (*idata++)&mask + div/2;
            *data++= (*idata++)&mask + div/2;
 
            // end of pixel processing ----------------
 
          } // end of line                   
      }
}

// using overloaded operators
void colorReduce13(cv::Mat &image, int div=64) {
    
      int n= static_cast<int>(log(static_cast<double>(div))/log(2.0));
      // mask used to round the pixel value
      uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0

      // perform color reduction
      image=(image&cv::Scalar(mask,mask,mask))+cv::Scalar(div/2,div/2,div/2);
}


#define NTESTS 14
#define NITERATIONS 20

int main()
{
    int64 t[NTESTS],tinit;
    cv::Mat image1;
    cv::Mat image2;

    // timer values set to 0
    for (int i=0; i<NTESTS; i++)
        t[i]= 0;

    // repeat the tests several times
    int n=NITERATIONS;
    for (int k=0; k<n; k++) {

        std::cout << k << " of " << n << std::endl; 

        image1= cv::imread("../cat.jpg");
        if (!image1.data)
           return 0; 

        // using .ptr and []
        tinit= cv::getTickCount();
        colorReduce0(image1);
        t[0]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using .ptr and * ++ 
        tinit= cv::getTickCount();
        colorReduce1(image1);
        t[1]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using .ptr and * ++ and modulo
        tinit= cv::getTickCount();
        colorReduce2(image1);
        t[2]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using .ptr and * ++ and bitwise
        tinit= cv::getTickCount();
        colorReduce3(image1);
        t[3]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using direct pointer arithmetic
        tinit= cv::getTickCount();
        colorReduce4(image1);
        t[4]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using .ptr and * ++ and bitwise with image.cols * image.channels()
        tinit= cv::getTickCount();
        colorReduce5(image1);
        t[5]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using .ptr and * ++ and bitwise (continuous)
        tinit= cv::getTickCount();
        colorReduce6(image1);
        t[6]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using .ptr and * ++ and bitwise (continuous+channels)
        tinit= cv::getTickCount();
        colorReduce7(image1);
        t[7]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using Mat_ iterator
        tinit= cv::getTickCount();
        colorReduce8(image1);
        t[8]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using Mat_ iterator and bitwise
        tinit= cv::getTickCount();
        colorReduce9(image1);
        t[9]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using Mat_ iterator 
        tinit= cv::getTickCount();
        colorReduce10(image1);
        t[10]+= cv::getTickCount()-tinit;

        image1= cv::imread("../cat.jpg");
        // using at 
        tinit= cv::getTickCount();
        colorReduce11(image1);
        t[11]+= cv::getTickCount()-tinit;
        
        image1= cv::imread("../cat.jpg");
        // using input/output images 
        tinit= cv::getTickCount();
        cv::Mat result;
        colorReduce12(image1, result);
        t[12]+= cv::getTickCount()-tinit;

        image2= result;
        
        image1= cv::imread("../cat.jpg");
        // using input/output images 
        tinit= cv::getTickCount();
        colorReduce13(image1);
        t[13]+= cv::getTickCount()-tinit;

        //------------------------------
    }
        
    cv::namedWindow("Result");
    cv::imshow("Result",image2);
    cv::namedWindow("Image Result");
    cv::imshow("Image Result",image1);

    // print average execution time
    std::cout << std::endl << "-------------------------------------------" << std::endl << std::endl;
    std::cout << "using .ptr and [] =" << 1000.*t[0]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using .ptr and * ++ =" << 1000.*t[1]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using .ptr and * ++ and modulo =" << 1000.*t[2]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using .ptr and * ++ and bitwise =" << 1000.*t[3]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using direct pointer arithmetic =" << 1000.*t[4]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using .ptr and * ++ and bitwise with image.cols * image.channels() =" << 1000.*t[5]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using .ptr and * ++ and bitwise (continuous) =" << 1000.*t[6]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using .ptr and * ++ and bitwise (continuous+channels) =" << 1000.*t[7]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using Mat_ iterator =" << 1000.*t[8]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using Mat_ iterator and bitwise =" << 1000.*t[9]/cv::getTickFrequency()/n << "ms" << std::endl;
    std::cout << "using MatIterator_ =" << 1000.*t[10]/cv::getTickFrequency()/n << "ms" << std::endl;    
    std::cout << "using at =" << 1000.*t[11]/cv::getTickFrequency()/n << "ms" << std::endl;    
    std::cout << "using input/output images =" << 1000.*t[12]/cv::getTickFrequency()/n << "ms" << std::endl;    
    std::cout << "using overloaded operators =" << 1000.*t[13]/cv::getTickFrequency()/n << "ms" << std::endl;    
    
    cv::waitKey();
    return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved