OpenCV

https://docs.opencv.org/2.4/modules/gpu/doc/gpu.html

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:

Resources

Some fundamental problems that I am running into:

OpenCV with GPU: https://docs.opencv.org/4.x/da/d2c/tutorial_table_of_content_gpu.html

Random Questions

How does OpenCV deal with NaN values when visualizing? I ran into this issue while trying to display depth images.

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;
A.copyTo(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 << M.at<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);

https://answers.opencv.org/question/125250/converting-cvmat-to-double/

Displaying Images

https://stackoverflow.com/questions/9588719/opencv-double-mat-shows-up-as-all-white

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);

Benchmarking

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

https://docs.opencv.org/4.x/dc/d69/tutorial_dnn_superres_benchmark.html

How a CV Mat is implemented

OpenCV uses reference counting to keep track of cv::Mat objects’ memory. When a cv::Mat object is copied, the new object points to the same data as the original, and an internal reference counter is incremented. The memory is deallocated only when the reference counter reaches zero, meaning no cv::Mat objects point to the data anymore. This system allows for efficient memory use and copying mechanisms, avoiding unnecessary data duplication.

latex