Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板编程使用的OpenCV标量导致编译错误_C++_Opencv_Templates - Fatal编程技术网

C++ 模板编程使用的OpenCV标量导致编译错误

C++ 模板编程使用的OpenCV标量导致编译错误,c++,opencv,templates,C++,Opencv,Templates,我在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 (fla

我在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;
}

您不能这样做,因为标量的维数与mat的维数不同,并且在这种情况下,运算符=未解析。OpenCV文档中的继承关系图最好地解释了这一点:


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

我显示的最后一个代码段实际上是编译的,尽管它与Scalar和Mat的维度不匹配。你知道为什么吗?在你的最后一个代码片段中,当你将标量(4个dims)分配给传递到Mat的模板中的Vec4b(这将导致4个通道)时,这是可以的。不管怎样,现在发生的事情是,你将标量(4通道)分配给Vec4b(也是4通道),所以一切正常。我想我把DIM和通道的定义搞混了,我以为它们是一样的。因此,在最后一段代码中,标量中有3个通道,mat中有4个通道,它仍然可以编译。您能告诉我OpenCV中维度的定义吗?即使您使用cv::Scalar(0,0,0)构造函数,标量内部仍然有4个维度。在您的例子中,最重要的是Mat::at模板中的内容以及=符号右侧的内容。正如我前面所说,标量与Vec4b兼容,因为它具有相同的维数,并且实际上它继承自vector。cv::Mat中的通道数取决于您在构造函数中使用的类型(即cv_8UC3解析为3个通道,1个dim)。更详细的描述如下:
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;
}