如何在OpenCV中访问/修改矩阵元素?为什么在()被模板化了?

Suz*_*ioc 12 c++ templates opencv matrix

我应该知道Mat元素类型at()是否正确使用?例如,如果我有

Mat rose = Mat(1,180, CV_64F, 0);
Run Code Online (Sandbox Code Playgroud)

然后我可以打电话

rose.at<short>(i,j)++;
Run Code Online (Sandbox Code Playgroud)

如果没有那么我应该使用哪个模板参数?

为什么Mat::at在模板化的同时Mat本身不是?

UPDATE

这个问题包含另一个错误的示例代码,现在在这里:如何在OpenCV中用零填充Matrix?

Mik*_*ail 9

正如William已正确指出的那样,您应该只提供正确的类型作为模板参数at.我相信它cv::Mat本身并不仅仅是为了简化而制作模板.但是,OpenCV工作人员正在尝试支持C++功能,包括模板.通过这种方式,界面变得略微异构.

由于显而易见的原因,您无法在运行时从类型变量中推断出编译器类型.但是,如果此时已知类型变量,则可以使用traits类在编译时推导出它:

template<int I>
struct CvType {};

template<>
struct CvType<CV_64F> { typedef double type_t; };
template<>
struct CvType<CV_32F> { typedef float type_t; };
template<>
struct CvType<CV_8U> { typedef unsigned char type_t; };
// Other types go here

void main()
{
  const int type = CV_64F;
  cv::Mat mat(10, 10, type);
  mat.at<CvType<type>::type_t>(1, 1);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以更改type所有at或其他方法调用的值,并且不需要手动更改类型.

  • 在您的情况下,`cv :: Mat`构造函数的最后一个参数是指向用户分配数据的指针,_not_是图像的默认填充.所以在你的情况下,你试图访问零地址的内存.摆脱它,你很好.或者用`cv :: Scalar(0)`替换它. (2认同)

Lov*_*ill 7

那么现在你编辑的帖子不同了。纠正:

Mat m1 = Mat(1,1, CV_64F, cvScalar(0.));
m1.at<double>(0,0) = 0;
Run Code Online (Sandbox Code Playgroud)

或尝试不同的:

Mat m1 = cv::Mat::zeros(1,1, CV_64F);
m1.at<double>(0,0) = 0;
Run Code Online (Sandbox Code Playgroud)