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()
.
- Recall that C arrays are stored in a row-major order, hence any additional alignment stride is introduced between rows and not columns.. ^