在网络机器人的监控中,尤其是在窄带网络中,如果采用原始的JPEG图像压缩格式,其压缩比受到局限,不能大幅度压缩图像,而且还不具有码流任意截断任意显示、ROI编码以及渐近显示的功能,其应用受到局限!一般来说一副320*240*24的图像大约为250K左右,在JPEG压缩比为10:1左右的情况下,大约需要传输20K左右的图像,如果每秒钟传输3-5副图片,其带宽要有60K-100K为图像传输所占用。在目前的窄带网络中(尤其CDMA),其应用受到限制!
鉴于此,我们采用压缩比大幅度提高的JPEG2000。该标准的制定为解决网络图像传输的瓶颈带来了曙光!其压缩比在同等图像质量的情况下比JPEG提高30%,并且具有许多优良的性质:渐近传输、任意截断显示、ROI等。为了能够利用它,采用了它的C语言包--Jasper。该包的压缩效率不是很好,许多地方需要改良!当然如果可能还是采用硬件压缩的方式,具论文介绍韩国已经能够实现每秒钟30帧的压缩效率(赞叹!)。
我在此只是对其包进行接口的改善,重点是我采集的图像连续的内存流,然后经过压缩成连续的内存流传输到客户端,在客户端对连续的帧流进行解码。达到连续的视频效果!
具体的改写为在jas_image_t.c中添加一个把内存图像buffer转换成jas_image_t结构,然后经过压缩成jas_stream_t流传输出去:
/***********jas_image_t.c***************/
/*************************************************\
把内存的数据写入buff中(采用的图像为320*240*24)
\*************************************************/
jas_image_t *mem_inv(char *buf)
{
jas_image_t *image;
uint_fast16_t cmptno;
jas_image_cmptparm_t cmptparms[3];
jas_image_cmptparm_t *cmptparm;
uint_fast16_t numcmpts;
// long n;
/* Get the number of components. */
numcmpts = 3;
for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
++cmptparm) {
cmptparm->tlx = 0;
cmptparm->tly = 0;
cmptparm->hstep = 1;
cmptparm->vstep = 1;
cmptparm->width = 320;
cmptparm->height =240;
cmptparm->prec = 8;
cmptparm->sgnd = false;
}
/* Create image object. */
if (!(image = jas_image_create(numcmpts, cmptparms,
JAS_CLRSPC_UNKNOWN))) {
return 0;
}
if (numcmpts == 3) {
jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
jas_image_setcmpttype(image, 0,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
jas_image_setcmpttype(image, 1,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
jas_image_setcmpttype(image, 2,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
} else {
jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
jas_image_setcmpttype(image, 0,
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
}
/* Read the bitmap data. */
if (mem_getdata(buf, image)) {
jas_image_destroy(image);
return 0;
}
return image;
}
static int mem_getdata(char *buf,jas_image_t *image)
{
int i;
int j;
int y;
jas_matrix_t *cmpts[3];
int numpad;
int red;
int grn;
int blu;
int ret;
int numcmpts;
int cmptno;
// int ind;
// bmp_palent_t *palent;
// int mxind;
int haspal;
numcmpts = 3;
haspal = 0;
ret = 0;
for (i = 0; i < numcmpts; ++i) {
cmpts[i] = 0;
}
/* Create temporary matrices to hold component data. */
for (i = 0; i < numcmpts; ++i) {
if (!(cmpts[i] = jas_matrix_create(1, 320))) {
ret = -1;
goto data_done;
}
}
/* Calculate number of padding bytes per row每行 of image data. */
numpad = (numcmpts * 320) % 4;
if (numpad) {
numpad = 4 - numpad;
}
for (i = 0; i < 240; ++i) {
for (j = 0; j < 320; ++j) {
red=*(buf++);
grn=*(buf++);
blu=*(buf++);
if (numcmpts == 3) {
jas_matrix_setv(cmpts[0], j, red);
jas_matrix_setv(cmpts[1], j, grn);
jas_matrix_setv(cmpts[2], j, blu);
}
}
for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
y =240 - 1 - i;
if (jas_image_writecmpt(image, cmptno, 0, y, 320,
1, cmpts[cmptno])) {
ret = -1;
goto data_done;
}
}
}
data_done:
/* Destroy the temporary matrices. */
for (i = 0; i < numcmpts; ++i) {
if (cmpts[i]) {
jas_matrix_destroy(cmpts[i]);
}
}
return ret;
}
另外为了在应用程序中引用,还需要在jas_image.h中添加接口:
/**open a memory buffer stream and invert a image*/
jas_image_t *mem_inv(char *buf);
如此完成了该库的修改,可以得到传输需要的buffer数据:
压缩的图像流:out->bufstart_ 大小:out->rwcnt_(受内存管理的限制8092)