opencv之訪問圖像像素


訪問像素的三種方法

①指針訪問:最快

②迭代器iterator:較慢,非常安全,指針訪問可能出現越界問題

③動態地址計算:更慢,通過at()實現。適用於訪問具體某個第i行,j列的像素,而不適用遍歷像素

 

Mat在內存中存儲形式

  灰度圖的存儲形式

    

 

  RGB的存儲形式

  

一般情況下,Mat是連續存儲的,按行連接。可以通過isContinuous()函數,判斷矩陣是否連續存儲,若連續返回true。

 

訪問像素的三種方法

1.指針訪問

 1 void VisitImgByPointer(Mat &inputImg, Mat &dstImg)
 2 {
 3     dstImg = inputImg.clone();
 4     int rows = dstImg.rows;
 5     int cols = dstImg.cols * dstImg.channels();
 6 
 7     for(int i = 0; i < rows; i++)
 8     {
 9         uchar* data = dstImg.ptr<uchar>(i);
10         for(int j = 0; j < cols; j++)
11         {
12             data[j] = 0;  //處理每一個像素
13             //add code
14         }
15     } 
16 }

當Mat按行連續存儲時,可以用指針直接訪問所有數據。

 1 void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg)
 2 {
 3     dstImg = inputImg.clone();
 4     int rows = dstImg.rows;
 5     int cols = dstImg.cols;
 6     int channels = dstImg.channels();
 7 
 8     if(dstImg.isContinuous())
 9     {
10         cols *= rows;
11         rows = 1;
12         //cout << "is continuous " << endl;
13     }
14 
15     for(int i = 0; i < rows; i++)
16     {
17         uchar* data = dstImg.ptr<uchar>(i);
18         for(int j = 0; j < cols * channels; j++)
19         {
20             data[j] = 155;  //處理每一個像素
21             //add code
22         }
23     } 
24     //若存儲連續,等效於以下代碼
25     //uchar* data = dstImg.data;
26     //for(int i = 0; i < cols * rows * channels; i++)
27     //    data[i] = 155;    //處理每一個像素
28 
29 }

 

 

2.迭代器訪問

 1 void VisitImgByIterator(Mat &inputImg, Mat &dstImg)
 2 {
 3     dstImg = inputImg.clone();
 4     const int channels = dstImg.channels();
 5   
 6     switch(channels)
 7     {
 8     case 1:
 9         {
10             Mat_<uchar>::iterator it= dstImg.begin<uchar>();
11             Mat_<uchar>::iterator itend= dstImg.end<uchar>();
12             for ( ; it!= itend; it++) //處理每一個像素
13             {
14                 *it = 150;
15             }
16             break;
17         }
18     case 3:
19         {
20             Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>();
21             Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>();
22             for ( ; it3!= itend3; it3++) //處理每一個像素
23             { 
24                 (*it3)[0]= 255;
25                 (*it3)[1]= 0;
26                 (*it3)[2]= 0;
27             }
28             break;
29         }
30     }
31 }

 

3.動態地址訪問

 1 void VisitImgByAt(Mat &inputImg, Mat &dstImg)
 2 {
 3     dstImg = inputImg.clone();
 4     int rows = dstImg.rows;
 5     int cols = dstImg.cols;
 6     int channels = dstImg.channels();
 7 
 8     switch(channels)
 9     {
10     case 1:
11         {
12             for(int i = 0; i < rows; i++)
13                 for(int j = 0; j < cols; j++)
14                     dstImg.at<uchar>(i,j) = 150;
15             break;
16         }
17     case 3:
18         {
19             for(int i = 0; i < rows; i++)
20                 for(int j = 0; j < cols; j++)
21                 {
22                     dstImg.at<Vec3b>(i,j)[0] =  0;
23                     dstImg.at<Vec3b>(i,j)[1] =  0;
24                     dstImg.at<Vec3b>(i,j)[2] = 255;
25                 }
26             break;
27         }
28     }
29 }

 

