Introduction à Mat, CvMat et IplImage dans opencv et la conversion entre les trois

Les conteneurs de données courants liés aux opérations d'image dans OpenCV sont Mat, cvMat et IplImage. Ces trois types peuvent représenter et afficher des images. La différence est la suivante: le type Mat se concentre sur le calcul et les mathématiques sont plus élevées. OpenCV optimise le calcul du type Mat; les types CvMat et IplImage se concentrent davantage sur "l'image" et opencv se concentre sur «l'image» Les opérations sur l'image (zoom, extraction monocanal, opérations de seuil d'image, etc.) ont été optimisées. Avant opencv2.0, opencv était complètement implémenté en C, mais la relation entre le type IplImage et le type CvMat est similaire à la relation d'héritage en orienté objet. En fait, il existe une classe de base plus abstraite au-dessus de CvMat-CvArr, qui est courante dans le code source.

1. Il est clairement indiqué dans le document opencv que CvMat est obsolète (CvMat est maintenant obsolète, envisagez d'utiliser Mat à la place) n'est pas recommandé;
2. Relation de dérivation: CvArr -> CvMat -> IplImage
3. Un ensemble de choses pour Mat est imread, imshow, etc., différent de CvArr et de ses sous-classes cvLoadImage (), cvShowImage () ...

1. Type de matrice: type de matrice, matrice.
Dans openCV, Mat est un tableau de données dense multidimensionnel. Il peut être utilisé pour traiter des données multidimensionnelles courantes telles que des vecteurs et des matrices, des images, des histogrammes, etc.
Mat a 3 méthodes importantes:
1. Mat mat = imread (const String * filename); read image
2. imshow (const string frameName, InputArray mat); display image
3. imwrite (const string & filename, InputArray img);
Comparé avec le Types CvMat et IplImage, le type Mat pour le stockage d'images a des capacités d'opérations matricielles plus fortes et prend en charge les opérations matricielles courantes. Dans les applications intensives en calcul, la conversion des types CvMat et IplImage en type Mat réduira considérablement le temps de calcul.
Deux, type CvMat: type d'image

typedef struct CvMat
{
    int type;
    int step;
    /* for internal use only */
    int* refcount;
    int hdr_refcount;
    union
    {
        uchar* ptr;
        short* s;
        int* i;
        float* fl;
        double* db;
    } data;
#ifdef __cplusplus
    union
    {
        int rows;
        int height;
    };
    union
    {
        int cols;
        int width;
    };
#else
    int rows;
    int cols;
#endif
}
CvMat;


Dans openCV, il n'y a pas de structure de données vectorielles. À tout moment, mais lorsque nous voulons représenter un vecteur, nous pouvons utiliser des données matricielles pour le représenter. Cependant, le type CvMat est plus abstrait que le concept vectoriel que nous avons appris dans le cours d'algèbre linéaire. Par exemple, le type de données d'élément de CvMat n'est pas limité au type de données de base. Par exemple, ce qui suit crée une matrice de données bidimensionnelle : CvMat * cvCreatMat (int rows, int cols, int type);
type peut être n'importe quel type de données prédéfini, tel que RVB ou d'autres données multicanaux. De cette manière, une image colorée peut être représentée sur une matrice CvMat.
3. IplImage: Type d'image.
En termes de relation de type, nous pouvons dire que le type IplImage hérite du type CvMat. Bien sûr, il inclut également d'autres variables pour l'analyser en données d'image, qui sont définies comme suit:


typedef struct _IplImage  
    {  
        int nSize; / * IplImage size * /  
        int ID; / * Version (= 0) * /  
        int nChannels; / * La plupart des fonctions OPENCV prennent en charge 1, 2, 3 ou 4 canaux * /  
        int alphaChannel; / * Ignoré par OpenCV * /  
        int depth; / * Profondeur de bits de pixel: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, 
                               IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F et IPL_DEPTH_64F sont pris en charge par le  
        canal de caractères * / * /           Charder
        * les données ci-dessus * / * /  
CharrO Canaux de couleur entrelacés 0, canaux de couleur séparés par 
                               1. cvCreateImage ne peut créer que des images entrelacées * /  
        int origin; / * structure 0-en haut à gauche, 
                               Structure 1 en bas à gauche (style bitmaps Windows) * /  
        int align; / * disposition des lignes de l'image (4 ou 8). OpenCV l'ignore et utilise widthStep au lieu de * /  
        int width; / * largeur de l'image en pixels * /  
        int height ; / * Le nombre de pixels hauts de l'image * /  
        struct _IplROI * roi; / * La région d'intérêt de l'image. Lorsque la valeur n'est pas vide, seule la région sera traitée * /  
        struct _IplImage * maskROI; / * NULL doit être défini dans OpenCV * /  
        void * imageId; / * Identique à ci-dessus * /  
        struct _IplTileInfo * tileInfo; / * Identique à ci-dessus * /  
        int imageSize; / * Taille des données d'image (au format entrelacé imageSize = image-> height * image-> widthStep), octet unitaire * /  
        char * imageData; / * Pointer sur les données d'image à organiser * /  
        int widthStep; / * La taille de la ligne d'image à organiser, en octets * /  
        int BorderMode [4] ; / * Mode de fin de bordure, ignoré par OpenCV * /  
        int BorderConst [4]; / ​​* Identique à ci-dessus * /  
        char * imageDataOrigin; / * Le pointeur pointe vers une structure de données d'image différente (pas nécessairement arrangée), qui est préparée pour corriger l'allocation de mémoire d'image * /  
    }  
    IplImage;  
deux des la valeur dataOrder: Le canal de couleur entrelacé est la disposition des données de couleur sera la disposition échelonnée de BGRBGR ... Des canaux de couleur séparés sont stockés dans plusieurs plans de couleur lorsqu'il y a plusieurs canaux de couleur. roi est la structure IplROI, qui contient les variables membres xOffset, yOffset, height, width, coi, où xOffset, yOffset sont les coordonnées x, y et coi représente le canal d'intérêt (canal d'intérêt), et uniquement lorsqu'il est pas 0 efficace. L'accès aux éléments de données de l'image est divisé en stockage indirect et stockage direct. Lorsque l'élément d'image est de type à virgule flottante, (uchar *) est remplacé par (float *): 
Supplément: IplImage est dérivé de CvMat et CvMat est dérivé de CvArr, c'est-à-dire CvArr -> CvMat -> IplImage

            CvArr est utilisé comme paramètre de la fonction, peu importe ce que CvMat ou IplImage est passé, il est traité en interne par CvMat.

La petite différence lors de la création de CvMat et IplImage:

1. Lors de la construction d'une matrice, le premier paramètre est le nombre de lignes et le deuxième paramètre est le nombre de colonnes.

CvMat * cvCreateMat (lignes int, cols int, type int);

2. Lors de la création d'une image, le premier paramètre de CvSize est la largeur, qui est le nombre de colonnes, le deuxième paramètre est la hauteur, qui est le nombre de lignes. C'est l'opposé de la matrice CvMat.

IplImage * cvCreateImage (taille CvSize, profondeur int, canaux int);

CvSize cvSize (largeur int, hauteur int);

De plus, chaque ligne du buffer interne d'IplImage est alignée sur 4 octets, CvMat n'a pas cette restriction

Quatre, conversion mutuelle
4.1IplImage -> Mat

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
    IplImage* srcImg = cvLoadImage("F:\\IM_VIDEO\\kobe.jpg");
    Mat m = cvarrToMat(srcImg, true);
    namedWindow("kobe image", CV_WINDOW_AUTOSIZE);
    imshow("kobe image", m);
    waitKey(0);
    return 0;
}


résultat de l'opération:

4.2 Mat -> IplImage:

 

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
    Mat m = imread("F:\\IM_VIDEO\\kobe.jpg");
    IplImage* transIplimage = cvCloneImage(&(IplImage)m);
    cvShowImage("kobe image", transIplimage);
    waitKey(0);
    cvReleaseImage(&transIplimage);
    return 0;
}


