您的位置:首页 > 运维架构

arm摄像头获取jpeg图像后,从内存中解压jpeg图像,并用openCV处理

2012-04-11 17:31 417 查看
目标板:GM8126
OpenCV1.0
由于8126板子获取的图像为jpg格式,jpg格式在内存中有编码,在处理时候必须将内存的jpg图像数据保存到本地磁盘操作。
由于交叉编译的opencv1.0中cvLoadImage()不能载入jpg格式的图像,因此需要对内存中的jpg图像数据进行解码。为了能使
8126获取的图像被opencv处理,同时加快处理速度,这里介绍如何将内存中的jpg数据进行解码后转化为IplImage格式。
首先下载jpeg-6b的src文件:jpegsrc.v6b.tar.gz
解压后修改里面的函数:
1、libjpeg.h
1)、在“ #define jpeg_stdio_src jStdSrc ” 下面增加
“ #define jpeg_stdio_mem_src jMemSrc ”
2)、在“ EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); ” 下面添加:
“ EXTERN(void) jpeg_stdio_mem_src JPP((j_decompress_ptr cinfo, char * indata, int nSize)); ”
2、jdatasrc.c
1)、 在 “my_source_mgr” 结构体定义中增加变量: 
char * indata; /* memory source stream */
int nInOffset; 
int nSize;
2)、增加函数: 
METHODDEF(boolean)
fill_input_mem_buffer (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
size_t nbytes;

//nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
nbytes = src->nSize-src->nInOffset;

if (nbytes>INPUT_BUF_SIZE) nbytes = INPUT_BUF_SIZE;
if (nbytes <= 0) 
{
if (src->start_of_file) /* Treat empty input file as fatal error */
ERREXIT(cinfo, JERR_INPUT_EMPTY);
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */
src->buffer[0] = (JOCTET) 0xFF;
src->buffer[1] = (JOCTET) JPEG_EOI;
nbytes = 2;
}
memcpy(src->buffer,src->indata+src->nInOffset,nbytes);
src->nInOffset+=nbytes;

src->pub.next_input_byte = src->buffer;
src->pub.bytes_in_buffer = nbytes;
src->start_of_file = FALSE;

return TRUE;
}

3)、增加函数:
METHODDEF(void)
skip_input_mem_data (j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) 
{
while (num_bytes > (long) src->pub.bytes_in_buffer)
{
num_bytes -= (long) src->pub.bytes_in_buffer;
(void) fill_input_mem_buffer(cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes;
}
}

4)、增加 ” jpeg_stdio_mem_src “ 的实现函数:
/***************** add by lixintao, 2012.4.10 ***************************/
/************* memory src object manager functiont **********************/
GLOBAL(void)
jpeg_stdio_mem_src (j_decompress_ptr cinfo, char * indata, int nSize)
{
my_src_ptr src;

/* The source object and input buffer are made permanent so that a series
* of JPEG images can be read from the memory by calling mem_jpeg_stdio_src
* only before the first one. (If we discarded the buffer at the end of
* one image, we'd likely lose the start of the next one.)
* This makes it unsafe to use this manager and a different source
* manager serially with the same JPEG object. Caveat programmer.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_source_mgr));
src = (my_src_ptr) cinfo->src;
src->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
INPUT_BUF_SIZE * SIZEOF(JOCTET));
}

src = (my_src_ptr) cinfo->src;
src->pub.init_source = init_source;
src->pub.fill_input_buffer = fill_input_mem_buffer;
src->pub.skip_input_data = skip_input_mem_data;
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->pub.term_source = term_source;
src->indata = indata;
src->nSize = nSize;
src->nInOffset = 0;
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
src->pub.next_input_byte = NULL; /* until buffer loaded */

}
修改完源码后,重新交叉编译libjpeg库。

下面提供内存中jpg图像数据转化为IplImage的函数代码:
/* author: lixintao data: 2012.4.11
* function name: Jpeg2Ipl
* arguments:
* jpegData: jpeg image data in the memory.
* jpegSize: jpeg image data size in the memory.
* return:
* IplImage*: the pointer to the IplImage struct
* function:
* this function convert the jpg image data in the memory to
* IplImage struct for opencv processing.
* */
IplImage* Jpeg2Ipl(char *jpegData, int jpegSize)
{
IplImage *_pImg = 0;

struct jpeg_error_mgr jerr;
struct jpeg_decompress_struct cinfo;

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);

jpeg_stdio_mem_src(&cinfo, jpegData, jpegSize);

jpeg_read_header(&cinfo, TRUE);

jpeg_start_decompress(&cinfo);

int nRowSize = cinfo.output_width * cinfo.output_components;
int w =cinfo.output_width;
int h =cinfo.output_height;

char *bmpBuffer = (char*)malloc(h*w*3);
JSAMPARRAY pBuffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, nRowSize, 1);

while(cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, pBuffer, 1);

int start=nRowSize*(cinfo.output_scanline-1);
for(int i=0;i<nRowSize;i++)
{
bmpBuffer[start+i]=pBuffer[0][i];
}
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);

_pImg = cvCreateImage(cvSize(w,h),8,3);
for (h=0; h<_pImg->height; h++)
{
for (w=0; w<_pImg->widthStep; w+=3)
{
*(_pImg->imageData+h*_pImg->widthStep+w+0)=*(bmpBuffer+h*_pImg->widthStep+w+2);
*(_pImg->imageData+h*_pImg->widthStep+w+1)=*(bmpBuffer+h*_pImg->widthStep+w+1);
*(_pImg->imageData+h*_pImg->widthStep+w+2)=*(bmpBuffer+h*_pImg->widthStep+w+0);
}
}

free(bmpBuffer);

bmpBuffer=NULL;
return _pImg;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