測試代碼-總

  1 #include <iostream>
  2 #include <opencv2/opencv.hpp>  
  3 using namespace cv;
  4 using namespace std;
  5 
  6 void VisitImgByPointer(Mat &inputImg, Mat &dstImg);
  7 void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg);
  8 void VisitImgByIterator(Mat &inputImg, Mat &dstImg);
  9 void VisitImgByAt(Mat &inputImg, Mat &dstImg);
 10 
 11 int main()
 12 {
 13     Mat srcImg = imread("pig.png"), dstImg;
 14     Mat grayImg;
 15     cvtColor(srcImg, grayImg, CV_BGR2GRAY);
 16     //VisitImgByPointer(srcImg,dstImg);
 17     //VisitContinueImgByPointer(grayImg,dstImg);
 18     
 19     //VisitImgByIterator(srcImg,dstImg);
 20     //VisitImgByIterator(grayImg,dstImg);
 21     
 22     //VisitImgByAt(srcImg,dstImg);
 23     VisitImgByAt(grayImg,dstImg);
 24 
 25     //imshow("原始圖", srcImg);
 26     //imshow("灰度圖", grayImg);
 27     imshow("生成圖", dstImg);
 28 
 29     waitKey(0);
 30     return 0;
 31 }
 32 
 33 void VisitImgByPointer(Mat &inputImg, Mat &dstImg)
 34 {
 35     dstImg = inputImg.clone();
 36     int rows = dstImg.rows;
 37     int cols = dstImg.cols * dstImg.channels();
 38 
 39     for(int i = 0; i < rows; i++)
 40     {
 41         uchar* data = dstImg.ptr<uchar>(i);
 42         for(int j = 0; j < cols; j++)
 43         {
 44             data[j] = 0;  //處理每一個像素
 45             //add code
 46         }
 47     } 
 48 }
 49 
 50 void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg)
 51 {
 52     dstImg = inputImg.clone();
 53     int rows = dstImg.rows;
 54     int cols = dstImg.cols;
 55     int channels = dstImg.channels();
 56 
 57     if(dstImg.isContinuous())
 58     {
 59         cols *= rows;
 60         rows = 1;
 61         //cout << "is continuous " << endl;
 62     }
 63 
 64     for(int i = 0; i < rows; i++)
 65     {
 66         uchar* data = dstImg.ptr<uchar>(i);
 67         for(int j = 0; j < cols * channels; j++)
 68         {
 69             data[j] = 155;  //處理每一個像素
 70             //add code
 71         }
 72     } 
 73     //若存儲連續,等效於一下代碼
 74     //uchar* data = dstImg.data;
 75     //for(int i = 0; i < cols * rows * channels; i++)
 76     //    data[i] = 155;    //處理每一個像素
 77 
 78 }
 79 
 80 
 81 void VisitImgByIterator(Mat &inputImg, Mat &dstImg)
 82 {
 83     dstImg = inputImg.clone();
 84     const int channels = dstImg.channels();
 85   
 86     switch(channels)
 87     {
 88     case 1:
 89         {
 90             Mat_<uchar>::iterator it= dstImg.begin<uchar>();
 91             Mat_<uchar>::iterator itend= dstImg.end<uchar>();
 92             for ( ; it!= itend; it++) //處理每一個像素
 93             {
 94                 *it = 150;
 95             }
 96             break;
 97         }
 98     case 3:
 99         {
100             Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>();
101             Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>();
102             for ( ; it3!= itend3; it3++) //處理每一個像素
103             { 
104                 (*it3)[0]= 255;
105                 (*it3)[1]= 0;
106                 (*it3)[2]= 0;
107             }
108             break;
109         }
110     }
111 }
112 
113 void VisitImgByAt(Mat &inputImg, Mat &dstImg)
114 {
115     dstImg = inputImg.clone();
116     int rows = dstImg.rows;
117     int cols = dstImg.cols;
118     int channels = dstImg.channels();
119 
120     switch(channels)
121     {
122     case 1:
123         {
124             for(int i = 0; i < rows; i++)
125                 for(int j = 0; j < cols; j++)
126                     dstImg.at<uchar>(i,j) = 150;
127             break;
128         }
129     case 3:
130         {
131             for(int i = 0; i < rows; i++)
132                 for(int j = 0; j < cols; j++)
133                 {
134                     dstImg.at<Vec3b>(i,j)[0] =  0;
135                     dstImg.at<Vec3b>(i,j)[1] =  0;
136                     dstImg.at<Vec3b>(i,j)[2] = 255;
137                 }
138             break;
139         }
140     }
141 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM