2017-06-05 1 views
0

J'ai une caméra IP qui diffuse des données compressées JPEG en UDP/RTP. J'ai utilisé Boost Asio pour recevoir les données. Je sais que j'ai reçu les données correctement parce que j'ai vérifié les informations d'en-tête pour chaque paquet avec Wireshark.Décodage d'un flux JPEG reçu d'une caméra IP vers une image RVB en C++

#include <boost/asio.hpp> 

#define MAX_BYTES 1500 

using boost::asio::ip::udp; 

int main(){ 

    boost::asio::io_service io_service; 
    udp::socket socket(io_service , udp::endpoint(udp::v4(),50242)); 
    char data[MAX_BYTES]; 
    size_t bytes_received = 0; 

    while(true){ 

    bytes_received = socket.receive(boost::asio::buffer(data,MAX_BYTES)); 

    } 

} 

I reçoivent le total de 1452 octets pour chaque paquet, les 20 premiers octets qui sont en-tête RTP (12 octets), suivi par l'en-tête JPEG (8 octets). Les 1432 octets restants contiennent la charge utile. Disons que chaque image est composée de 145 paquets (frm_pckts = 145). Après le tri des paquets que je les stocke dans un tampon pour une seule image comme suit:

unsigned char* buffer = (unsigned char*) malloc(frm_pckts * 1432 * sizeof(unsigned char); 

memcpy(&buffer[packet_index*1432] , &data[20], 1432); 

si je copie ce tampon dans un OpenCV Mat et affichage qu'il affiche des valeurs de déchets. J'ai également essayé

cv::Mat img = cv::imdecode(frame, CV_LOAD_IMAGE_COLOR); 

mais cela n'a pas fonctionné non plus. J'ai regardé toutes les solutions possibles que j'ai pu trouver sur ce site mais aucun d'eux n'a fonctionné pour moi. Y at-il une bibliothèque que je pourrais utiliser pour passer ce tampon à l'une de ses fonctions et récupérer le cadre JPEG? Aussi, pour décoder le cadre, dois-je inclure les octets d'en-tête dans le tampon? Si oui quel en-tête? En-tête JPEG, en-tête RTP ou les deux?

J'apprécierais beaucoup des solutions ou des suggestions utiles.

+0

Comment triez-vous exactement les paquets? Cela pourrait être la racine de votre problème. –

+0

Vous devez inclure l'en-tête JPEG dans le tampon que vous passez à 'cv :: imdecode()'. Il doit être capable de savoir quel est le format de l'image, donc il a besoin de l'en-tête. Comme premier test que vous avez correctement reçu l'image, enregistrez-le dans un fichier et essayez d'ouvrir ce fichier avec n'importe quelle visionneuse JPEG. Comme un autre test, je suggère de construire un petit programme qui décode une image JPEG à partir d'un fichier disque en utilisant 'cv :: imdecode()' pour voir si vous utilisez l'API correctement. – zett42

+0

Merci pour vos réponses. Je ne pense pas qu'il y ait un problème de tri parce que je trie les paquets en fonction des horodatages et du numéro de séquence que je reçois de l'en-tête RTP. –

Répondre

0

L'en-tête JPEG over RTP est appelé l'en-tête principal et ne mesure que 8 octets. à partir de cela, l'en-tête JFIF doit être créé afin de pouvoir décoder les données compressées JPEG. La création d'en-tête JFIF peut être effectuée en utilisant le format "RFC 2435". Tout a été expliqué là-bas. Une fois l'en-tête JFIF créé, il doit être préfixé aux données compressées, puis transmis à uncompressedFrame = cv :: imdecode (compressedImage, 1) ou à tout autre décodeur JPEG pour récupérer la trame non compressée. Si vous rencontrez des problèmes comme celui-ci, s'il vous plaît laissez-moi savoir à ([email protected]) Je serai plus qu'heureux de vous aider.