如何在OpenCV中用零填充Matrix?

Suz*_*ioc 26 c++ opencv initialization matrix

下面的代码会导致异常.为什么?

#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;
    }

}
Run Code Online (Sandbox Code Playgroud)

错误如下:

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
Run Code Online (Sandbox Code Playgroud)

UPDATE

如果跟踪此代码,我看到构造函数行调用构造函数

inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
Run Code Online (Sandbox Code Playgroud)

为什么?这个原型有5个参数,而我提供4个参数.

jua*_*nza 35

如何在OpenCV中用零填充Matrix?

Mat使用零填充预先存在的对象,您可以使用Mat::zeros()

Mat m1 = ...;
m1 = Mat::zeros(1, 1, CV_64F);
Run Code Online (Sandbox Code Playgroud)

要初始化a Mat以使其仅包含零,您可以将带有值的标量传递0给构造函数:

Mat m1 = Mat(1,1, CV_64F, 0.0);
//                        ^^^^double literal
Run Code Online (Sandbox Code Playgroud)

你的版本失败的原因是传递0第四个参数匹配过载void*比一个标量更好.

  • @SuzanCioc我看到这个:`Mat :: Mat(int rows,int cols,int type,void*data,size_t step = AUTO_STEP)`这里http://docs.opencv.org/modules/core/doc/basic_structures. HTML (3认同)

GPP*_*PPK 13

使用cv :: mat :: setto

img.setTo(CV ::标量(redVal,greenVal,blueVal))


Lov*_*ill 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;
Run Code Online (Sandbox Code Playgroud)

但最好直接使用这个基于模板的构造函数:

//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));
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以选择填充零数据或创建零垫。

  1. setTo()填充零数据:

    img.setTo(Scalar::all(0));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用zeros()创建零数据:

    img = zeros(img.size(), img.type());
    
    Run Code Online (Sandbox Code Playgroud)

img 更改内存地址。


Nik*_*Ved 6

如果您更喜欢使用模板编程,您也可以这样做...

template<typename _Tp>
... some algo ...
cv::Mat mat = cv::Mat_<_Tp>::zeros(rows, cols);
mat.at<_Tp>(i, j) = val;
Run Code Online (Sandbox Code Playgroud)