更改cv :: Mat图像的类型(解释)

时间:2016-05-16 16:02:16

标签: c++ opencv image-processing

无论出于何种原因,我的.tiff图片被OpenCV cv::imread错误地输入为CV_16U类型而非CV_16S。我知道这是不正确的,因为我向我解释了我的数据(图像应包含-9999的虚拟值和最大正值),并且在Matlab输入时得到正确的值。

我仍然可以通过例如.at<type>函数我自己知道实际类型,所以我可以使用.at<short>。但是,cv::Mat::type()是错误的,如果我使用其他函数进行进一步处理(可能依赖于此参数(处理可能取决于cv::Mat::type()),则不可取。

如何更改cv::Mat::type()而不转换图片?也就是说,我不希望从unsigned shortshort表示重新计算值,而只需要更改读取的方式。

如何更改与图片相关联的cv::Mat::type()(但不是简单地将图片转换为其他类型)。

以下是一些示例代码及其输出来说明问题:

cv::Mat test = cv::imread(argv[1], CV_LOAD_IMAGE_ANYDEPTH);
if (test.type() == CV_16U){ // true
    std::cerr << (short)(*std::min_element(test.begin<short>(),
                                           test.end<short>()))
              << std::endl;
    std::cerr << (short)(*std::max_element(test.begin<short>(),
                                           test.end<short>()))
              << std::endl;
    // output is OK, "-9999" and "1645"

    std::cerr << (unsigned short)
                 (*std::min_element(test.begin<unsigned short>(),
                                    test.end<unsigned short>()))
              << std::endl;
    std::cerr << (unsigned short)
                 (*std::max_element(test.begin<unsigned short>(),
                                    test.end<unsigned short>()))
              << std::endl;
    // output is not OK: "1" and "55537"

    cv::Mat test2;
    test.convertTo(test2, CV_16S);
    // also tried:
    // test.assignTo(test2, CV_16S);

    std::cerr << (short)(*std::min_element(test2.begin<short>(),
                                           test2.end<short>()))
              << std::endl;
    std::cerr << (short)(*std::max_element(test2.begin<short>(),
                                           test2.end<short>()))
              << std::endl;
    // output is not OK: "1" and "32767"

    test.type = CV_16U; // what I would like to do
}

1 个答案:

答案 0 :(得分:2)

OpenCV默认将其数据成员公开(尽管您通常不想自己弄乱它们)。来吧,试一试;如果它工作得很好!如果还不好......

警告:未经测试和黑客的解决方案

test.flags = (test.flags & ~CV_MAT_TYPE_MASK) | CV_16S;