How can I access an RGB mat as a 1D array? I looked at the documentation but couldn't find how the 3 channel data is laid out in that case.
I'm trying to loop over each pixel with 1 for loop going from n=0
to n = img.rows*img.cols - 1
, and access R, G, and B values at each pixel.
Any help would be greatly appreciated.
I don't really understand why you really need only 1 loop, so I will propose you several options (including 1 or 2 for-loops) that I know by experience to be efficient.
If you really want to iterate over all the values with only one loop in a safe way, you can reshape the matrix and turn a 3-channel 2D image into a 1-channel 1D array using
cv::Mat::reshape(...)
(doc):There are two caveats:
reshape()
returns a newcv::Mat
reference, hence its output needs to be assigned to a variable (it won't operate in-place)OpenCV stores the matrix data in row-major order. Thus, an alternative is to iterate over the rows by getting a pointer to each row start. This way, you will not do anything unsafe because of possible padding data at the end of the rows:
Why do I like the iteration over the rows ? Because it is easy to make parallel. If you have a multi-core computer, you can use any framework (such as OpenMP or GCD) to handle each line in parallel in a safe way. Using OpenMP, it as easy as adding a
#pragma parallel for
before the outer loop.