154 votes

Comment trouver le type d'un objet Mat avec Mat::type() dans OpenCV ?

Je suis un peu confus avec type() méthode de Mat dans OpenCV.
Si j'ai les lignes suivantes :

mat = imread("C:\someimage.jpg");
type = mat.type();

y type = 16 comment puis-je savoir quel type de mat La matrice est
J'ai essayé de trouver la réponse dans son manuel et dans quelques livres, en vain.

264voto

Kevin Johnsrude Points 140

À des fins de débogage, au cas où vous souhaiteriez rechercher un fichier brut Mat::type dans un débogueur :

C1

C2

C3

C4

C(5)

C(6)

C(7)

C(8)

CV_8U

0

8

16

24

32

40

48

56

CV_8S

1

9

17

25

33

41

49

57

CV_16U

2

10

18

26

34

42

50

58

CV_16S

3

11

19

27

35

43

51

59

CV_32S

4

12

20

28

36

44

52

60

CV_32F

5

13

21

29

37

45

53

61

CV_64F

6

14

22

30

38

46

54

62

Ainsi, par exemple, si type = 30, le type de données OpenCV est le suivant CV_64FC4 . Si type = 50 alors le type de données OpenCV est CV_16UC(7) .

262voto

Octopus Points 1289

Voici une fonction pratique que vous pouvez utiliser pour aider à identifier vos matrices opencv au moment de l'exécution. Je la trouve utile pour le débogage, au moins.

string type2str(int type) {
  string r;

  uchar depth = type & CV_MAT_DEPTH_MASK;
  uchar chans = 1 + (type >> CV_CN_SHIFT);

  switch ( depth ) {
    case CV_8U:  r = "8U"; break;
    case CV_8S:  r = "8S"; break;
    case CV_16U: r = "16U"; break;
    case CV_16S: r = "16S"; break;
    case CV_32S: r = "32S"; break;
    case CV_32F: r = "32F"; break;
    case CV_64F: r = "64F"; break;
    default:     r = "User"; break;
  }

  r += "C";
  r += (chans+'0');

  return r;
}

Si M est une var de type Mat vous pouvez l'appeler comme ça :

string ty =  type2str( M.type() );
printf("Matrix: %s %dx%d \n", ty.c_str(), M.cols, M.rows );

Il produira des données telles que :

Matrix: 8UC3 640x480 
Matrix: 64FC1 3x2 

Il convient de noter qu'il existe également des méthodes Matrix. Mat::depth() y Mat::channels() . Cette fonction est juste un moyen pratique d'obtenir une interprétation lisible par l'homme à partir de la combinaison de ces deux valeurs dont les bits sont tous stockés dans la même valeur.

36voto

Martin Beckett Points 60406

Dans l'en-tête d'OpenCV, " types_c.h "il existe un ensemble de définitions qui les génèrent, le format est le suivant CV_bits{U|S|F}C<number_of_channels>
Ainsi, par exemple CV_8UC3 signifie des caractères non signés de 8 bits, 3 canaux de couleur - chacun de ces noms correspond à un entier arbitraire avec les macros de ce fichier.

Edit : Voir " types_c.h " par exemple :

#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))

eg.
depth = CV_8U = 0
cn = 3
CV_CN_SHIFT = 3

CV_MAT_DEPTH(0) = 0
(((cn)-1) << CV_CN_SHIFT) = (3-1) << 3 = 2<<3 = 16

Alors CV_8UC3 = 16 mais vous n'êtes pas censé utiliser ce numéro, vérifiez simplement type() == CV_8UC3 si vous avez besoin de savoir quel est le type d'un tableau interne d'OpenCV.
Rappelez-vous qu'OpenCV convertira le jpeg en BGR (ou en échelle de gris si vous passez '0' à la variable imread ) - donc cela ne vous dit rien sur le fichier d'origine.

18voto

ProgrammingCuber Points 337

D'autres ont répondu à cette question, mais j'ai trouvé une solution qui a très bien fonctionné pour moi.

System.out.println(CvType.typeToString(yourMat.type()));

16voto

shahar_m Points 727

J'ai ajouté quelques fonctionnalités à la fonction de la réponse de @Octopus, à des fins de débogage.

void MatType( Mat inputMat )
{
    int inttype = inputMat.type();

    string r, a;
    uchar depth = inttype & CV_MAT_DEPTH_MASK;
    uchar chans = 1 + (inttype >> CV_CN_SHIFT);
    switch ( depth ) {
        case CV_8U:  r = "8U";   a = "Mat.at<uchar>(y,x)"; break;  
        case CV_8S:  r = "8S";   a = "Mat.at<schar>(y,x)"; break;  
        case CV_16U: r = "16U";  a = "Mat.at<ushort>(y,x)"; break; 
        case CV_16S: r = "16S";  a = "Mat.at<short>(y,x)"; break; 
        case CV_32S: r = "32S";  a = "Mat.at<int>(y,x)"; break; 
        case CV_32F: r = "32F";  a = "Mat.at<float>(y,x)"; break; 
        case CV_64F: r = "64F";  a = "Mat.at<double>(y,x)"; break; 
        default:     r = "User"; a = "Mat.at<UKNOWN>(y,x)"; break; 
    }   
    r += "C";
    r += (chans+'0');
    cout << "Mat is of type " << r << " and should be accessed with " << a << endl;

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X