将从IP摄像机接收的JPEG流解码为C ++中的RGB图像

时间:2017-06-05 16:06:29

标签: c++ jpeg decode

我有一台IP摄像机,可以在UDP / RTP中传输JPEG压缩数据。我使用Boost Asio来接收数据。我知道我已正确收到数据,因为我使用Wireshark检查了每个数据包的头信息。

#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));

  }

}

我收到每个数据包的总共1452个字节,其中前20个字节是RTP头(12个字节),后跟JPEG头(8个字节)。剩余的1432个字节包含有效负载。假设每帧由145个数据包组成(frm_pckts = 145)。在对数据包进行排序后,我将它们存储在一个缓冲区中,如下所示:

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

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

如果我将此缓冲区复制到OpenCV Mat中并显示它将显示垃圾值。我也试过

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

但它也没有用。我查看了本网站上可以找到的所有可能的解决方案,但它们都没有为我工作。有没有我可以用来将这个缓冲区传递给它的一个函数并检索JPEG帧的库?另外,为了解码帧,我是否应该在缓冲区中包含头字节?如果是哪个标题? JPEG标题,RTP标题或两者兼而有之?

我非常感谢任何有用的解决方案或建议。

1 个答案:

答案 0 :(得分:0)

JPEG over RTP标头称为主标头,长度仅为8个字节。因此,应该创建JFIF标头,以便能够解码JPEG压缩数据。可以使用“RFC 2435”格式完成JFIF标头创建。一切都在那里解释了。创建JFIF标头后,应将其添加到压缩数据之前,然后传递给uncompressedFrame = cv :: imdecode(compressedImage,1)或任何其他JPEG解码器以检索未压缩的帧。如果你遇到这样的问题,请通过(davar.daei@gmail.com)告诉我。我将非常乐意提供帮助。