0 = black 255 = white, max intensity

I have always been using the Python version. Time to be a man and use the C++ version.

If you want to fundamentally understand OpenCV, go through the core tutorials first:


Some fundamental problems that I am running into:

OpenCV with GPU:

OpenCV header files

which OpenCV header file should I include?

You can figure this info out by looking at documentation. For example, cv::VideoCapture documentation is here. It shows that it is included in #include <opencv2/videoio.hpp>.

Cool Things

Some really cool things:

  • OpenCV uses a reference counter, similar to the way shared_ptr is implemented. So they know when to clean up

If you want to copy the matrix, you can do this

Mat F = A.clone();
Mat G;

Accessing Individual Pixels

An RGB image has 3-different channels. However, usually, we only process a black and white image, because it’s much faster to process.

Cycle through pixels opencv:

This is the method in the tutorial

    uchar* p;
    for (int i = 0; i < img.rows; i++) {
        p = img.ptr<uchar>(i);
        for (int j=0;j<img.cols;j++) {
            p[j] = 240;

However, there is a much faster method with multithreading

img.forEach<uchar>([](uchar &p, const int position[]) -> void {
	p = 255

If you just need a single pixel, you can do

cout <<<double>(0,0);

Type conversions

This is a very common problem, because you don’t actually want to be working with uchar everywhere throughout your codebase. That is super slow.

Mat pgm_image = imread("image.pgm", IMREAD_GRAYSCALE); //flag is important !
Mat pgm_double;
pgm_image.convertTo(pgm_double, CV_64F); // optionally scale by 1.0/255, if you need [0..1] range
double *I = pgm_double.ptr<double>(0);

Displaying Images

cv::imshow works in following ways:

  1. If the image is 8-bit unsigned, it is displayed as is.
  2. If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range “[0,255*256]is mapped to[0,255]`.
  3. If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].

Therefore, if you convert from unsigned to double, make sure to normalize if you want to display it.

For example

img = cv::imread("../livingroom.jpg", cv::IMREAD_COLOR);
cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);
img.convertTo(img, CV_64FC1, 1.0 / 255);
img.convertTo(img, CV_8UC1, 255.0);


I need to benchmark opencv, to see how my implementation compares to their speed