Le résultat en cours d'exécution est le même que ci-dessus.
5. Méthode d'acquisition des pixels
5.1 La méthode d'acquisition des pixels de la méthode Mat est disponible à l'adresse: http://blog.csdn.net/piaoxuezhong/article/details/54236227

5.2 Acquisition de pixels de la méthode IplImage

Accès direct:
Les deux éléments les plus importants pour nous sont: char * imageData et widthStep. imageData stocke les données de pixels d'image et widStep est similaire à l'étape de CvMat, qui représente la longueur des données de ligne en octets.
Une image d'octets à canal unique m * n, son imageData est organisé comme suit:


#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
    IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);
    uchar* tmp = new uchar[img->width*img->height*img->nChannels];
    for (int i = 0; i < img->height; i++)
    {
        for (int j = 0; j < img->width; j++)
        {
            *tmp = ((uchar *)(img->imageData + i*img->widthStep))[j];
        }
    }
    cout << "第1行第1列的图像灰度值: " << (float)tmp[0]<< endl;
    cvShowImage("kobe image", img);
    waitKey(0);
    cvReleaseImage(&img);
    return 0;
}


Méthode d'acquisition du pointeur:


#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
    IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);
    //uchar* tmp = new uchar[img->width*img->height*img->nChannels];
    uchar* data = (uchar *)img->imageData;
    int step = img->widthStep / sizeof(uchar);
    uchar* tmp = data;
    for (int i = 0; i < img->height; i++)
    {
        for (int j = 0; j < img->width; j++)
        {
            *tmp = data[i*step + j];
        }
    }
    cout << "第1行第1列的图像灰度值: " << (float)tmp[0] << endl;
    cvShowImage("kobe image", img);
    waitKey(0);
    cvReleaseImage(&img);
    return 0;
}


 

Je suppose que tu aimes

Origine blog.csdn.net/yangdashi888/article/details/104522460
conseillé
Classement