J'essaie d'utiliser OpenCV 2.3.1 pour convertir une image Bayer 12 bits en une image RGB 8 bits. Cela semble que cela devrait être assez simple à l'aide de la fonction CVCVTColor, mais la fonction jette une exception lorsque je l'appelle avec ce code:
cv::Mat srcMat(100, 100, CV_8UC3); const cv::Scalar val(255,0,0); srcMat.setTo(val); cv::Mat destMat(100, 100, CV_8UC3); cvCvtColor(&srcMat, &destMat, CV_RGB2BGR);
3 Réponses :
J'ai pu convertir mes données à 8 bits RGB à l'aide du code suivant:
// Copy the data into an OpenCV Mat structure cv::Mat bayer16BitMat(height, width, CV_16UC1, inputBuffer); // Convert the Bayer data from 16-bit to to 8-bit cv::Mat bayer8BitMat = bayer16BitMat.clone(); // The 3rd parameter here scales the data by 1/16 so that it fits in 8 bits. // Without it, convertTo() just seems to chop off the high order bits. bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625); // Convert the Bayer data to 8-bit RGB cv::Mat rgb8BitMat(height, width, CV_8UC3); cv::cvtColor(bayer8Bit, rgb8BitMat, CV_BayerGR2RGB);
Je fais la même chose qu'ici, mais mes images semblent avoir un filtre vert de l'image. pas certain de pourquoi
@pksorensen: Si vous avez un problème connexe, demandez-lui simplement une nouvelle question et reliez à celui-ci. De cette façon, vous pouvez ajouter plus de détails sur votre problème particulier.
J'ai fini par prendre un chemin différent et utiliser le SDK Nikon pour avoir fait le de-Bayer alors que je suis confronté à quelques problèmes qui tentent de le faire avec Libraw et OpenCV. L'utilisation de NIKONS SDK m'a donné de meilleurs résultats et de déterminer pourquoi les mêmes résultats ne pouvaient pas être exercés avec Libraw et OpenCV doivent attendre. Merci quand même.
Mais en utilisant 0.0625, vous avez également "couper les bits de commande bas" (X / 16 est identique au changement de bit X >> 4). Il est donc préférable de demander à la caméra d'envoyer une image de 8 bits et de garder le CPU refroidisseur. Il faut une méthode de compression plus sophistiquée comme la vieille bonne HDR (lente) ou des courbes simples (rapides) pour éviter les informations 4 bits en perdant pendant 16 (12) bits -> compression 8 bits.
@Vithiryaev qui serait génial si je pouvais demander à l'appareil photo de m'envoyer les fichiers du format dont j'avais besoin, mais dans ce cas, je n'ai eu que l'accès aux fichiers, pas la caméra elle-même.
Super travail! C'est ce que je cherchais. Cependant, j'ai aussi un problème de filtre vert comme @poul. Est-ce résolu ou demandé dans une nouvelle question?
La réponse de Gillfish fonctionne techniquement, mais lors de la conversion, il utilise une structure de données plus petite (CV_8UC1) que l'entrée (qui est CV_16UC1) et perd certaines informations de couleur.
Je suggérerais d'abord à décoder le codage de Bayer mais reste en 16 ans. -bits par canal (de CV_16UC1 à CV_16UC3) et de convertir ultérieur en CV_8UC3. p>
Le code de Gillfish modifié (en supposant que la caméra donne une image dans l'encodage 16 bits Bayer): P>
// Copy the data into an OpenCV Mat structure cv::Mat mat16uc1_bayer(height, width, CV_16UC1, inputBuffer); // Decode the Bayer data to RGB but keep using 16 bits per channel cv::Mat mat16uc3_rgb(width, height, CV_16UC3); cv::cvtColor(mat16uc1_bayer, mat16uc3_rgb, cv::COLOR_BayerGR2RGB); // Convert the 16-bit per channel RGB image to 8-bit per channel cv::Mat mat8uc3_rgb(width, height, CV_8UC3); mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3, 1.0/256); //this could be perhaps done more effectively by cropping bits
J'ai gratté ma tête pendant des heures se demanda pourquoi cela ne fonctionnait pas, je me suis rendu compte que je travaillais avec de grandes données Endian tandis que OpenCV attend de la petite endanie ...
Pour que quiconque a du mal à ce sujet, la solution ci-dessus ne fonctionne que si votre image vient en réalité en 16 bits, comme déjà suggéré par les commentaires que vous devez couper les 4 bits les moins importants. J'ai atteint cela avec cela. Ce n'est pas très propre mais ça marche.
Donc, il s'avère que je était i> manque quelque chose. Mon collègue a souligné que je mélangeais des appels C et C ++. Changer la dernière ligne en CV :: CVTColor (Srcmat, Desmat, CV_RGB2BGR); fait tout ce qui fonctionne comme un charme. Je travaille toujours sur le problème initial de convertir des données de Bayer 16 bits aux données RVB 8 bits, donc je posterai une mise à jour si je trouve la réponse à cela.
CVCVTColor CODE> appartient à l'ancien C OpenCV API, mais
CV :: Mat Code> est une classe d'API C ++. Les mélanger n'est pas une bonne idée et vous feriez mieux d'utiliser une seule version d'API.
CV :: CVTColor (SRCMAT, DSTMAT, COLOR_RGB2BGR) CODE> devrait fonctionner pour vous.
"Look de filtre vert" signifie probablement que vous avez spécifié le mauvais modèle de Bayer. Essayez-les tous.