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

后端 未结 2 1252
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-18 06:43

Following is an Assertion Error report (displayed on console) when calling cvtColor() function in opencv giving the argument CV_GRAY2BGR on a Mat object which is already a

相关标签:
2条回答
  • 2020-12-18 07: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));
        ...
    }        
    
    0 讨论(0)
  • 2020-12-18 07:28

    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.

    0 讨论(0)
提交回复
热议问题