Italiano - English

Lossless video codec per image processing

Translation for this document is not available or is not complete,
if you are intrested to receive information please write to

Working as vision systems integrator usually you will have need to acquire and save great numbers of fames or video sequence on field, in order to perform a later processing or studies. In this cases it’s vital to store the image “as is” without alteration. This may be is not a problem if you use raw image format like bmp or xpm but you can’t use JPG/PNG or DiVx/MPEGn because image/video compression forma are quality lossy. A good solution is to use Lossless image format like JPG2000 or Lagarith lossless codec to have a good compression without loosing information.

This page shows some lossless codec, how to install and use it with OpenCV image library

Scegliere il codec lossless

Dato che per definizione un codec lossless garantisce compressione a perdita nulla i parametri rilevanti nella scelta di un codec lossless sono

  1. Il formato delle immagini accettate
  2. Il rapporto di compressione offerto
  3. Le prestazioni ovvero la velocità di compressione/decompressione

Sicuramente il punto di partenza per valutare e scegliere un codec lossless è un'ottima pubblicazione reperibile a questo indirizzo: Lossless Video Codecs Comparison ‘2007 (http://compression.ru/video/codec_comparison/lossless_codecs_2007_en.html)

Nella pubblicazione vengono eseguiti numerosi test sui diversi codec lossless disponibili (al 2007) utilizzando differenti stream in ingresso. Vi si possono trovare numerosissimi grafici che mostrano con chiarezza i risultati. Riassumendo si puo' affermare che

  • Quasi tutti i codec accettano immagini in formato RGB24 e YV2/12
  • La risposta di un codec dipende dal tipo di stream in ingresso (dinamico, statico, verticale ecc...)
  • I codec lossless offrono un rapporto di compressione variabile da 2 a 3. La variabilità dipende dal codec utilizzato e dal tipo stream.
  • Sul piano delle prestazioni (4CIF frame al secondo) si misurano notevoli differenze tra i vari codec utilizzati. Il tipo di stream influisce sulle prestazioni in maniera meno significativa rispetto a quanto accade per il rapporto di compressione.

In estrema sintesi l'articolo citato conclude che

  • Il codec Lagarith offre un elevato rapporto di compressione (circa 2.8) ed elevate prestazioni.
  • Il Codec HuffYuv offre le prestazioni leggermente più elevate di Lagarith
  • Il codec FFV1 offre un rapporto di compressione superiore (minore di 3.3) con prestazioni medie
  • Il codec YULS il rapporto di compressione piu' elevato (circa 3.3) con prestazioni 10 volte inferiori a FFV1 e 15 volte inferiori a Lagarith

I valori possono cambiare in funzione del formato di immagine (RGB, YUY2, YV12) e del tipo di stream in ingresso ma la relazione tra i codec non cambia in modo significativo.

In conclusione, la scelta di PkLab è che, a meno di esigenze molto molto particolari in cui sono richieste compressione o velocità elevatissima, il codec Lagarith è la scelta ideale per la totalità delle applicazioni offrendo contemporaneamente prestazioni e compressioni vicine al massimo.

complimenti a l'autore di Lagrith, Ben Greenwood, che oltretutto distribuisce il codec completo di sorgenti con licenza GPL.

Link di riferimento

Installazione dei codec

L'installazione dei codec varia. Esistono pacchetti di codec, come ad esempio K-Lite Codec Pack (http://www.codecguide.com/ solo la versione Mega contiene tutti i codec lossless) che dispongono di un setup semplificato.

Anche Lagarith dispone di un setup semplificato.

Utilizzo dei codec (lossless e non) per creare video con OpenCV

Le librerie OpenCV dispongono di un set limitato di funzioni per la creazione di video, e per l'utilizzo dei codec in lettura/scrittura utilizza le librerie FFMPEG che normalmente sono linkate staticamente nella libreria HighGui.dll.

Benchè limitate, le funzioni video di OpenCV permettono di utilizzare molti dei codec disponibili, che naturalmente devono essere precedentemente installati sul calcolatore in uso.

Creare un file video con OpenCV 2.2

 
#include "opencv2/opencv.hpp"
 
int    codec      = CV_FOURCC('L', 'A', 'G', 'S'); //use this for lagarith lossless codec
//int    codec      = CV_FOURCC('F', 'F', 'V', '1'); //use this for FFV1 lossless codec
//int    codec      = CV_FOURCC('X', 'V', 'I', 'D'); //use this for XVID codec
//int    codec      = CV_FOURCC('F', 'F', 'D', 'S'); //use this for DirectX DirectShow encoding settings
//int    codec      = -1;                            //use this for codec prompt while creating file
 
char   fname[]    = "Test.avi";
double fps        = 25;
int    img_width  = 2048;
int    img_height = 300;
 
cv::VideoWriter  m_videoOut;
cv::Mat frameGray,frameRgb;
 
frameGray = cv::Mat( cv::Size(img_width,img_height) , CV_8UC1 );
frameRgb  = cv::Mat( cv::Size(img_width,img_height) , CV_8UC3 );
 
//Close video file if it's opened
if (m_videoOut.isOpened() )
{
  m_videoOut.~VideoWriter(); 
}
 
//create the video file 
m_videoOut.open(
  fname,                           // filename
  codec,                           // required codec for encoding
  fps,                             // encoding frames per second
  cv::Size(img_width,img_height) , // frame size for all video
  1                                // output frame format: 1=COLOR(RGB) 0=GRAY
);
 
if (!m_videoOut.isOpened() )
{
  cerr << "unable to create the video file: " << fname;
  return;
}
 
//the video file is ready to accept frames into stream
E' importante sottolineare che è necessario creare il video stream a colori perchè la maggiorparte dei codec non accetta immagini gray come input.

Aggiunta di frame ad un video

Inserire un frame in coda allo stream video è molto semplice. Basta chiamare il metodo write. Siccome lo stream video è a colori è necessario convertire l'eventuale immagine GRAY in RGB prima di scrivere il frame nel video.

 
cv::cvtColor(frameGray,frameRgb,CV_GRAY2RGB,3);
m_videoOut.write(frameRgb);
 

Naturalmente il frame deve avere le stesse dimensione di larghezza e altezza dello stream video.

Chiusura di un file video

L'oggetto VideoWriter non dispone di un metodo esplicito per la chiusura di un file ed è necessario chiamare il distruttore di classe. Nota che comunque lo stesso oggetto può essere riutilizzato eseguendo un nuovo open.

 
//Close video file if it's opened
if (m_videoOut.isOpened() )
{
  m_videoOut.~VideoWriter(); 
}
Vote this page:

0 Comments:

Leave your comment:

Note:
  • Your email email will not be visible or used in any way, and is not required
  • Please keep comments relevant
  • Any content deemed inappropriate or offensive may be edited and/or deleted
  • HTML code is not allowed. Please use BBCode to format your text
    [b]bold[/b], [u]underline[/u], [i]italic[/i], [code]code[/code]
The coding examples presented here are for illustration purposes only. The author takes no responsibility for end-user use
This work is property of Pk Lab. You can use it for free but you must retain author's copyright.