与模板编程一起使用的OpenCV标量会导致编译错误

时间:2017-02-14 19:52:27

标签: c++ opencv templates

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

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

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_<double>}
  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<unsigned char, 3>&

我当时认为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;
}

1 个答案:

答案 0 :(得分:0)

您不能这样做,因为Scalar的尺寸不同于您的垫子,并且在这种情况下,operator =未得到解决。 OpenCV文档中的这个继承图最好地解释了这一点:

enter image description here

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