Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

Camera常用格式MJPEG和jpeg-turbo库

$
0
0
作者: Sam (甄峰)  sam_code@hotmail.com

USB Camera在通过V4L2接口获取Camera数据时,有多种图像格式可选择。但最常用的却是YUV和MJPEG. 又因为YUV图片所占空间大,在超过640x480情况下,会超过USB数据传输带宽。 所以只能使用MJPEG. 

现在就谈谈MJPEG相关内容。

1. 视频压缩格式:
1.1:JPEG (Joint Photographic Experts Group)压缩技术是所有图像压缩技术的基础。 它适合静态图像的压缩,直接处理整幅画面,压缩倍数为20-80倍,分辨率没有选择的余地。在传输中,必须要等整个压缩档传输完成才可以解压,这就造成传输时间较长。它是帧内压缩。


1.2. MJPEG(Motion JPEG):
在JPEG基础上发展起来的动态图像压缩技术,也是帧内压缩,只单独的对某一帧进行压缩,而基本不考虑视频流中不同帧之间的变化。其压缩后的图像还可以任意剪切。
Motion JPEG, 即动态JPEG. 按一定帧数使用JPEG算法压缩视频信号,完成动态视频的压缩。MJPEG图像流的单元就是一帧一帧的JPEG画片。 因为每帧可以任意存取,所以MJPEG常用于视频编辑系统。

1.3. MPEG:
其实是一个标准。
其中MPEG-4. 它会使用帧间数据。压缩比很高。应用广泛。


2. libjpeg-turbo:
jpeg, Mjpeg的压缩和解压,比较耗费CPU。 所以就有了libjpeg-turbo库,它可以更快的压缩和解压jpeg数据。

因为是帧内压缩,所以可以对JPEG数据进行各种处理,如放大/缩小,翻转,剪切,镜像等。

2.1:  libjpeg-turbo 对JPEG的压缩和解压:
libjpeg-turbo提供压缩(Compress)和解压(Decompress)接口。
同时,它还有个概念----Transform.

2.1.1: 压缩:
给定RGB data. 把它压缩成指定jpeg文件。
A. 打开一个压缩实例:
 tjhandle tjInitCompress(void)

B. 把给定pixel,w,h pitch等信息的数据,压缩成jpeg(给定sample,质量)数据。
int tjCompress2(tjhandle handle, const unsigned char *srcBuf,
                          int width, int pitch, int height, int pixelFormat,
                          unsigned char **jpegBuf, unsigned long *jpegSize,
                          int jpegSubsamp, int jpegQual, int flags)

C.  销毁实例:
int tjDestroy(tjhandle handle)


2.1.2:解压:
把给定的JPEG数据,解压成RGB数据:
这个过程,只是简单的解压,或者仅仅是图片大小变化。

A. 打开一个解码实例
tjInstance = tjInitDecompress();

B. 通过读取到的jpeg数据,来分析文件头,获取图像信息(长宽,sample, colour信息等)
int tjDecompressHeader3(tjhandle handle,
                                  const unsigned char *jpegBuf,
                                  unsigned long jpegSize, int *width,
                                  int *height, int *jpegSubsamp,
                                  int *jpegColorspace)
jpegBuf是jpeg数据。

C. 解压到指定格式,指定长宽数据:
int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf,
                            unsigned long jpegSize, unsigned char *dstBuf,
                            int width, int pitch, int height, int pixelFormat,
                            int flags)
width, height: 目标图像长宽。
pixelFormat: 目标图像格式, enum TJPF 中定义,如RGBX。

此时,dstBuf中的内容,就是解压过的,指定大小,深度,和图像格式的图片数据了。

如果指定为RGBX,则直接存文件即为BMP文件。

D. 销毁实例:
 int tjDestroy(tjhandle handle)

2.1.3:Transform:
Transform是干什么呢,Sam觉得是因为要实质修改JPEG数据,重新排列。 比如剪切,翻转,镜像。这些动作叫做Transform.

A. 打开一个transform实例:
tjhandle tjInitTransform(void)


B. Transform转换:

 tjtransform xform;  //指定transform的参数,如裁剪区域
想要裁剪:
xform.r.x = iX; //左上角位置
xform.r.y = iY;
xform.r.h , xform.r.w  //区域高度。
xform.options |= TJXOPT_CROP;   //指定要剪切。


int tjTransform(tjhandle handle, const unsigned char *jpegBuf,
                          unsigned long jpegSize, int n,
                          unsigned char **dstBufs, unsigned long *dstSizes,
                          tjtransform *t, int flags)

dstBufs中保存这transform后的数据。

C. 可选: 获取新的jpeg数据信息:
DLLEXPORT int tjDecompressHeader3(tjhandle handle,
                                  const unsigned char *jpegBuf,
                                  unsigned long jpegSize, int *width,
                                  int *height, int *jpegSubsamp,
                                  int *jpegColorspace)

D. 后续可以随意处理jpeg数据了。如解压。
E. 销毁:
int tjDestroy(tjhandle handle)



2.2: libjpeg-turbo对图像文件的处理:
unsigned char *tjLoadImage(const char *filename, int *width,
                                     int align, int *height, int *pixelFormat,
                                     int flags)


int tjSaveImage(const char *filename, unsigned char *buffer,
                          int width, int pitch, int height, int pixelFormat,
                          int flags)



2.3:获取放大缩小factor:
libjpet-turbo并不可以随意比例放大缩小,而是指定了一系列(16个)比例系数。
可以先获取这个列表:

scalingFactors = tjGetScalingFactors(&numScalingFactors);
if(scalingFactors == NULL)
{
printf("\nGet Scaling Factor Error.\n");
return -1;
}
printf("\nThere are [%d] ScalingFactors\n", numScalingFactors);
for(int i = 0; i < numScalingFactors; i++)
{
printf("\t Numerator/Denominator is:[%d/%d]\n", scalingFactors[i].num, scalingFactors[i].denom);
}

此时就可以得到turbo-jpeg给定的Scaling Factor.










 

Viewing all articles
Browse latest Browse all 158

Trending Articles