Reshaping OpenCV Mat fails

11,381

Solution 1

Make sure that you fully understand the effect from reshape() and the meaning of the parameters you pass to the method. Here's the article from OpenCV documentation on it:

Mat Mat::reshape(int cn, int rows=0) const

Parameters:   

    cn – New number of channels. If the parameter is 0, the number of channels remains the same.
    rows – New number of rows. If the parameter is 0, the number of rows remains the same.

So, at your first code snippet you initialised eigenvectors by four elements: 4, 3, 2, 1. reshape() creates another matrix of given size parameters for these elements.

cv::Mat reshaped = eigenvectors.reshape(4, 1); - here you go, you get the [1x1] 4-channel matrix. All the elements are stored in the single 4-channel element of the reshaped matrix just like the output says. To create the matrix with wished number of rows and columns set the number of channels and columns accordingly. For example, if there is a 1-channel matix of [4x4] size and you wish it to have 2 rows and 8 columns, you just call reshape(1,2).

Hope it helps.

Solution 2

The confunsion to most people is, the opencv reshape() function is different to Matlab's reshape, in matlab you manually provide both new numOfRows and numOfCols. With openCV you just provide the new image dimension(number of channels) as the first parameter and then the number of rows as the second parameter.

Open CV automatically figures out the number of new columns for you.

Share:
11,381
Seanny123
Author by

Seanny123

I'm a Theoretical Neuroscientist turned Research Engineer. I enjoy writing, taking chances, making mistakes and getting messy. Tweet me to contact me.

Updated on July 20, 2022

Comments

  • Seanny123
    Seanny123 almost 2 years

    I am unable to reshape my cv::Mat.

    Here is my code.

    #include "opencv2/core/core.hpp"
    #include "opencv2/contrib/contrib.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/objdetect/objdetect.hpp"
    #include <boost/algorithm/string.hpp>
    #include <stdlib.h>
    #include <vector>
    #include <string>
    #include <assert.h>
    #include <iostream>
    #include <fstream>
    #include <stdio.h>
    #include <iterator>
    #include <sstream>
    
    
    
    int main(int argc, const char* argv[])
    {
        std::cout << "Start\n";
        cv::Mat eigenvectors = (cv::Mat_<float>(2,2) << 4, 3, 2, 1);
        std::cout << "eigenvectors shape " << eigenvectors.size() << std::endl;
        cv::Mat reshaped = eigenvectors.reshape(4, 1);
        std::cout << reshaped.size() << std::endl;
        std::cout << reshaped << std::endl;
    }
    

    Here is the result.

    Start
    eigenvectors shape [2 x 2]
    [1 x 1]
    [4, 3, 2, 1]
    

    Why is my program claiming to have a 1x1 matrix, but holding the values for a 4x1 matrix? It is only doing this for this dimension.

    When I expand my code to include these tests.

    reshaped = eigenvectors.reshape(1, 4);
    std::cout << reshaped.size() << std::endl;
    std::cout << reshaped << std::endl;
    reshaped = eigenvectors.reshape(2, 2);
    std::cout << reshaped.size() << std::
    

    I get normal results.

    [1 x 4]
    [4; 3; 2; 1]
    [1 x 2]
    [4, 3; 2, 1]
    

    Is this a bug or am I doing something wrong?

    EDIT:

    To improve the Google relevance of this result, another symptom I was having is that as a result of my "reshaping", I was also losing the type of my Mat.