How to interpret c++ opencv Assertion error messages due to an error in cvtColor function?

只谈情不闲聊 提交于 2019-11-29 12:09:08

This snippet

#include <opencv2\opencv.hpp>
using namespace cv;

int main(int argc, char** argv)
{
    // Just a small green BGR image
    Mat3b img(10,10,Vec3b(0,255,0));

    Mat1b gray;
    cvtColor(img, gray, CV_GRAY2BGR); // WARNING: this won't work (on purpose)

    return 0;
}

will produce your exact error:

OpenCV Error: Assertion failed (scn == 1 && (dcn == 3 || dcn == 4)) in cv::cvtCo lor, file C:\builds\2_4_PackSlave-win32-vc12-static\opencv\modules\imgproc\src\c olor.cpp, line 3789


This code is obviuosly wrong, because you're trying to convert an BGR image from GRAY.

OpenCV is telling you:

Since you're using the code CV_GRAY2BGR, I'm expecting to convert from GRAY (1 channel) source image to a BGR (3 channel) destination image. (I'll allow also BGRA (4 channels) as destination image, even if CV_GRAY2BGRA would be more appropriate in this case.)

In the documentation OpenCV is telling you:

  • src: input image: 8-bit unsigned, 16-bit unsigned ( CV_16UC... ), or single-precision floating-point.
  • dst: output image of the same size and depth as src.
  • code: color space conversion code (see the description below).
  • dstCn: number of channels in the destination image; if the parameter is 0, the number of the channels is derived automatically from src and code .

In C++, OpenCV say this as

CV_Assert( scn == 1 && (dcn == 3 || dcn == 4));

where scn stands for "Source Channels Number", and dcn stands for "Destination Channels Number".

Now the last point, where do scn and dcn comes from? If you use a debugger and follow the execution path, you'll see in function void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) in color.cpp that (comments added by me):

void cv::cvtColor( InputArray _src /* source image*/, 
                   OutputArray _dst /* destination image*/,  
                   int code, /* here is CV_GRAY2BGR*/ 
                   int dcn /* defaults to -1*/ ) 
{
    Mat src = _src.getMat(), dst;
    ...
    int scn = src.channels(); // scn is the number of channels of the source image 
    ...
    switch( code ) {
        ...
        case CV_GRAY2BGR: case CV_GRAY2BGRA:
            if( dcn <= 0 ) dcn = (code==CV_GRAY2BGRA) ? 4 : 3; 
            // destination channels are set to 3 because of the code CV_GRAY2BGR

            // Check that the input arguments are correct
            CV_Assert( scn == 1 && (dcn == 3 || dcn == 4));
    ...
}        

calling cvtColor() function in opencv giving the argument CV_GRAY2BGR on a Mat object which is already a BGR image

You have already answered your own question here. The assertion will have originally have been something like:

CV_Assert( scn == 1 && (dcn == 3 || dcn == 4));

Since you're using a BGR Mat, scn - which is the number of channels in the source Mat - will be 3 causing the whole expression to evaluate to false, and the assertion to fail.

The operation you are performing makes no sense. Omit it, and your code will probably work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!