由于 cvtColor 函数错误,如何解释 c++ opencv 断言错误消息?

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

以下是在 opencv 中调用 cvtColor() 函数时在已经是 BGR 图像的 Mat 对象上给出参数 CV_GRAY2BGR 时的断言错误报告(显示在控制台上)。我想知道如何由一个还不知道这里有什么错误的人来解释这个错误消息。 (希望一些博学的人不会投票结束这个问题作为题外话,因为我知道学习阅读 Assertion 或 c++ 新手的任何其他错误消息有很大的价值。)而且我猜这很可能是一个关于读取断言错误的 opencv 问题。

OpenCV Error: Assertion failed (scn == 1 && (dcn == 3 ||
 dcn == 4)) in cv::cvtColor, file C:\builds_4_PackSlave-win32-vc12-shared\open
cv\modules\imgproc\src\color.cpp, line 3791

我知道这里测试了2个条件,

  1. (scn == 1)
  2. (dcn == 3 || dcn == 4)

并且其中一个应该失败导致断言错误。如何区分和明确失败的条件?可能我可能需要查看 cvtColor 函数源代码,这没问题。 (实际上我做到了,但我在 improc.cpp class 那里找不到名称为 scn 或 dcn 的变量)

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

您已经在这里回答了您自己的问题。断言最初是这样的:

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

由于您使用的是 BGR 垫,scn(源垫中的通道数)将是 3,导致整个表达式的计算结果为 false ,以及失败的断言。

您正在执行的操作没有意义。忽略它,您的代码可能会起作用。

这个片段

#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;
}

将产生您的确切错误:

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


此代码显然是错误的,因为您正在尝试将 BGR 图像从 GRAY 转换。

OpenCV 告诉你:

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.)

documentation OpenCV 中告诉你:

  • src:输入图像:8 位无符号、16 位无符号(CV_16UC...)或单精度浮点数。
  • dst: 与src.
  • 大小和深度相同的输出图像
  • code: color space 转换代码(见下文说明)。
  • dstCn目标图像中的通道数;如果参数为 0,通道数自动从 src 和代码导出。

在 C++ 中,OpenCV 表示为

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

其中scn代表"Source Channels Number",dcn代表"Destination Channels Number"。

最后一点,scndcn是从哪里来的?如果您使用调试器并遵循执行路径,您将在 color.cpp 中的函数 void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) 中看到(我添加的注释):

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));
    ...
}