web-dev-qa-db-fra.com

Imprimer les valeurs d'une matrice (Mat) dans OpenCV C++

Je veux vider les valeurs d'une matrice dans OpenCV sur la console en utilisant cout. J'ai rapidement compris que je ne comprenais pas suffisamment le système de types d'OpenvCV ni les modèles C++ pour accomplir cette tâche simple.

Est-ce qu'un lecteur pourrait poster (ou m'indiquer) un petit fragment de fonction ou de code qui imprime un tapis?

Cordialement, Aaron

PS: le code qui utilise la nouvelle interface C++ Mat par opposition à l'ancienne interface CvMat est préférable.

53
ahoffer

Voir la première réponse à Accès à un élément de matrice dans l'objet "Mat" (pas l'objet CvMat) dans OpenCV C++
Ensuite, passez simplement sur tous les éléments de cout << M.at<double>(0,0); plutôt que sur 0,0

Ou mieux encore avec le nouvelle interface C++ (grâce à SSteve

cv::Mat M;

cout << "M = "<< endl << " "  << M << endl << endl;
79
Martin Beckett

Je pense que l'utilisation de matrix.at<type>(x,y) n'est pas la meilleure façon de parcourir un objet Mat! Si je me souviens bien, matrix.at<type>(x,y) itérera depuis le début de la matrice à chaque fois que vous l'appelez (je me trompe peut-être). Je suggère d'utiliser cv::MatIterator_

cv::Mat someMat(1, 4, CV_64F, &someData);;
cv::MatIterator_<double> _it = someMat.begin<double>();
for(;_it!=someMat.end<double>(); _it++){
    std::cout << *_it << std::endl;
}
3
Dima Maligin
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <iomanip>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    double data[4] = {-0.0000000077898273846583732, -0.03749374753019832, -0.0374787251930463, -0.000000000077893623846343843};
    Mat src = Mat(1, 4, CV_64F, &data);
    for(int i=0; i<4; i++)
        cout << setprecision(3) << src.at<double>(0,i) << endl;

    return 0;
}
3
Dmoonleo

Si vous utilisez opencv3, vous pouvez imprimer un mat comme python numpy style:

Mat xTrainData = (Mat_<float>(5,2) << 1, 1, 1, 1, 2, 2, 2, 2, 2, 2);

cout << "xTrainData (python)  = " << endl << format(xTrainData, Formatter::FMT_PYTHON) << endl << endl;

Comme indiqué ci-dessous, vous pouvez le voir plus lisible, voir ici pour plus d’informations.

 enter image description here

Mais dans la plupart des cas, il n'est pas nécessaire de générer toutes les données dans Mat, vous pouvez générer une plage de lignes telle que 0 ~ 2 lignes:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <iomanip>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    //row: 6, column: 3,unsigned one channel
    Mat image1(6, 3, CV_8UC1, 5);

    // output row: 0 ~ 2
    cout << "image1 row: 0~2 = "<< endl << " "  << image1.rowRange(0, 2) << endl << endl;

    //row: 8, column: 2,unsigned three channel
    Mat image2(8, 2, CV_8UC3, Scalar(1, 2, 3));

    // output row: 0 ~ 2
    cout << "image2 row: 0~2 = "<< endl << " "  << image2.rowRange(0, 2) << endl << endl;

    return 0;
}

Sortie comme ci-dessous:

 enter image description here

0
Jayhello