【问题标题】:Grab one image frame from MJPEG stream从 MJPEG 流中抓取一帧图像
【发布时间】:2013-04-20 10:26:51
【问题描述】:

我有 VideoSec IP 摄像头,以及在嵌入式 linux NPE 控制器上运行的守护程序。守护进程需要从 IP 摄像头获取图像,该部分是使用 libcurl 以标准方式实现的,并且使用轴摄像头工作得很好:

static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
     size_t written = fwrite(ptr, size, nmemb, stream);
     return written;
}

void refreshCameraImage(char *target, char *url)
{
     CURL *image;
     CURLcode imgresult;
     FILE *fp;

     image = curl_easy_init();

     if (image)
     {
          fp = fopen(target, "wb");
          if(fp == NULL)
          printf("\nFile cannot be opened");


          curl_easy_setopt(image, CURLOPT_URL, url);
          curl_easy_setopt(image, CURLOPT_WRITEFUNCTION, NULL);
          curl_easy_setopt(image, CURLOPT_WRITEDATA, fp);

          imgresult = curl_easy_perform(image);
          if( imgresult )
          {
               printf("\nCannot grab the image!");
          }
     }
     curl_easy_cleanup(image);
     fclose(fp);
}

VideoSec 摄像头的问题是我无法定义任何 jpeg 流,只能定义 MJPEG。 因此,我需要一种使用 libcurl 从 mjpeg 流中仅抓取一帧的方法。 OpenCV 不是一个选项。

【问题讨论】:

    标签: c video libcurl ip-camera mjpeg


    【解决方案1】:

    在 M-JPEG 中,JPEG 图像被完整嵌入并由带有子标题的文本分隔符分隔。所以提取JPEG是一件容易的事:

    • 您在响应正文中找到第一个/下一个子标题/分隔符
    • 您可以找到 Content-Length 值(如果有)
    • 您跳到 \r\n\r\n 以定位 JPEG 数据的开头
    • 您接收 JPEG 数据以获取 Content-Length 字节数,或者如果长度不可用,则读取直到获得下一个分隔符

    生成的数据正是 JPEG 文件/图像/流。

    【讨论】:

    • 我已经在 Content-Length 的帮助下做到了这一点,使用的是 socket 而不是 curl,但是这个方法是对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多