【问题标题】:Getting enum names (e.g. CV_32FC1) of OpenCV image types?获取 OpenCV 图像类型的枚举名称(例如 CV_32FC1)?
【发布时间】:2012-09-02 08:58:09
【问题描述】:

在 OpenCV 的 C++ 接口中,检查图像的类型似乎很容易。如果您有图像cv::Mat img = cv::imread("someImage.xyz"),则只需使用int theType = img.type()

但是,正如您所料,调用 img.type() 只会给出一个整数,而不是枚举名称(例如 CV_32FC1)。

如果我知道 OpenCV 枚举的整数值,是否有一种简单的方法可以打印出枚举名称(例如 CV_32FC1)?

【问题讨论】:

标签: c++ image-processing opencv enums image-formats


【解决方案1】:

据我所知,OpenCV 中不存在这样的功能。

我认为你最好编写自己的函数来获得这些。很多开关盒,但我想它可以完成工作。枚举可以找到here

编辑:

这是你可以用来提取类型的东西。我猜可能有一种更有效的方法,但我现在无法理解它。

std::string getImageType(int number)
{
    // find type
    int imgTypeInt = number%8;
    std::string imgTypeString;

    switch (imgTypeInt)
    {
        case 0:
            imgTypeString = "8U";
            break;
        case 1:
            imgTypeString = "8S";
            break;
        case 2:
            imgTypeString = "16U";
            break;
        case 3:
            imgTypeString = "16S";
            break;
        case 4:
            imgTypeString = "32S";
            break;
        case 5:
            imgTypeString = "32F";
            break;
        case 6:
            imgTypeString = "64F";
            break;
        default:
            break;
    }

    // find channel
    int channel = (number/8) + 1;

    std::stringstream type;
    type<<"CV_"<<imgTypeString<<"C"<<channel;

    return type.str();
}

【讨论】:

  • 好主意。我按照您的建议编写了一些代码来执行此操作。请参阅下面的答案。
  • 应该使用枚举本身,而不是使用整数(在您在特定构建中检查它们时正确)。 case 8U: str= "8U" 那么如果枚举在不同的构建中发生变化,您一定会正确处理它们。
  • 在代码中硬编码 8 不是一个好主意。见stackoverflow.com/questions/10167534/…
【解决方案2】:

按照@Bob 的建议,我编写了自己的函数来解决这个问题。这里是:

// take number image type number (from cv::Mat.type()), get OpenCV's enum string.
string getImgType(int imgTypeInt)
{
    int numImgTypes = 35; // 7 base types, with five channel options each (none or C1, ..., C4)

    int enum_ints[] =       {CV_8U,  CV_8UC1,  CV_8UC2,  CV_8UC3,  CV_8UC4,
                             CV_8S,  CV_8SC1,  CV_8SC2,  CV_8SC3,  CV_8SC4,
                             CV_16U, CV_16UC1, CV_16UC2, CV_16UC3, CV_16UC4,
                             CV_16S, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4,
                             CV_32S, CV_32SC1, CV_32SC2, CV_32SC3, CV_32SC4,
                             CV_32F, CV_32FC1, CV_32FC2, CV_32FC3, CV_32FC4,
                             CV_64F, CV_64FC1, CV_64FC2, CV_64FC3, CV_64FC4};

    string enum_strings[] = {"CV_8U",  "CV_8UC1",  "CV_8UC2",  "CV_8UC3",  "CV_8UC4",
                             "CV_8S",  "CV_8SC1",  "CV_8SC2",  "CV_8SC3",  "CV_8SC4",
                             "CV_16U", "CV_16UC1", "CV_16UC2", "CV_16UC3", "CV_16UC4",
                             "CV_16S", "CV_16SC1", "CV_16SC2", "CV_16SC3", "CV_16SC4",
                             "CV_32S", "CV_32SC1", "CV_32SC2", "CV_32SC3", "CV_32SC4",
                             "CV_32F", "CV_32FC1", "CV_32FC2", "CV_32FC3", "CV_32FC4",
                             "CV_64F", "CV_64FC1", "CV_64FC2", "CV_64FC3", "CV_64FC4"};

    for(int i=0; i<numImgTypes; i++)
    {
        if(imgTypeInt == enum_ints[i]) return enum_strings[i];
    }
    return "unknown image type";
}

我是否忘记在查找表中包含任何 OpenCV 图像类型?

【讨论】:

  • 你必须注意两件事。首先,没有零通道的情况,总是至少有 1 个通道,这实际上意味着 CV_8U = CV_8UC1 等。其次,您最多可以有 CV_CN_MAX 通道,根据 2.4.2 文档设置为512,因此您以这种方式将自己限制为 4 个频道。我写了一些东西,看看我的编辑,只要确保测试它,因为我没有编译它。
  • @Bob 你确定实现了 5 到 512 像素的枚举吗?编译器说 CV_8UC5 没有定义。
  • 它们不是#defined,而是使用CV_MAKETYPE派生的,例如CV_MAKETYPE(CV_32F, 5);当然,如果您不打算使用这么多通道,您可以使用您的功能,只需删除 CV_8U 等,因为它们返回与 CV_8UC1 等相同的结果
  • @Bob 啊,这是有道理的。我试图理解 cv::Mat 数据结构的所有微妙之处,所以很高兴你指出了这一点。
猜你喜欢
  • 1970-01-01
  • 2018-04-05
  • 2016-08-12
  • 2018-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
相关资源
最近更新 更多