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.