你好,游客 登录 注册 搜索
背景:
阅读新闻

使用OpenCV实现WebCam摄像头保存JPEG图片 - Augusdi的专栏

[日期:2013-04-06] 来源:  作者: [字体: ]

    由于在OpenCV1.0中只提供了从硬盘打开JPEG图像进行解码,有些时候如果JPEG的图像数据是从内存载入的,就无法使用这些曾经很方便高效的接口。为了实现这个目的,我们通过修改OpenCV1.0源码,在其源码包中添加函数,实现把jpeg数据从内存复制到IplImage结构中,这为我们进行相应处理会方便很多,实现过程如下:

    修改源码包目录下的otherlibs/highgui目录下的如下源码文件:

    1、highgui.h,在其中添加函数的声明:

       CVAPI(IplImage*) cvJpeg2Ipl(char *jpegData, int jpegSize);

    2、grfmt_jpeg.cpp,在其中添加函数的实现:

       1)、添加头文件:

            #include "jpeglib.h"

       2)、添加源代码:
            

void mem_init_source(j_decompress_ptr cinfo)
            {
                //  cinfo->src->bytes_in_buffer = g_buf_len;
                //  cinfo->src->next_input_byte = (unsigned char*)g_buf;
            }
            boolean mem_fill_input_buffer(j_decompress_ptr cinfo)
           {
                 return true;
           }
           void mem_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
          {
                cinfo->src->bytes_in_buffer -= num_bytes;
                cinfo->src->next_input_byte += num_bytes;
          }
          boolean mem_resync_to_restart(j_decompress_ptr cinfo, int desired)
          {
                 return jpeg_resync_to_restart(cinfo, desired);
          }
         void mem_term_source(j_decompress_ptr cinfo)
         {
         }
         // @jpegData: 内存中的JPEG图像数据流

         // @jpegSize:数据流大小
         CV_IMPL IplImage*
         cvJpeg2Ipl(char *jpegData, int jpegSize)
        {
             IplImage *_pImg = 0;
 
             jpeg_source_mgr jmgr;
             struct jpeg_error_mgr jerr;
             struct jpeg_decompress_struct cinfo;
 
             cinfo.err = jpeg_std_error(&jerr);
             jpeg_create_decompress(&cinfo);
 
             jmgr.init_source = mem_init_source;
             jmgr.fill_input_buffer = mem_fill_input_buffer;
             jmgr.skip_input_data = mem_skip_input_data;
             jmgr.resync_to_restart = mem_resync_to_restart;
             jmgr.term_source = mem_term_source;
             jmgr.next_input_byte = (unsigned char*)jpegData;
             jmgr.bytes_in_buffer = jpegSize; 
 
             cinfo.src = &jmgr;
             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=new char[h*w*3];
            JSAMPARRAY pBuffer = (*cinfo.mem->alloc_sarray)
            ((j_common_ptr) &cinfo, 1, 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);
             }
         }

 

         delete bmpBuffer;

         bmpBuffer=NULL;
         return _pImg;
     }


     修改完成后得新编译安装OpenCV包即可,接下来就可以在程序中包含highgui.h头文件,然后就可以使用cvJpeg2Ipl函数了。

     参考资料:http://blog.csdn.net/xfeng_12/archive/2009/11/10/4794583.aspx





收藏 推荐 打印 | 录入:admin | 阅读:
相关新闻