 <p><code>Mat1b</code> and <code>Mat3b</code> are just two pre-defined cases of <code>Mat</code> types, which are defined in <code>core.hpp</code> as follows:</p> <pre><code>typedef Mat_&lt;uchar&gt; Mat1b; ... typedef Mat_&lt;Vec3b&gt; Mat3b; </code></pre> <p>That said, conversion between Mat and <code>Mat1b</code>/<code>Mat3b</code> should be quite natural/automatic:</p> <pre><code>Mat1b mat1b; Mat3b mat3b; Mat mat; mat = mat1b; mat = mat3b; mat1b = mat; mat3b = mat; </code></pre> <hr> <p>Back to your case, your problem should not be attributed to their conversions, but the way you define the <code>SubMain()</code> and how you use it. The input parameter of <code>SubMain()</code> is a <code>const cv::Mat3b &amp;</code>, however, you're trying to modify its header to change it to be a <code>Mat1b</code> inside the function.</p> <p>It will be fine if you change it to, e.g.:</p> <pre><code>cv::Mat1b SubMain(const cv::Mat3b&amp; img) { cv::Mat tmp = img.clone(); OperateImage opImg(tmp); opImg.Trafo(tmp); return tmp; } </code></pre>