Quelles sont les différences entre CV_8U et CV_32F et à quoi dois-je m’inquiéter lors de la conversion entre eux?

J’ai du code qui fonctionne et je suppose que c’est parce que j’utilise les mauvais types de données ou que je les convertis mal.

Il mélange des objects cv::Mat de types CV_8U (ce qui est créé lors de la lecture d’une image jpg en niveaux de gris avec cv::imread ), CV_32F et CV_32S .

Quelles sont les différences entre ces types de données et de quoi dois-je être sûr lors de la conversion entre eux?

CV_8U est non signé 8bit / pixel – c’est-à-dire qu’un pixel peut avoir les valeurs 0-255, c’est la plage normale pour la plupart des formats d’image et de vidéo.

CV_32F est float – le pixel peut avoir n’importe quelle valeur entre 0-1.0, ceci est utile pour certains ensembles de calculs sur les données – mais il doit être converti en 8bits pour enregistrer ou afficher en multipliant chaque pixel par 255.

CV_32S est une valeur entière signée de 32 bits pour chaque pixel – encore une fois utile lorsque vous effectuez des calculs de nombre entier sur les pixels, mais que vous devez à nouveau convertir en 8 bits pour enregistrer ou afficher. Ceci est plus compliqué car vous devez décider comment convertir le plus grand nombre possible de valeurs possibles (+/- 2 milliards!) En 0-255.

Ils décrivent simplement les composants individuels:

  • CV_8U : Entier non signé sur 1 octet (caractère unsigned char ).

  • CV_32S : entier signé de 4 octets ( int ).

  • CV_32F : virgule flottante de 4 octets ( float ).

Ce que vous devez toujours garder à l’esprit, c’est que vous ne pouvez pas simplement les lancer de l’un à l’autre (ou cela ne fera probablement pas ce que vous voulez), en particulier entre des types de tailles différentes.

Veillez donc toujours à utiliser des fonctions de conversion réelles pour les convertir entre elles, comme cv::convert ou cv::Mat::convertTo . N’essayez pas simplement d’accéder aux éléments d’un type cv::Mat de CV_8U utilisant par exemple cv::Mat::at ou cv::Mat_ .

Ou si vous voulez simplement convertir des éléments individuels et ne voulez pas créer une nouvelle masortingce de l’autre type, accédez aux éléments en utilisant la fonction appropriée (dans l’exemple cv::Mat::at ) et convertissez le résultat à float .

De même, existe-t-il une différence entre le nombre de composants et un type cv::Mat de CV_8UC3 différent d’une image de type CV_8UC1 et qui ne devrait (normalement) pas être consulté par cv::Mat::at , mais par cv::Mat::at .

EDIT: En voyant la réponse de Martin, il se peut que vous soyez au courant de tout cela et ses explications sont plus ce que vous cherchiez.