如何使用cv::Mat::convertTo函数

3
我正在编写一个函数,它接受任意类型的cv::Mat,将其转换为浮点图像,处理后再转换回原始类型。问题在于我想到的简单方法都无法实现。以下是我迄今为止尝试过的方法:
cv::Mat process(const cv::Mat& input)// input might be float
{
    cv::Mat_<float> result(input.size());

   // Generate result based on input.
    result = ...;

    // Now convert result back to the type of input:
#if 1
    // Version 1: Converting in place crashes with:
    // OpenCV Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in cv::_OutputArray::create,
    // file ...\OpenCV\modules\core\src\matrix.cpp, line 1365
    if (result.type() != input.type())
        result.convertTo(result, input.type());

#else
    // Version 2: Not what you'd expect
    if (result.type() != input.type())
    {
        cv::Mat tmp;
        result.convertTo(tmp, input.type());
        result = tmp;// This line doesn't replace result, but converts tmp back to float.
    }
#endif
    return result;
}

调用函数:
int main(int argc, char* argv[])
{
    cv::Mat_<float> a =  cv::Mat_<float>::zeros(256, 256);
    cv::Mat a1 = process(a);

    cv::Mat_<uint16_t> b =  cv::Mat_<uint16_t>::zeros(256, 256);
    cv::Mat b1 = process(b);
    assert(b1.type()==CV_16UC1);
    return 0;
}

那么,做这件事的标准方法是什么?我在Windows上使用OpenCV 2.4.10。


你不能只是返回 tmp; 而不是 result = tmp 吗? tmp 已经具有正确的类型和表示。 - Alan Stokes
你能添加std::cout << a1.type() << " and " << b1.type() << std::endl 并告诉我们吗? - Micka
2
啊...问题可能是你使用了那些模板Mats而不是openCV类型!你可以尝试使用cv::Mat b = cv::Mat::zeros(256, 256, 16UC1);吗? - Micka
@AlanStokes 针对这个特定的最小案例,这可能是一个解决方法,但在我的实际函数中,我会在那行代码之后继续处理“result”。 - bgp2000
好的...我试过了...输入类型并不重要,但是你的中间类型会出现问题。如果你将它改为cv::Mat result(input.size(), CV_32FC1);,一切都能正常工作,至少对我来说是这样的...不确定这是否是一个错误或者.convertTo不能从模板Mats中工作。 - Micka
显示剩余4条评论
1个回答

0
问题在于模板化的cv::Mat_<float>。显然,cv::Mat::convertTo()不能将Mat_<>作为输出。此外,cv::Mat_<float>::operator=()cv::Mat:operator=()的工作方式不同。它会隐式地将图像转换为适当的格式。

一旦你想到这一点,就很有道理了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接