libjpeg库的简单使用,rgb565与rgb888互转,以及色块的寻找

最近用的摄像头OV2640摄像头,支持RGB565、JPEG、YUV和YCbCr格式的输出,想要对采集的图像进行色块识别,这样一般需要用到RGB格式的输出会比较好处理,数字图像处理中常用的采用模型是RGB(红,绿,蓝)模型和HSV(色调,饱和度,亮度),RGB广泛应用于彩色监视器和彩色视频摄像机,我们平时的图片一般都是RGB模型。别人是RGB的LCD屏幕作为上位机,而我却没有LCD屏幕作为上位机,...
摘要由CSDN通过智能技术生成

最近用的摄像头OV2640摄像头,支持RGB565、JPEG、YUV和YCbCr格式的输出,想要对采集的图像进行色块识别,这样一般需要用到RGB格式的输出会比较好处理,数字图像处理中常用的采用模型是RGB(红,绿,蓝)模型和HSV(色调,饱和度,亮度),RGB广泛应用于彩色监视器和彩色视频摄像机,我们平时的图片一般都是RGB模型。别人是RGB的LCD屏幕作为上位机,而我却没有LCD屏幕作为上位机,输出JPEG我可以存为.jpg为后缀的文件,输出RGB565的数据不好将图片保存下来,存RGB格式一般存为bmp位图,就想着既然板子都是作为客户端采集图像传出来,在服务器端将JPEG的数据转换成RGB数据在做色块识别的处理,就了解到libjpeg这个库,libjpeg是一款功能强大的开源jpeg图像库工具软件,jpeg是一个国际图像压缩标准,图像的后缀一般为jpeg或者jpg,利用libjpeg可以读取jpeg图像数据,libjpeg库是用于编码数据为jpeg格式或者解码jpeg格式图片的常用库。

既然传出来的数据是JPEG,这里需要做的就是JPEG的解码,下面简单的说说libjpeg库的使用:

一、libjpeg库的简单使用

1、设置出错处理函数并初始化编解码结构对象

 在libjpeg库中,实现了默认错误处理函数,当错误发生时,比如如果内存不足(非常可能发生,后面会介绍)等,则默认错误处理函数将会调用exit函数结束整个进程,详细内容可以参考jerror.c文件。在C语言中没有C++的异常处理机制,但是提供了setjmp和longjmp机制来实现类似的功能,设置完出错处理就初始化编解码结构对象

编码:

 /*  Step 1: allocate and initialize JPEG compression object */

    cinfo.err = jpeg_std_error(&jerr);

    /*  Now we can initialize the JPEG compression object. */

jpeg_create_compress(&cinfo);

解码:

/*  We set up the normal JPEG error routines, then override error_exit. */

 cinfo.err = jpeg_std_error(&jerr);

/*  Now we can initialize the JPEG decompression object. */

jpeg_create_decompress(&cinfo);

2、初始化源数据

 在libjpeg库中仅仅提供了文件作为输入数据的接口,在example.c中代码如下:jpeg_stdio_src(&cinfo, infile);

3、读取jpeg文件的头信息

调用jpeg_read_header(&cinfo, TRUE)读取jpeg文件头信息,这个和初始化解码对象一样,是必须要调用的,是约定

    (void) jpeg_read_header(&cinfo, TRUE);

    /*  源信息 */

    printf("image_width = %d\n", cinfo.image_width);

    printf("image_height = %d\n", cinfo.image_height);

    printf("num_components = %d\n", cinfo.num_components);

4、设置解码参数

很多情况下,这步非常重要。比如设置输出格式,设置scale(缩放)等等功能都是在这一步设置。参数设置通过修改上步得到cinfo的值来实现。这里简单介绍一下一些常用的字段。out_color_space:输出的颜色格式,libjpeg定义如下:

typedef enum {  

    JCS_UNKNOWN,        /* error/unspecified */  

    JCS_GRAYSCALE,        /* monochrome */  

    JCS_RGB,        /* red/green/blue */  

    JCS_YCbCr,        /* Y/Cb/Cr (also known as YUV) */  

    JCS_CMYK,        /* C/M/Y/K */  

    JCS_YCCK,        /* Y/Cb/Cr/K */   

 } J_COLOR_SPACE;

不设置的话通常就是JCS_RGB,RGB888的格式,除此之外,还可以设置缩放大小等,scale_num,scale_denom:因为实际的显示设备千变万化,我们可能需要根据实际情况对输出数据进行一些缩放才能够显示。libjpeg支持对输出数据进行缩放(scale),这个变量就是用来设置缩放的参数。

mem:可以指定内存管理相关的内容,比如分配和释放内存,指定libjpeg可以使用的最大内存。默认情况下不同的平台下面都有一个libjpeg默认最大可用内存值,比如Android平台上面该值为10000000L(10M),请参考jmemxxxx.c文件中的DEFAULT_MAX_MEM,了解不同平台的默认最大内存值。通过修改mem->pub.max_memory_to_use的值,库的使用者可以自定义libjpeg可以使用的最大内存值。

5、开始解码

经过前面的参数设置,接着调用jpeg_start_decompress(&cinfo);开始解码。

6、对解码出来的数据做处理

    /*  Step 6: while (scan lines remain to be read) */

    /*            jpeg_read_scanlines(...); */


    while (cinfo.output_scanline < cinfo.output_height)

    {

        row_pointer[0] = & rdata[(cinfo.output_scanline)*cinfo.image_width*cinfo.num_components];

        jpeg_read_scanlines(&cinfo,row_pointer ,1);

        //(void) jpeg_read_scanlines(&cinfo, buffer, 1);

        /*  Assume put_scanline_someplace wants a pointer and sample count. */

        //put_scanline_someplace(buffer[0], row_stride);

    }

解码出来的数据是一行一行的,我这里读到rdata里面,这里根据个人需求改。

解码JPEG文件输出RGB888数据到out_buf

int read_JPEG_file (char * filename, unsigned char *out_buf,int size)

