Возьмите один кадр изображения из потока MJPEG

У меня есть IP-камера VideoSec и демон, работающий на встроенном контроллере 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. Итак, мне нужен способ получить только один кадр из потока mjpeg с помощью libcurl. OpenCV не вариант.


person Mel    schedule 20.04.2013    source источник


Ответы (1)


В M-JPEG изображения JPEG встраиваются без изменений и разделяются текстовыми разделителями с подзаголовками. Итак, распаковать JPEG очень просто:

  • вы находите первый / следующий подзаголовок / разделитель в теле ответа
  • вы находите значение Content-Length, если доступно
  • вы пропускаете до \ r \ n \ r \ n, чтобы найти начало данных JPEG
  • вы получаете данные JPEG, чтобы получить либо количество байтов Content-Length, либо, если длина недоступна, вы читаете, пока не получите следующий разделитель

В результате получаются данные в точности как файл / изображение / поток в формате JPEG.

person Roman R.    schedule 26.04.2013
comment
Я уже делал это с помощью Content-Length, используя сокет вместо curl, но этот метод правильный. - person Mel; 29.04.2013