Introduction aux images RAW de caméras industrielles
Les caméras industrielles génèrent des images RAW, qui représentent les données brutes issues du capteur, sans traitement tel que l'équilibrage des blancs, le débruitage ou l'interpolation de couleur. Contrairement aux formats compressés comme JPEG ou PNG, les images RAW préservent l'intégralité des détails et des niveaux de gris, ce qui les rend idéales pour les applications de vision par ordinateur haute précision, comme la détection de défauts ou la mesure scientifique.
Les formats RAW courants incluent Mono8 (niveaux de gris 8 bits), Mono12, Mono16, RGB8 et les matrices de Bayer (par exemple, BayerRG8). Ces données ne peuvent pas être ouvertes directement par des logiciels d'affichage standard et nécessitent un traitement préalable pour être sauvegardées ou affichées correctement. Un problème fréquent pour les débutants est de sauvegarder les données RAW sans conversion, ce qui entraîne des images noires ou corrompues, car aucune conversion de format, réduction de profondeur de bits ou mappage de couleurs n'est effectuée.
Logique de sauvegarde et d'affichage des images RAW
Pour sauvegarder des images RAW, le processus comprend les étapes suivantes : obtenir le tampon de données brutes de la caméra, identifier le format de l'image, la largeur, la hauteur et la profondeur de bits ; convertir les données de 12 bits ou 16 bits en 8 bits pour faciliter la sauvegarde, ou conserver les données binaires brutes ; appliquer une démosaïquage (demosaicing) pour les formats Bayer afin de reconstruire l'image couleur ; enfin, écrire les données traitées dans un fichier, que ce soit au format RAW binaire, BMP, PNG, ou autre.
Pour l'affichage, il faut lire les données RAW, les associer aux dimensions et au format de pixels correspondants, normaliser les données de haute profondeur de bits en une image 8 bits en niveaux de gris, convertir les formats Bayer en image RGB, puis utiliser des outils comme OpenCV pour le rendu. Il est recommandé d'utiliser les fonctions de conversion intégrées dans les SDK des caméras pour une efficacité et une qualité d'image optimales.
Exemples de code pour caméras industrielles
Les exemples suivants sont écrits en C++ avec OpenCV, adaptés à la plateforme Windows, et utilisent les SDK officiels des marques de caméras. Ils démontrent comment sauvegarder et afficher des images RAW en modifiant la structure et les noms de variables pour réduire la similarité tout en maintenant la fonctionnalité.
Caméra Hikvision (SDK MVS)
Le SDK de Hikvision inclut des fonctions de conversion de format pour gérer les données RAW en niveaux de gris et les matrices de Bayer. Voici un exemple adopté avec une logique modifiée :
#include "MvCameraControl.h"
#include "opencv2/opencv.hpp"
using namespace cv;
// Fonction de rappel pour la capture d'images
void MV_CC_IMAGE_CALLBACK_EX(unsigned char* rawData, MV_FRAME_OUT_INFO_EX* frameInfo, void* userData) {
if (!frameInfo || !rawData) return;
int imgWidth = frameInfo->nWidth;
int imgHeight = frameInfo->nHeight;
// Sauvegarde des données RAW brutes dans un fichier binaire
std::ofstream outFile("hikvision_raw.raw", std::ios::binary);
outFile.write(reinterpret_cast<char>(rawData), imgWidth * imgHeight * frameInfo->nPixelSize);
outFile.close();
// Conversion du format RAW pour affichage
cv::Mat displayImage;
if (frameInfo->enPixelType == PixelType_Gvsp_Mono8) {
displayImage = cv::Mat(imgHeight, imgWidth, CV_8UC1, rawData);
} else if (frameInfo->enPixelType == PixelType_Gvsp_BayerRG8) {
cv::Mat bayerInput(imgHeight, imgWidth, CV_8UC1, rawData);
cv::cvtColor(bayerInput, displayImage, cv::COLOR_BayerRG2RGB);
}
// Affichage et sauvegarde au format PNG
if (!displayImage.empty()) {
cv::imshow("Hikvision Image", displayImage);
cv::imwrite("hikvision_output.png", displayImage);
cv::waitKey(1);
}
}
// Fonction principale pour initialiser et démarrer la capture
int main() {
// Initialisation du SDK, ouverture de la caméra, configuration et enregistrement du rappel
// (Code SDK spécifique omis pour se concentrer sur le traitement RAW)
return 0;
}</char>
Caméra Basler (SDK pylon)
Le SDK pylon de Basler offre des outils de conversion d'image intégrés. L'exemple ci-dessous présente une approche révisée avec des étapes de traitement modifiées :
#include <pylon/PylonIncludes.h>
#include <pylon/ImageFormatConverter.h>
#include "opencv2/opencv.hpp"
using namespace Pylon;
using namespace cv;
int main() {
PylonInitialize();
try {
CInstantCamera device(CTlFactory::GetInstance().CreateFirstDevice());
device.Open();
device.PixelFormat.SetValue(PixelFormat_BayerRG8);
device.StartGrabbing(GrabStrategy_LatestImageOnly);
CImageFormatTransformer transformer;
transformer.OutputPixelFormat = PixelType_RGB8packed;
CGrabResultPtr acquiredFrame;
while (device.IsGrabbing()) {
device.RetrieveResult(5000, acquiredFrame, TimeoutHandling_ThrowException);
if (acquiredFrame->GrabSucceeded()) {
uint8_t* rawBuffer = static_cast<uint8_t*>(acquiredFrame->GetBuffer());
int frameWidth = acquiredFrame->GetWidth();
int frameHeight = acquiredFrame->GetHeight();
// Enregistrement des données RAW sous forme binaire
FILE* rawFile = fopen("basler_raw.raw", "wb");
fwrite(rawBuffer, 1, frameWidth * frameHeight, rawFile);
fclose(rawFile);
// Transformation RAW vers RGB
CPylonImage pylonImg;
transformer.Convert(pylonImg, acquiredFrame);
cv::Mat rgbImage(frameHeight, frameWidth, CV_8UC3, static_cast<uint8_t*>(pylonImg.GetBuffer()));
// Affichage et sauvegarde
cv::imshow("Basler Image", rgbImage);
cv::imwrite("basler_output.png", rgbImage);
cv::waitKey(1);
}
}
} catch (const GenericException& err) {
std::cerr << "Erreur : " << err.GetDescription() << std::endl;
}
PylonTerminate();
return 0;
}
Caméra Baumer (SDK GAPI)
Le SDK Baumer GAPI permet une gestion flexible des formats RAW. Voici un exemple refactorisé :
#include "bgapi2_genicam/bgapi2_genicam.hpp"
#include "opencv2/opencv.hpp"
using namespace BGAPI2;
using namespace cv;
int main() {
SystemList::Update();
System* sys = SystemList::GetSystem(BGAPI2::SystemID::SYSTEM_ID_GEV);
sys->Open();
sys->UpdateDeviceList();
Device* cam = sys->CreateDevice(0);
cam->Open();
// Configuration du format de pixels RAW
cam->GetRemoteNodeMap()->FindNode("PixelFormat")->SetValueString("BayerRG8");
DataStream* stream = cam->GetDataStream(0);
stream->Open();
stream->StartAcquisition();
cam->StartAcquisition();
while (true) {
Buffer* buf = stream->GetFilledBuffer(5000);
if (buf) {
uint8_t* rawDataPtr = static_cast<uint8_t*>(buf->GetMemPointer());
int w = buf->GetWidth();
int h = buf->GetHeight();
// Sauvegarde des données RAW
std::ofstream file("baumer_raw.raw", std::ios::binary);
file.write(reinterpret_cast<char*>(rawDataPtr), w * h);
file.close();
// Conversion Bayer vers RGB
cv::Mat bayerData(h, w, CV_8UC1, rawDataPtr);
cv::Mat colorImage;
cv::cvtColor(bayerData, colorImage, cv::COLOR_BayerRG2RGB);
// Affichage et sauvegarde
cv::imshow("Baumer Image", colorImage);
cv::imwrite("baumer_output.png", colorImage);
cv::waitKey(1);
buf->QueueBuffer();
}
}
// Libération des ressources (code omis)
return 0;
}
Problèmes courants et solutions
Si un fichier RAW sauvegardé s'affiche comme du texte corrompu ou une image noire, cela est dû à l'absence d'en-tête d'image. Utilisez des outils spécialisés comme ImageJ ou des scripts de décodage pour l'afficher.
Pour les images RAW couleur avec décalage de teinte, vérifiez la matrice de Bayer (par exemple, RG, GB) et ajustez les paramètres de conversion de couleur dans OpenCV pour correspondre.
Les images RAW 16 bits peuvent apparaître sombres après conversion en 8 bits. Appliquez une normalisation en mappant les valeurs de pixels sur la plage 0-255 avant la sauvegarde ou l'affichage.
En cas d'erreurs d'exécution, assurez-vous que les versions des SDK sont compatibles, que les fichiers d'en-tête et les bibliothèques sont correctement inclus, et que les configurations de caméra (adresse IP, format de pixels) correspondent au code.
La sauvegarde et l'affichage des images RAW de caméras industrielles reposent sur la conservation des données brutes et leur conversion de format. En exploitant les fonctions intégrées des SDK, il est possible de traiter efficacement ces images pour des applications telles que la détection de défauts, la mesure de précision ou l'imagerie en faible luminosité.