{

    struct jpeg_decompress_struct           cinfo;

    struct jpeg_error_mgr                   jerr;

    /*  More stuff */

    FILE                                    *infile;                /*  source file */

    int                                     row_stride;               /*  physical row width in output buffer */

    unsigned char                           *rdata;

    JSAMPROW                                row_pointer[1];

    int                                     image_size = 0 ;





    if ((infile = fopen(filename, "rb")) == NULL)

    {

        fprintf(stderr, "can't open %s\n", filename);

        return -1;

    }



    /*  Step 1: allocate and initialize JPEG decompression object */



    /*  We set up the normal JPEG error routines, then override error_exit. */

    cinfo.err = jpeg_std_error(&jerr);

    /*  Now we can initialize the JPEG decompression object. */

    jpeg_create_decompress(&cinfo);



    /*  Step 2: specify data source (eg, a file) */



    jpeg_stdio_src(&cinfo, infile);



    /*  Step 3: read file parameters with jpeg_read_header() */



    (void) jpeg_read_header(&cinfo, TRUE);

    /*  源信息 */

    printf("image_width = %d\n", cinfo.image_width);

    printf("image
  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: libjpeg是一个流行的JPEG图像压缩和解压缩,可以用于将JPEG图像转换为RGB888格式。 要使用libjpegJPEG图像转换为RGB888,首先需要安装libjpeg并包含相关的头文件。 使用以下步骤可以实现此功能: 1. 打开JPEG图像文件,使用libjpeg的函数`jpeg_stdio_src`。 2. 调用`jpeg_read_header`函数获取JPEG图像的头文件信息。 3. 设置解压缩参数,包括输出格式。在本例中,我们需要将JPEG图像解压缩为RGB888格式,因此可以使用`jpeg_set_decompress_parms`函数来设置输出格式。 4. 使用`jpeg_start_decompress`函数开始解压缩过程。 5. 创建一个指向放置解压缩后像素数据的缓冲区的指针。在本例中,我们需要将JPEG图像解压缩为RGB888格式,因此缓冲区的大小应为图像宽度乘以图像高度乘以3。 6. 使用`jpeg_read_scanlines`函数逐行读取JPEG图像的像素数据,存储在缓冲区中。 7. 解压缩完成后,调用`jpeg_finish_decompress`函数完成解压缩过程。 8. 将RGB888格式的像素数据存储在所需的格式中,例如,在C语言中,可以将像素数据存储在一个三维数组中。 9. 最后,使用`jpeg_destroy_decompress`函数销毁解压缩对象。 通过以上步骤,我们可以使用libjpegJPEG图像转换为RGB888格式。 需要注意的是,以上只是实现此功能的基本步骤,实际使用时还需要添加错误处理和其他必要的功能来确保程序的正确性和稳定性。 ### 回答2: libjpeg是一个非常常用的JPEG图像解码,它可以将JPEG图像解码为其他不同的格式,包括RGB888格式。下面是使用libjpegJPEG转换为RGB888的步骤: 1. 首先,需要安装libjpeg,并在代码中引入相关的头文件。 2. 创建一个jpeg_decompress_struct结构体对象,用于存储解码过程中的相关参数。 3. 调用jpeg_CreateDecompress函数初始化jpeg_decompress_struct对象。 4. 使用jpeg_stdio_src函数将源JPEG文件关联到jpeg_decompress_struct对象。 5. 调用jpeg_read_header函数读取JPEG文件的头部信息。 6. 设置解码参数,包括解码模式和输出格式。对于RGB888格式,可以通过设置jpeg_decompress_struct的输出颜色空间和输出全色彩标志来实现。 7. 调用jpeg_start_decompress函数开始解码过程。 8. 使用jpeg_read_scanlines函数逐行读取解码后的RGB像素数据。 9. 将得到的RGB像素数据存储到目标RGB888格式的缓冲区中。 10. 最后,调用jpeg_finish_decompress函数结束解码过程,并释放相关资源。 以上是使用libjpegJPEG图像转换为RGB888格式的简要步骤。具体的代码实现会更加复杂,需要进行各种错误处理和内存管理。但使用libjpeg可以方便地完成这一任务,而无需自己从头开始实现JPEG解码算法。 ### 回答3: libjpeg是一个经典的JPEG图像压缩与解压缩,可以用于将JPEG图像文件转换为RGB888格式。 使用libjpegJPEG图像转换为RGB888格式的过程如下: 首先,我们需要包含libjpeg的头文件,并声明所需的变量。JPEG图像的压缩信息将存储在jpeg_decompress_struct结构体中,而解压缩的输出数据将存储在jpeg_decompress_struct结构体的jd_output_components变量中。RGB888格式的数据需要通过指针指向一个unsigned char型的一维数组。 ``` #include <stdio.h> #include <jpeglib.h> int main() { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPARRAY buffer; unsigned char *rgbData; ... } ``` 接着,我们需要使用libjpeg提供的函数初始化并打开JPEG文件,进行解压缩准备工作。 ``` cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); FILE *infile = fopen("input.jpg", "rb"); if (!infile) { return 0; } jpeg_stdio_src(&cinfo, infile); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width * cinfo.output_components, 1); rgbData = malloc(cinfo.output_width * cinfo.output_height * cinfo.output_components); ``` 然后,我们需要使用libjpeg提供的函数逐行读取图像数据,并将其存储在我们之前声明的rgbData中。 ``` int row = 0; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, buffer, 1); memcpy(rgbData + row * cinfo.output_width * cinfo.output_components, buffer[0], cinfo.output_width * cinfo.output_components); row++; } ``` 最后,我们完成转换后需要进行一些清理工作,关闭文件,释放内存等。 ``` jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); free(rgbData); fclose(infile); ``` 通过以上步骤,我们就可以使用libjpegJPEG图像转换为RGB888格式,最终结果存储在rgbData数组中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值