以下代码会导致异常。为什么呢?
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void main() {
try {
Mat m1 = Mat(1,1, CV_64F, 0);
m1.at<double>(0,0) = 0;
}
catch(cv::Exception &e) {
cerr << e.what() << endl;
}
}
错误如下:
OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3
) - 1))*4) & 15) == elemSize1()) in unknown function, file %OPENCV_DIR%\build\include\opencv2\core\mat.hpp, line 537
更新
如果跟踪此代码,我会看到构造函数行调用构造函数
inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
为什么呢?这个原型有5个参数,而我提供4个参数。
答案 0 :(得分:31)
如何在OpenCV中用零填充Matrix?
要使用零填充预先存在的Mat
对象,您可以使用Mat::zeros()
Mat m1 = ...;
m1 = Mat::zeros(1, 1, CV_64F);
要初始化Mat
以使其仅包含零,您可以将值0
的标量传递给构造函数:
Mat m1 = Mat(1,1, CV_64F, 0.0);
// ^^^^double literal
你的版本失败的原因是传递0
作为第四个参数匹配重载比使用标量的void*
更好。
答案 1 :(得分:13)
img.setTo(CV ::标量(redVal,greenVal,blueVal))
答案 2 :(得分:11)
因为最后一个参数是可选的,并且数据指针也应指向适当的位置:
//inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
double mydata[1];
Mat m1 = Mat(1,1, CV_64F, mydata);
m1.at<double>(0,0) = 0;
但最好直接使用这个基于模板的构造函数:
//inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
Mat m1 = Mat(1,1, CV_64F, cvScalar(0.));
//or even
Mat m1 = Mat(1,1, CV_64F, double(0));
答案 3 :(得分:6)
如果您更喜欢使用模板进行编程,您也可以这样做......
template<typename _Tp>
... some algo ...
cv::Mat mat = cv::Mat_<_Tp>::zeros(rows, cols);
mat.at<_Tp>(i, j) = val;
答案 4 :(得分:3)
您可以使用它在已包含数据的Mat对象中填充零:
image1 = Scalar::all(0);
例如,如果你这样使用它:
Mat image,image1;
image = imread("IMG_20160107_185956.jpg", CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
cvtColor(image,image1,CV_BGR2GRAY);
image1 = Scalar::all(0);
它会正常工作。但你不能将它用于未初始化的Mat。为此,您可以选择上述答案中提到的其他选项,例如
Mat drawing = Mat::zeros( image.size(), CV_8UC3 );
答案 5 :(得分:2)
Mat img;
img = Mat :: zeros(图像大小,CV_8UC3);
如果你想要它是一个图像img1
IMG =垫::零(img1.size,CV_8UC3);
答案 6 :(得分:2)
您可以选择填充零数据或创建零Mat。
答案 7 :(得分:0)
我认为你在谈论填充一些现有垫子的零点?这个怎么样? :)
mat * = 0;