C++ 如何在 OpenCV 中用零填充矩阵?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17041758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:52:28  来源:igfitidea点击:

How to fill Matrix with zeros in OpenCV?

c++opencvmatrixinitialization

提问by Suzan Cioc

The code below causes an exception. Why?

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

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

}

Error is follows:

错误如下:

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

UPDATE

更新

If tracing this code, I see that constructor line calls the constructor

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

inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)

Why? This prototype has 5 parameters, while I am providing 4 arguments.

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

采纳答案by LovaBill

Because the last parameter is optional and also the data pointer should point somewhere appropriate:

因为最后一个参数是可选的,而且数据指针应该指向适当的地方:

//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;

But better do it directly with this template-based constructor:

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

//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));

回答by juanchopanza

How to fill Matrix with zeros in OpenCV?

如何在 OpenCV 中用零填充矩阵?

To fill a pre-existing Matobject with zeros, you can use Mat::zeros()

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

Mat m1 = ...;
m1 = Mat::zeros(1, 1, CV_64F);

To intialize a Matso that it contains only zeros, you can pass a scalar with value 0to the constructor:

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

Mat m1 = Mat(1,1, CV_64F, 0.0);
//                        ^^^^double literal

The reason your version failed is that passing 0as fourth argument matches the overload taking a void*better than the one taking a scalar.

您的版本失败的原因是0作为第四个参数传递的重载void*比采用标量的重载更好。

回答by GPPK

use cv::mat::setto

使用cv::mat::setto

img.setTo(cv::Scalar(redVal,greenVal,blueVal))

img.setTo(cv::Scalar(redVal,greenVal,blueVal))

回答by Nik Ved

If You are more into programming with templates, You may also do it this way...

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

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

回答by James Koo

You can choose filling zero data or create zero Mat.

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

  1. Filling zero data with setTo():

    img.setTo(Scalar::all(0));
    
  2. Create zero data with zeros():

    img = zeros(img.size(), img.type());
    
  1. setTo()填充零数据:

    img.setTo(Scalar::all(0));
    
  2. 使用zeros()创建零数据:

    img = zeros(img.size(), img.type());
    

The img changes address of memory.

img 更改内存地址。

回答by Shameel Mohamed

You can use this to fill zeroes in a Mat object already containing data:

您可以使用它在已经包含数据的 Mat 对象中填充零:

image1 = Scalar::all(0);

For eg, if you use it this way:

例如,如果您以这种方式使用它:

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);

It will work fine. But you cannot use this for uninitialised Mat. For that you can go for other options mentioned in above answers, like

它会正常工作。但是您不能将它用于未初始化的 Mat。为此,您可以选择上述答案中提到的其他选项,例如

Mat drawing = Mat::zeros( image.size(), CV_8UC3 );

回答by Lonewolf

Mat img;

垫 img;

img=Mat::zeros(size of image,CV_8UC3);

img=Mat::zeros(图像大小,CV_8UC3);

if you want it to be of an image img1

如果你希望它是一个图像 img1

img=Mat::zeros(img1.size,CV_8UC3);

img=Mat::zeros(img1.size,CV_8UC3);

回答by Cynichniy Bandera

I presume you are talking about filling zeros of some existing mat? How about this? :)

我想你是在谈论填充一些现有垫子的零?这个怎么样?:)

mat *= 0;

垫 *= 0;