以下のコードは例外を引き起こします。どうして?
#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
[〜#〜] update [〜#〜]
このコードをトレースすると、コンストラクター行がコンストラクターを呼び出すことがわかります
inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
どうして?このプロトタイプには5つのパラメーターがあり、4つの引数を提供しています。
最後のパラメーターはオプションであり、データポインターは適切な場所を指す必要があるためです。
//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));
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
バージョンが失敗した理由は、4番目の引数として0
を渡すと、スカラーを取るよりもvoid*
を取るオーバーロードと一致するためです。
cv :: mat :: setto を使用します
img.setTo(cv :: Scalar(redVal、greenVal、blueVal))
テンプレートを使用したプログラミングにもっと興味がある場合は、この方法で行うこともできます...
template<typename _Tp>
... some algo ...
cv::Mat mat = cv::Mat_<_Tp>::zeros(rows, cols);
mat.at<_Tp>(i, j) = val;
これを使用して、すでにデータが含まれている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 drawing = Mat::zeros( image.size(), CV_8UC3 );
マットimg;
img = Mat :: zeros(画像のサイズ、CV_8UC3);
あなたがそれが画像であるようにしたい場合img1
img = Mat :: zeros(img1.size、CV_8UC3);
既存のマットのゼロを埋めることについて話していると思いますか?これはどう? :)
mat * = 0;