Reshaping a matrix with OpenCV

A short post about the method cv::Mat::reshape(int channels, int rows).

A few days ago, I had some strange results when analyzing some high-dimensional data by PCA in OpenCV. For compatibility with another library, I was forcing the allocation of contiguous memory for my images, simply by creating them with only 1 row and $m \times n$ columns1, then reshaping into the actual size of $m \times n$ pixels. However, the corresponding principal values were actually very very low, ad furthermore the results was not stable at all.

Looking at my output more carefully, I suddenly realized that my PCA output had size $1 \times 1$ pix, which is clearly not high dimensional !

And I found the answer, and my bug, in the manual of course ! Let’s have a look at the complete signature of the method :

    cv::Mat& cv::Mat::reshape(int channels, int rows) const

You’ve probably guessed the bug by now.

As written above, the method is a const member of cv::Mat, i.e. it does not change the object that calls it. Instead, it returns a reference to another instance wrapping the same data but with the new size, stride, etc…

Hence, the fix was simple : replace each occurrence of myMatrix.reshape() by myMatrix = myMatrix.reshape().

  1. Recall that C arrays are stored in a row-major order, hence any additional alignment stride is introduced between rows and not columns.. ^