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.
Comment triez-vous exactement les paquets? Cela pourrait être la racine de votre problème. –
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
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. –