opencv Pixel Access Efficient pixel access using cv::Mat::ptr pointer


Example

If efficiency is important, a fast way to iterate over pixels in a cv::Mat object is to use its ptr<T>(int r) method to obtain a pointer to the beginning of row r (0-based index).

According to the matrix type, the pointer will have a different template.

  • For CV_8UC1: uchar* ptr = image.ptr<uchar>(r);
  • For CV_8UC3: cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);
  • For CV_32FC1: float* ptr = image.ptr<float>(r);
  • For CV_32FC3: cv::Vec3f* ptr = image.ptr<cv::Vec3f>(r);

This ptr object can then be used to access the pixel value on row r and column c by calling ptr[c].

To illustrate this, here is an example where we load an image from disk and invert its Blue and Red channels, operating pixel by pixel:

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

int main(int argc, char** argv) {
    cv::Mat image = cv::imread("image.jpg", CV_LOAD_IMAGE_COLOR);

    if(!image.data) {
        std::cout << "Error: the image wasn't correctly loaded." << std::endl;
        return -1;
    }

    // We iterate over all pixels of the image
    for(int r = 0; r < image.rows; r++) {
        // We obtain a pointer to the beginning of row r
        cv::Vec3b* ptr = image.ptr<cv::Vec3b>(r);

        for(int c = 0; c < image.cols; c++) {
            // We invert the blue and red values of the pixel
            ptr[c] = cv::Vec3b(ptr[c][2], ptr[c][1], ptr[c][0]);
        }
    }

    cv::imshow("Inverted Image", image);
    cv::waitKey();

    return 0;
}