conversion between Mat and Mat1b/Mat3b

beginh picture beginh · Jun 14, 2015 · Viewed 7.2k times · Source

I want to match my code into a given interface. Inside my class OperateImage in all methods I use cv::Mat format. When putting it in SubMain function which uses cv::Mat3b and returns cv::Mat1b it does not work. How can I change it so that I can use my written class? I am sure there must exist simple conversion which however I did not find, I am beginning in opencv. Thank you in advance for help. Will be very grateful if someone can shortly point out when it makes sense to use Mat1b/Mat3b instead of Mat, what is their role? (I always saw examples using Mat.)

cv::Mat1b SubMain(const cv::Mat3b& img)
{
    OperateImage opImg(img);
    opImg.Trafo(img); // being used as reference in my methods
    return img;
}

Answer

herohuyongtao picture herohuyongtao · Jun 15, 2015

Mat1b and Mat3b are just two pre-defined cases of Mat types, which are defined in core.hpp as follows:

typedef Mat_<uchar> Mat1b;
...
typedef Mat_<Vec3b> Mat3b;

That said, conversion between Mat and Mat1b/Mat3b should be quite natural/automatic:

Mat1b mat1b;
Mat3b mat3b;
Mat mat;

mat = mat1b;
mat = mat3b;
mat1b = mat;
mat3b = mat;

Back to your case, your problem should not be attributed to their conversions, but the way you define the SubMain() and how you use it. The input parameter of SubMain() is a const cv::Mat3b &, however, you're trying to modify its header to change it to be a Mat1b inside the function.

It will be fine if you change it to, e.g.:

cv::Mat1b SubMain(const cv::Mat3b& img)
{
    cv::Mat tmp = img.clone();

    OperateImage opImg(tmp);
    opImg.Trafo(tmp);
    return tmp;
}