【问题标题】:OpenCV scalar used with template programming causes compilation error与模板编程一起使用的 OpenCV 标量导致编译错误
【发布时间】:2017-02-15 04:52:11
【问题描述】:

我在 Ubuntu 16.04 上使用来自 trunk 和 gcc 5.4 的最新 OpenCV。

我很难理解为什么下面的代码无法编译

template <typename T>
void Func2(const cv::Scalar clr, cv::Mat &img){
  img.at<T>(0, 0) = clr;
}

void Func1(const bool flag, const cv::Scalar clr, cv::Mat &img){
  if (flag == 1){
    Func2<cv::Vec4b>(clr, img);
  }
  else{
    Func2<cv::Vec3b>(clr, img);
  }
}

int main(){
  cv::Mat img = cv::Mat(100, 100, CV_8UC4, cv::Scalar(1,1,1,1));
  cv::Scalar clr = cv::Scalar(0, 0, 0, 0);

  Func1(1, clr, img);

  return 0;
}

编译错误是

void Func2(cv::Scalar, cv::Mat&) [with T = cv::Vec<unsigned char, 3>; cv::Scalar = cv::Scalar_<double>]的实例化中:从这里需要

错误:operator= 不匹配(操作数类型为 cv::Vec<unsigned char, 3>const Scalar {aka const cv::Scalar_&lt;double&gt;}
img.at<T>(0, 0) = clr; ^

/usr/local/include/opencv2/core/matx.hpp:305:38:注意:候选人: constexpr cv::Vec<unsigned char, 3>& cv::Vec<unsigned char, 3>::operator=(const cv::Vec<unsigned char, 3>&) template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1> ^
/usr/local/include/opencv2/core/matx.hpp:305:38:注意:未知 将参数 1 从 const Scalar {aka const cv::Scalar_<double>} 转换为 const cv::Vec&lt;unsigned char, 3&gt;&amp;

我在想可能是cv::Scalar 的类型需要正确匹配,但即使下面的代码编译也没有问题

int main(){
  cv::Mat img = cv::Mat(100, 100, CV_8UC4, cv::Scalar(1,1,1,1));
  cv::Scalar clr = cv::Scalar(0, 0, 0);

  img.at<cv::Vec4b>(0, 0) = clr // still compiles but has runtime error

  return 0;
}

【问题讨论】:

    标签: c++ opencv templates


    【解决方案1】:

    您不能这样做,因为 Scalar 的维数与您的垫子不同,并且运算符 = 在这种情况下无法解析。 OpenCV 文档中的继承图可以很好地解释这一点:

    如您所见,标量是一个具有模板类型的 4 维向量,而 mat 中的每个元素始终是 1 维,但通道数不同,表示为 cn。您需要使用 cv::Scalar::operator[] 为每个 Mat 元素显式分配值,以分别访问每个通道。

    【讨论】:

    • 我展示的最后一个代码 sn-p 尽管尺寸与 Scalar 和 Mat 不匹配,但它实际上可以编译。你知道为什么吗?
    • 在您的最后一个 sn-p 中,您可以将 Scalar(即 4 个暗淡)分配给 Vec4b,并将模板传递给 Mat(这会产生 4 个通道)。无论如何,发生的事情是您将 Scalar(4 通道)分配给 Vec4b(也是 4 通道),所以一切正常。
    • 我想我混淆了调光和通道的定义,我认为它们是同一回事。所以在最后一个 sn-p 中,标量中有 3 个通道,垫子中有 4 个通道,它仍然可以编译。你能告诉我OpenCV中尺寸的定义吗?
    • 即使使用 cv::Scalar(0, 0, 0) 构造函数,Scalar 内部仍然有 4 个维度。在您的情况下,重要的是您在 Mat::at 模板中拥有的内容以及在 = 符号右侧拥有的内容。正如我之前所说,Scalar 与 Vec4b 兼容,因为它具有相同的维数,实际上它继承自 vector。 cv::Mat 中的通道数取决于您在构造函数中创建它的类型(即 CV_8UC3 解析为 3 个通道,1 个暗淡)。更详细的描述在这里:docs.opencv.org/2.4.10/modules/core/doc/basic_structures.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 2015-06-19
    • 2013-03-31
    相关资源
    最近更新 更多