Le code ci-dessous provoque une exception. Pourquoi?
#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;
}
}
L'erreur est la suivante:
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
MISE À JOUR
Si le traçage de ce code, je vois que la ligne constructeur appelle le constructeur
inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
Pourquoi? Ce prototype a 5 paramètres, tandis que je fournis 4 arguments.
Parce que le dernier paramètre est facultatif et que le pointeur de données doit pointer vers un endroit approprié:
//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;
Mais il vaut mieux le faire directement avec ce constructeur basé sur un modèle:
//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));
Comment remplir Matrix avec des zéros dans OpenCV?
Pour remplir un objet Mat
préexistant avec des zéros, vous pouvez utiliser Mat::zeros()
Mat m1 = ...;
m1 = Mat::zeros(1, 1, CV_64F);
Pour initialiser un Mat
afin qu'il ne contienne que des zéros, vous pouvez passer un scalaire avec la valeur 0
au constructeur:
Mat m1 = Mat(1,1, CV_64F, 0.0);
// ^^^^double literal
La raison de l'échec de votre version est que le passage de 0
comme quatrième argument correspond à la surcharge prenant un void*
mieux que celui qui prend un scalaire.
utilisez cv :: mat :: setto
img.setTo (cv :: Scalar (redVal, greenVal, blueVal))
Si vous êtes plus dans la programmation avec des modèles, vous pouvez également le faire de cette façon ...
template<typename _Tp>
... some algo ...
cv::Mat mat = cv::Mat_<_Tp>::zeros(rows, cols);
mat.at<_Tp>(i, j) = val;
Vous pouvez l'utiliser pour remplir des zéros dans un objet Mat contenant déjà des données:
image1 = Scalar::all(0);
Par exemple, si vous l'utilisez de cette façon:
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);
Cela fonctionnera bien. Mais vous ne pouvez pas l'utiliser pour le Mat non initialisé. Pour cela, vous pouvez opter pour d'autres options mentionnées dans les réponses ci-dessus, comme
Mat drawing = Mat::zeros( image.size(), CV_8UC3 );
Mat img;
img = Mat :: zeros (taille de l'image, CV_8UC3);
si vous voulez qu'il soit d'une image img1
img = Mat :: zeros (img1.size, CV_8UC3);
Je suppose que vous parlez de remplir des zéros de certains tapis existants? Que dis-tu de ça? :)
mat * = 0;