web-dev-qa-db-fra.com

opencv lire l'image jpeg à partir du tampon

J'ai un unsigned char* tampon contenant les données d'une image jpeg. Je voudrais afficher cette image en utilisant c ++ et opencv. Si je fais:

Mat img(Size(640, 480), CV_8UC3, data);
namedWindow("image", 1);
imShow("image", img);

Je reçois un désordre bruyant de pixels.

Je suppose que c'est parce que les données sont en jpeg (avec un en-tête). Parce que cela fonctionne:

Mat imgbuf(Size(640, 480), CV_8UC3, data);
Mat img = imdecode(imgbuf, CV_LOAD_IMAGE_COLOR);

MAIS je ne peux pas utiliser la fonction imdecode car elle provient de highgui.h qui est basé sur GTK 2, et dans mon projet j'utilise GTK 3.

Alors, comment puis-je afficher les données du tampon? Existe-t-il un moyen de décoder l'image jpeg autre que imdecode en opencv, si tel est le problème. Je ne veux pas vraiment avoir à reconstruire l'opencv avec Qt ...

D'autres suggestions?

(Sous Linux)

23
Matekk

J'ai décompressé l'image JPEG en utilisant libjpeg en utilisant la procédure standard décrite dans documentation de l'API libjpeg sous 'Détails de décompression'.

Après avoir décompressé les données, vous pouvez les utiliser pour construire le cv::Mat. Remarquez que l'image décompressée est au format RVB, alors que openCV utilise un format BGR, donc une opération cvtColor() au format CV_RGB2BGR Est nécessaire.

4
Matekk

J'ai vu de nombreuses réponses à cette question sur le net disant que vous devriez appeler libjpeg directement et contourner la routine imread () d'OpenCV.

Ce n'est PAS nécessaire! Vous pouvez utiliser imdecode () pour décoder un tampon d'image brut de la mémoire. La façon de le faire n'est PAS intuitive et n'est pas suffisamment documentée pour aider les gens qui essaient de le faire pour la première fois.

Si vous avez un pointeur/taille pour vos données de fichier brutes (fread () directement à partir des fichiers .jpg, .png, .tif, etc ...

int    nSize = ...       // Size of buffer
uchar* pcBuffer = ...    // Raw buffer data


// Create a Size(1, nSize) Mat object of 8-bit, single-byte elements
Mat rawData( 1, nSize, CV_8UC1, (void*)pcBuffer );

Mat decodedImage  =  imdecode( rawData /*, flags */ );
if ( decodedImage.data == NULL )   
{
    // Error reading raw image data
}

C'est tout!

J'espère que cela aidera quelqu'un à l'avenir.

46
Jeff Reeder