1. 程式人生 > >【OpenCV】OpenCV訪問畫素點的三種方式

【OpenCV】OpenCV訪問畫素點的三種方式

環境配置

  VS2013+OpenCV3.0+Win7(X64)

前言

  OpenCV是影象處理最常用的庫之一。它提供了許多常用的影象處理演算法相關的函式,極大地方便了影象處理方法的開發,而影象處理最本質的就是對影象中畫素點的畫素值的運算。所以我們需要了解一下OpenCV如何訪問影象中的畫素點。首先說明一下,這裡預設影象儲存為Mat格式,RGB型別。
  

三種訪問方式

1. 利用指標訪問

  通過呼叫函式 Mat::ptr(i) 來得到第i行的首地址地址,然後在行內訪問畫素;

for (int i = 0; i < Row; i++)
{        
    for
(int j = 0; j < Col; j++) { Scr.ptr<Vec3b>
(i)[j][0] = 0; } }

  上面的Vec3b指的是3通道的uchar型別的資料。i,j表示畫素點在影象中的位置,而[0]表示通道編號,因為是3通道的資料,所以[0]表示RGB中的藍色通道(因為在OpenCV中通道的順序是BGR)。
  

2. 利用迭代器訪問

  建立一個Mat::Iterator物件it,通過it=Mat::begin()來的到迭代首地址,遞增迭代器知道it==Mat::end()結束迭代;

while
(it != Scr.end<Vec3b>()) { //(*it)[0] = 0;//藍色通道置零; (*it)[1] = 0;//綠色通道置零; //(*it)[2] = 0;//紅色通道置零; it++; }

3. 動態訪問

  這種方法是最慢的一種方法,但是比較好理解,使用at函式來得到畫素,Mat::at(i,j)為一個畫素點的畫素值陣列,是一個大小為3的陣列。從0到2存放了BGR三種顏色的灰度值。

for (int i = 0; i < Row; i++)
{
    for (int j = 0; j < Col; j++)
    {
        Scr.at<Vec3b>(i, j)[2
] = 0; }
}

運算結果


原始影象

指標訪問方式

程式碼

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>

using namespace std;
using namespace cv;

void main()
{
    Mat Scr = imread("lena.jpg");
    if (Scr.empty() )
    {
        printf("%s\n", "讀入圖片失敗;");
        system("pause");
        return;
    }
    imshow("原始影象", Scr);


    int Row = Scr.rows;            //獲取行數目;
    int Col = Scr.cols;            //獲取列數目;
    int Channel = Scr.channels();  //獲取通道數目;


    Mat Array(3, 3, CV_8UC3, Scalar(2, 3, 240));
    cout << "Array=" <<endl<< Array<<endl;

    //指標的訪問
    for (int i = 0; i < Row; i++)
    {        
        for (int j = 0; j < Col; j++)
        {       

                Scr.ptr<Vec3b>(i)[j][0] = 0;
        }
   }

    //迭代器訪問,訪問的是每一個畫素點

    Mat_<Vec3b>::iterator it = Scr.begin<Vec3b>();
    while (it != Scr.end<Vec3b>())
    {
        //(*it)[0] = 0;//藍色通道置零;
        (*it)[1] = 0;//綠色通道置零;
        //(*it)[2] = 0;//紅色通道置零;
        it++;
    }


    //動態訪問,訪問的是每一個畫素點,最慢也是最直接易理解的訪問方式
    for (int i = 0; i < Row; i++)
    {
        for (int j = 0; j < Col; j++)
        {
            Scr.at<Vec3b>(i, j)[2] = 0;
        }

    }

    imshow("改變後的影象", Scr);
    waitKey(0);
    system("pause");
    return;
}

已完。。