1 pièce(s) jointe(s)
Conversion de rtype (cv::Mat.depth()) impossible
Salut les OpenCV,
j'ai d'abords développer une petite library d'effets divers, avec pour les test une grosse vingtaine d'images de tout types concernant la nature de l'image: paysages, portraits, groupes de personnes, dessins 3D ou 2D, etc... soit photos ou image, couleurs (avec canal alpha ou non) ou gris
dans la plupart des formats supportés par OpenCV ( *.bmp, *.jpeg, *.jpg et *.png).
Avec un bon fichiers main.cpp incluant la library graphique de débogage highgui permettant de tester mes effets et ajustements de tout types.
J'ai même compiler la library en library statique.
Et du coup j'ai commencer a développer la GUI, et là un gros hic... !!! ???
J'ai ajouter de nouveau fichiers de tests (images) et le drame je tombe sur fichier qui me résiste: il est encoder en 16-bit (non-signé).
Et j'arrive pas a le convertir en U8 ou du mois la conversion réussis mais quand ont affiche l'image après il ne correspond pas a l'image de départ.
l'image est la suivante:
Pièce jointe 187378
L'image est de type:
Citation:
PNG image data, 640 x 480, 16-bit/color RGB, non-interlaced
Sois si je ne convertis pas en U8 et met quand même a 8 la valeurs depth dans la GUI, j'obtiens un affichage de l'image vraiment strier et pas ressemblant du tout.
Sinon si j'essaie de convertir l'image en U8 soit avec:
Code:
1 2 3 4
|
frame.convertTo(frame, CV_8U) ;
// ou alors:
frame.assignTo(frame, CV_8U) ; |
Et bien j'obtiens un mauvais affichage partiel de l'image:
juste le milieux bas de l'image: ce qui correspond au rebord au bas du socle (le triangle là ou c'est plus le bleu foncé) sur lequel repose le vase en bleu uniforme (b=255).
Au lieu du motif et de la couleur créer par l'ombre du vase et du socle.
J'ai tout essayer de convertir en U8 avant ou après la conversion en RGB,
en passant par une Mat temporaire
(car il y a des opérateurs dans OpenCV qui ne peuvent travailler inline (src et dst la même Mat.) ),
ou en assignant la conversion a une Mat temporaire qui est pré-configuré en CV_8U
ou alors de prendre en compte le nombre de canaux lors de la conversion c.a.d CV_8UC3
et j'ai même penser que il y avait un canal alpha caché, vue a quoi ressemble l'image et vue sont encodage, c'est peut-être possible.
Rien a faire pour obtenir l'image original en passant par une conversion quelqu'onque.
J'arrive juste a afficher correctement l'image en passant par le main.cpp de test de ma library donc par highgui sans conversion,
ce qui ne me convient pas pour l'affichage avec GTK+3, avec la technique que j'utilise c.a.d en passant par un GdkPixbuf...
Car il faut que j'obtienne une image RGB(A) avec 8 de depth (CV_8U) pour pouvoir l'afficher de cette manière.
Je m'en remet donc a vous et vous serai grandement reconnaissant si vous désirez bien me fournir une solution au problème car j'ai épuisé les miennes.
Merci pour vos réponses éclairés et bon code CV a vous.
Merci je l'avait penser mais autrement.
Merci beaucoup d'avoir résolu le problème, car ta solution fonctionne parfaitement.
J'avais penser a ce type de solution d'ajouter un facteur et | ou une addition dans les paramètres de ConvertTo() ,
seulement je n'ai pas penser au fameux saturate_cast()<> de OpenCV donc je ne savais pas quel valeur(s) mettre,
étant donnée que l'image est un 16bits unsigned car ton facteur fonctionnera sûrement avec une image encodé en float CV_32F aussi je pense vue la nature du 1.0/256.
Qu'en pense tu ?
Car je n'ai pas d'images encoder par défaut sur CV_32F sure mon disque dur et j'ai bien fait le tour de mon dossier image récursivement.
Et je n'en trouve pas sur le net.
Pour finir j'arrive a avoir un affichage correct en tentant de convertir une CV_8U en CV_32F (simplement pour en avoir une rapidement la de suite).
Code:
1 2 3 4
|
frame = cv::imread(argv[1], cv::IMREAD_UNCHANGED) ;
cv::Mat b(frame.size(), CV_32F) ;
frame.convertTo(b, CV_32F, 1.0/256 ) ; |
Mais il y a une erreur lors de la tentative de sauvegarde:
Code:
1 2
|
cv::imwrite("./test01.png", b) ; |
Par contre comme ceux-ci ca n'affiche pas correctement mais sauvegarde correctement.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include <opencv2/opencv.hpp>
int main (int argc, char *argv[]) {
if (argc != 2) {
fprintf(stdout,"usage %s filename\n",argv[0]) ;
return 1 ;
}
cv::Mat frame ;
frame = cv::imread(argv[1], cv::IMREAD_UNCHANGED) ;
cv::Mat b(frame.size(), CV_32F) ;
frame.convertTo(b, CV_32F ) ;
cv::namedWindow("MyWin") ;
fprintf(stdout, "img channels: %d depth: %d\n", b.channels(), b.depth() ) ;
while (true) {
char keycode = cv::waitKey(1) ;
if ( keycode != -1) {
fprintf(stdout,"Keycode: %d\n",keycode) ;
break ;
}
imshow("MyWin", b) ;
}
cv::imwrite("./test01.png", b) ;
return 0 ;
} |
Donc je me suis tromper au-dessus il faut géré les CV_32F autrement:
Mais je suppose que une image encoder en plus 16bits est peu commune sauf imagerie spécialisée horsmise...
Merci beaucoup encore d'avoir solutionner le problème.