1. 程式人生 > >How to access pixel data of an image

How to access pixel data of an image

總體來說, 總共有三種辦法:

(1)  using 'at'

(2) using direct address calculation

(3) using 'ptr'

方法一:如下

Mat img= imread("image.jpg", 0) //0 for grayscale image reading 
for (int i = 0; i < img.rows; i++) {// run through the rows
    for(int j = 0; j < img.cols; j++) { // run through the cols
            cout << (int) img.at<uchar>(i, j) << " "; // for getting
            img.at<uchar>(i, j) = 0; // for setting
    }
}

方法二: 對於grayscale image, by directly going to address.

Hint: 對於(8 bit)灰度圖影象, 影象資料的儲存格式如下所示, 5 x 10:


但是對於彩色影象而言, 例如彩色(RGB)影象有三通道, 在OpenCV 中尤其要注意彩色影象的儲存格式是每一個畫素是以GBR的順序儲存的。


要獲得第(i, j)個pixel的 k 通道分量的資料, 計算公式如下:


對於灰度影象, 程式如下:

Mat img= imread("image.jpg", 0) //0 for grayscale image reading 
for (int i = 0; i < img.rows; i++) {// run through the rows
    for(int j = 0; j < img.cols; j++) { // run through the cols
            cout << (int) *(img.data + img.step[0] * i + j * img.step[1]) << " "; // for getting
            *(img.data + img.step[0] * i + j * imgstep[1]= 0; // for setting
    }
}
對於彩色影象如下:
Mat img= imread("image.jpg", 1) //1 for color image reading 
for(int k = 0; k < img.step[1]; k++) {
    for (int i = 0; i < img.rows; i++) {// run through the rows
        for(int j = 0; j < img.cols; j++) { // run through the cols
            cout << (int) *(img.data + k + img.step[0] * i + j * img.step[1]) << " "; // for getting
            *(img.data + k + img.step[0] * i + j * imgstep[1]= 0; // for setting
        }
}


方法三, 使用指標

對於灰度影象:

Mat img= imread("image.jpg", 0) //0 for grayscale image reading 
for (int i = 0; i < img.rows; i++) {// run through the rows
    uchar* rowPtr = img.ptr<uchar>(i); // rowPtr holds the pointer to ith row
    for(int j = 0; j < img.cols; j++) { // run through the cols
            cout << (int) rowPtr[j] << " "; // for getting
            rowPtr[j] = 0; // for setting
    }
另外對於IplImage 的RGB的影象, 我們有如下的方式:
for(int i = 0; i < img -> height; i++) {
    for(int j = j; j < img -> width; j++) {
        cvScalar s;
        s = cvGet2D(img, i, j);
        s.val[0] = 0; //B
        s.val[1] = 0; //G
        s.val[2] = 0; //R
        cvSet2D(img, i, j, s);
    }
}

對於小的矩陣, 可以如下優化:

#include <opencv2/core/core.hpp>

using namespace cv;

int main(void)
{

    Mat img = imread("test.jpg");
    int rows = img.rows;
    int cols = img.cols;

    if (img.isContinuous())
    {
        cols = rows * cols; // Loop over all pixels as 1D array.
        rows = 1;
    }

    for (int i = 0; i < rows; i++)
    {
        Vec3b *ptr = img.ptr<Vec3b>(i);
        for (int j = 0; j < cols; j++)
        {
            Vec3b pixel = ptr[j];
        }
    }

    return 0;
}

還可以如下: