Comment remplir Matrix avec des zéros dans OpenCV?

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%buildincludeopencv2coremat.hpp, line 537

UPDATE

si je trace 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, alors que je fournis 4 arguments.

23
demandé sur Suzan Cioc 2013-06-11 14:18:22

8 réponses

parce que le dernier paramètre est optionnel et aussi le pointeur de données devrait pointer quelque part 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 mieux vaut le faire directement avec ce constructeur basé sur le 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));
11
répondu William 2013-06-11 11:24:46

comment remplir la matrice avec des zéros dans OpenCV?

pour remplir unMat objet avec des zéros, vous pouvez utiliser Mat::zeros()

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

Pour initialiser un Mat pour qu'il ne contienne que des zéros, vous pouvez passer un scalar avec la valeur 0 pour le constructeur:

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

la raison pour laquelle votre version a échoué est que passing 0 comme quatrième argument correspond à la surcharge de prendre un void* mieux que celui qui prend un scalaire.

28
répondu juanchopanza 2013-06-11 14:03:33

utiliser cv:: mat:: setto

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

11
répondu GPPK 2013-06-11 10:26:05

si vous êtes plus à la programmation avec des modèles, vous pouvez aussi 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;
6
répondu Nik Ved 2013-06-11 17:00:04

vous pouvez utiliser ceci pour remplir des zéros dans un objet Mat contenant déjà des données:

image1 = Scalar::all(0);

Par exemple, si vous utiliser 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);

Il fonctionne parfaitement. Mais vous ne pouvez pas l'utiliser pour un tapis non initialisé. Pour cela, vous pouvez choisir d'autres options mentionnées dans les réponses ci-dessus, comme

Mat drawing = Mat::zeros( image.size(), CV_8UC3 );
3
répondu Shameel Mohamed 2016-02-10 10:38:23

vous pouvez choisir de remplir des données zéro ou de créer un tapis zéro.

  1. remplir le zéro des données avec setTo ():

    img.setTo(Scalar::all(0));
    
  2. Créer un zéro de données zéros ():

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

l'img change l'adresse de la mémoire.

2
répondu James Koo 2016-06-18 06:28:49

Mat img;

img=Mat::zéros(taille de l'image,CV_8UC3);

si vous voulez qu'il soit de une image img1

img=Mat:: zéros (img1.size, CV_8UC3);

1
répondu Lonewolf 2015-06-04 16:43:44

je présume que vous parlez de remplir des zéros d'un tapis existant? Comment à ce sujet? :)

mat *= 0;

0
répondu Cynichniy Bandera 2016-02-03 13:01:33