1. 程式人生 > >opencv之訪問影象畫素

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 }

相關推薦

opencv訪問影象

訪問畫素的三種方法 ①指標訪問:最快 ②迭代器iterator:較慢,非常安全,指標訪問可能出現越界問題 ③動態地址計算:更慢,通過at()實現。適用於訪問具體某個第i行,j列的畫素,而不適用遍歷畫素 Mat在記憶體中儲存形式   灰度圖的儲存形式        RGB的儲存形式    一般情況下,Mat

opencv訪問影象的 三種方法

訪問畫素的三種方法 ①指標訪問:最快 ②迭代器iterator:較慢,非常安全,指標訪問可能出現越界問題 ③動態地址計算:更慢,通過at()實現。適用於訪問具體某個第i行,j列的畫素,而不適用遍歷畫素 Mat在記憶體中儲存形式   灰度圖的儲存形式        RGB的儲存形式    一般情況下,M

OpenCV訪問影象值並修改--IplImage

1.IplImage的結構: typedef struct _IplImage { int nSize; /* IplImage大小 */

openCV--訪問影象的三個方法

方法一       指標訪問:C操作符[ ] 方法二       迭代器iterater 方法三        動態地址計算 訪問速度上,debug模式下 ,方法一 > 方法二 > 方法

opencv中對影象訪問的三種方法利用程式進行解讀

程式碼放到自己的工程中,執行就可以的 #include <opencv2\opencv.hpp> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #includ

opencv訪問影象

(1) 假設你要訪問第k通道、第i行、第j列的畫素。 (2) 間接訪問: (通用,但效率低,可訪問任意格式的影象) 對於單通道位元組型影象: IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); CvSc

opencv 通過指標訪問影象值,輸出為空的問題

for (int i = 0; i < img_roi_gray_at.rows; ++i) { uchar* datatemp = img_roi_gray_at.ptr<uchar>(i);

訪問影象幾種方法

#include <iostream> #include <opencv2/opencv.hpp> #include <Windows.h> #include <opencv2/highgui/highgui.hpp> using namespace

運用opencv 讀取BMP影象資訊 程式碼及實現

1. 環境:Win7(64位),opencv2.3,vs2010 2.程式碼: /////////////////////////////////////////////////////////////////////////////////////////////////

OpenCV中讀取影象

OpenCV中用於讀取影象畫素點的值的方法很多,這裡主要提供了兩種常用的方法。 方法一 利用IplImage資料型別的imageData定位資料緩衝區來實現,imageData包含指向影象第一個畫素資料的指標 例: If( imgSource != 0 )//imgSource為IplImage* { fo

opencv對於bmp影象值的讀取和賦值

#include <stdio.h> #include <cv.h> #include <highgui.h> void main(){     IplImage *img=cvLoadImage("c://fruitfs.bmp",1

OpenCV訪問影象中的

OpenCV影象處理運算元都是一個函式。 作用: 接受一個輸入或多個輸入,產生輸出影象。 格式: g(x)=f(h(x))//單個輸入, 或 g(x)=f(h0(x),h1(x),...,hn(x))//多個輸入 影象處理變換中典型的操作:點操作 點操作: 影象亮度和對

OpenCV學習筆記(三)影象的提取

     提取影象的畫素及畫素索引 Mat src, dst; src = imread("mountainandwater.jpg"); //讀取影象 if (src.empty()) { qDebug()<<"can

opencv讀取影象值讀取並儲存到txt檔案(二)灰度圖

#include "stdafx.h" #include"cv.h" #include <stdlib.h> #include <stdio.h> #include <math.h> #include <fstream> #include &l

opencv讀取影象值讀取並儲存到txt檔案(一)RGB

#include “stdafx.h” #include"cv.h" #include <stdlib.h> #include <stdio.h> #include <math.h> #include #include #include “iost

python數字影象處理(3):影象訪問與裁剪

圖片讀入程式中後,是以numpy陣列存在的。因此對numpy陣列的一切功能,對圖片也適用。對陣列元素的訪問,實際上就是對圖片畫素點的訪問。 彩色圖片訪問方式為: img[i,j,c] i表示圖片的行數,j表示圖片的列數,c表示圖片的通道數(RGB三通道分別對應0,1

OpenCV二值化影象操作

二值化影象畫素不是0就是255,資料型別為uchar。所以訪問方法是: // 這裡inputmat是二值化影象的mat inputmat.at<uchar>(y, x); 判斷是否為白色的方法: if (inputmat.at<uchar&g

OpenCV——修改影象(隨心所欲)

這一節將講述OpenCV——修改影象畫素,根據自己需要新增特定的畫素部分 原圖如下,我們就是先在這個視訊流上新增一條直線段(有一定寬度的) 現在我們想新增一條,135行-455行,列350--360的直線段 #include<opencv2/opencv.hp

opencv影象值讀取

說到影象畫素,肯定要先認識一下影象中的座標系長什麼樣。 1. 座標體系中的零點座標為圖片的左上角,X軸為影象矩形的上面那條水平線;Y軸為影象矩形左邊的那條垂直線。該座標體系在諸如結構體Mat,Rect,

OpenCV影象操作及效率分析

        學習OpenCV也幾個月了,雖然對OpenCV有些瞭解,但是感覺基礎還是沒打實,在這在介紹一下OpenCV的畫素操作,以及OpenCV讀取影象的格式和讀取影象的效率分析。當然文章也有很多沒有介紹到的地方,希望大家多多指教,相互交流。         在計