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; }
相关文章推荐
- Linux下opencv通过V4L获取摄像头图像的底层源码icvRetrieveFrameCAM_V4L
- opencv 获取摄像头图像
- OpenCV入门六:OpenCV打开摄像头并对摄像头获取的每一帧图像进行Canny算子边缘化提取操作
- OpenCV ios 摄像头获取和磁盘读取的图像RGB顺序问题
- 【OpenCV图像处理入门学习教程一】OpenCV2 + 3的安装教程与VS2013的开发环境配置 + JPEG压缩源码分析与取反运算修改
- javacpp-opencv图像处理3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)
- opencv2-摄像头获取图像相关参数设置
- [Mo]OpenNI+OpenCV处理kinect深度图,获取手掌骨架图像
- javacpp-opencv图像处理3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)
- 使用Linux的V4L2读取摄像头数据+Opencv图像处理
- OpenCV 处理内存中的图像数据
- opencv 获取摄像头图像
- 关于图像采集卡采集到图像到内存后怎样用Opencv进行图像处理
- 使用OpenCV 实现多摄像头图像处理笔记(1):DirectShow的配置过程可能出现的问题
- opencv中如何利用mat来获取连续内存的图像区域,并改变形状
- 使用OpenCv获取摄像头图像并进行旋转操作
- 【IOS】OpenCV摄像头实时图像处理(灰度,二值化,轮廓检测)
- [Mo]OpenNI+OpenCV处理kinect深度图,获取手掌骨架图像
- matlab通过摄像头获取图像进行处理
- 图像处理之其他杂项(二)之 opencv vs中断内存等问题解决策略 不定时更新