2013-06-11 17 views
20

Il codice seguente provoca un'eccezione. Perché?Come riempire Matrix con zeri in OpenCV?

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

} 

errore è seguente:

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

Se tracciare questo codice, vedo che la linea di costruzione chiama il costruttore

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

Perché? Questo prototipo ha 5 parametri, mentre sto fornendo 4 argomenti.

+2

Ecco un esempio di 'cv :: Mat depthMap = cv :: Mat :: zeros (depthMap.rows, depthMap.cols, depthMap.type());' –

risposta

9

Perché l'ultimo parametro è facoltativo e anche il puntatore di dati deve puntare da qualche parte appropriata:

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

Ma meglio farlo direttamente con questo modello a base di costruttore:

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

Come riempire Matrix con zeri in OpenCV?

per riempire un Mat oggetto pre-esistente con zeri, è possibile utilizzare Mat::zeros()

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

Per inizializzare un Mat in modo che contenga solo zeri, è possibile passare uno scalare con un valore 0 al costruttore :

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

la ragione per la versione non è riuscita è che passando 0 come quarto argomento corrisponde al sovraccarico di prendere un 012.migliore di quello che prende uno scalare.

+0

Grazie. Ma cosa fa il mio campione? '0' non viene convertito automaticamente in' Scalare'? –

+0

@SuzanCioc potrebbe essere interpretato come "void *", ovvero come puntatore ad alcuni dati. – juanchopanza

+0

Non vedo alcun prototipo con 4 parametri e 'void *' alla fine. –

6

Se siete più in programmazione con i modelli, si può anche fare in questo modo ...

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

Mat img;

img = Mat :: zeros (dimensione dell'immagine, CV_8UC3);

se si vuole che sia di un img1 un'immagine

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

0

Suppongo che stiate parlando di riempire gli zeri di un tappetino esistente? Cosa ne pensi di questo?:)

mat * = 0;

3

È possibile utilizzare questo per riempire zeri in un oggetto opaco che contiene già dati:

image1 = Scalar::all(0); 

Per esempio, se si utilizza in questo modo:

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

apparecchio funzionerà regolarmente. Ma non puoi usare questo per Mat non inizializzato. Per quello puoi andare per altre opzioni citate nelle risposte sopra, come

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

Puoi scegliere di riempire dati zero o creare zero Mat.

  1. riempimento dei dati pari a zero con setTo():

  2. Creare dati pari a zero con zeros():

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

L'img cambia l'indirizzo di memoria.