免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 11019 | 回复: 11
打印 上一主题 下一主题

[应用] 嵌入式linux下RGB数据转换成JPG格式图片花屏问题求助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-15 17:23 |只看该作者 |倒序浏览
本帖最后由 wcy0556 于 2010-08-15 17:25 编辑

这几天小弟正在做一个有关图片格式转换的课题,具体是这样的:将CMOS摄像头采集到的RGB565格式数据转换成JPG格式图片,以便在QT界面上显示。我的思路是这样:将RGB565->RGB888->JPG,但是最后生成的.jpg图片出现了花屏现象,百思不得其解,希望各位大侠帮帮忙!!
我的源码如下:
/*main.cpp*/
#include <QApplication>
#include "camtest1.cpp"
#define RGB565_RED 0xF800  /*R*/
#define RGB565_RED_BEST 0x3800
#define RGB565_GREEN 0x07E0 /*G*/
#define RGB565_GREEN_BEST 0x0060
#define RGB565_BLUE 0x001F /*B*/
#define RGB565_BLUE_BEST 0x0007
extern "C"{
#include <jpeglib.h>
#include <jerror.h>
}
#include <stdio.h>
int main(int argc, char **argv)
{
FILE* jpgFile;
unsigned short data[20480];  
unsigned short *pdata=data;
unsigned short j=0;
unsigned short tmp1=0;
unsigned short tmp2=0;   
unsigned short tmp3=0;
unsigned char buff[61440];/*存放RGB565->RGB888的三个数据*/
QApplication app(argc,argv);
    try {                            /*try中包含抛出异常的模块*/
                TFrameBuffer FrameBuffer;/*建立帧缓存对象*/
                TVideo Video;
                Video.FetchPicture();/*采集图像数据*/
                FrameBuffer.DrawRect(Video);/*显示图像*/
                        /*for(int i=0;i<20;i++)
                        std::cerr << "the Video.Addr is"<< (int)(*(Video.Addr+i)) << std::endl;*/
                for(unsigned short i=0;i<40960;i++)/*将摄像头输出的RGB565字节流转化为字流,便于下面的的格式转换*/
                    {
                       tmp1 = (unsigned short)(*(Video.Addr+i));
                       tmp1&=0x00FF;
                       /*std::cerr << "tmp1=" << tmp1 << std::endl;*/
                       tmp1 = (tmp1<<;
                       /*std::cerr << "tmp1<<8=" << tmp1 << std::endl;*/
                       tmp2 = (unsigned short)(*(Video.Addr+i+1));
                       tmp2&=0x00FF;
                       /*std::cerr << "tmp2=" << tmp2 << std::endl;*/
                                 data[j] = tmp1+tmp2;
                                 /*std::cerr << data[j] << std::endl;*/
                                 i++;
                                 j++;
                                        if(j==20479)
                                         {
                                           j=0;
                                           std::cerr << " 16 is OK" << std::endl;
                                         }
                                 }
                         for(unsigned short i=0;i<20480;i++)/*将RGB565数据转化为RGB888数据*/
                            {
                              tmp3 = *pdata;
                              buff[i*3+0]=(tmp3 & RGB565_RED)>>11;
                              buff[i*3+0]<<=3;
                              /*buff[i*3+0]|=((tmp3 & RGB565_RED_BEST)>>11);*//*R4R3R2R1R0R2R1R0*/
                              buff[i*3+1]=(tmp3 & RGB565_GREEN)>>5;
                              buff[i*3+1]<<=2;
                              /*buff[i*3+1]|=((tmp3 & RGB565_GREEN_BEST)>>5);*//*G5G4G3G2G1G0G1G0*/
                              buff[i*3+2]=(tmp3 & RGB565_BLUE);
                              buff[i*3+2]<<=3;
                              /*buff[i*3+2]|=(tmp3 & RGB565_BLUE_BEST);*//*B4B3B2B1B0B2B1B0*/
                             /* bmp24=(buff[i*3+0]<<16)+(buff[i*3+1]<<+buff[i*3+2];*//*数据存入RGB888数组*/
                              pdata++;
                                 if(i==20479)
                                   {
                                    pdata=data;
                                    std::cerr << " RGB888 is OK" << std::endl;
                              
                                   }
                            }
                       /*调用JEPG库,将图片压缩成JPEG格式*/
                       struct jpeg_compress_struct jcs;
                       struct jpeg_error_mgr jem;
                       jcs.err = jpeg_std_error(&jem);
                       jpeg_create_compress(&jcs);                           
                       jpgFile=fopen("camera.jpg","wb";
                       if (jpgFile==NULL)
                       {
                       free(buff);
                       return 0;
                       }
                       jpeg_stdio_dest(&jcs, jpgFile);
                     
                       jcs.image_width = 160;      /*为图的宽和高,单位为像素*/
                       jcs.image_height = 128;
                       jcs.input_components = 3;     /*色彩通道数 在此为1,表示灰度图, 如果是彩色位图,则为3*/
                       jcs.in_color_space = JCS_RGB; /*色彩空间 ,JCS_GRAYSCALE表示灰度图, JCS_RGB 表示彩色图像*/
                       jpeg_set_defaults(&jcs);
                       jpeg_set_quality(&jcs, 80, true);/*压缩质量*/
                    /*上面的工作准备完成后,就可以压缩了,压缩过程非常简单,首先调用 jpeg_start_compress,
                                       然后可以对每一行进行压缩,也可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,如下:*/
                       jpeg_start_compress(&jcs, true);
                       JSAMPROW row_pointer[1]; /*一行位图*/
                       int row_stride;          /*每一行的字节数*/
                       row_stride = jcs.image_width*3;  /*如果不是索引图,此处需要乘以3*/ /*480*/
                     
                       /*对每一行进行压缩*/
                        while(jcs.next_scanline <12
                        {
                        row_pointer[0] = & buff[jcs.next_scanline * row_stride];
                        jpeg_write_scanlines(&jcs, row_pointer, 1);
                        }
                        jpeg_finish_compress(&jcs);//压缩完成后,记得要调用jpeg_finish_compress函数
                       /*5、最后就是释放压缩工作过程中所申请的资源了,主要就是jpeg压缩对象,由于在本例中我是直接用的局部变量,
                                                所以只需调用jpeg_destroy_compress这个函数即可,如下:*/
                        jpeg_destroy_compress(&jcs);
                        /*FrameBuffer.DrawRect(Video);*/
                        while(1) ;
                    }
            }catch (TError bitand e) {   //捕获异常
                e.Output();
                return 1;
            }
        std::cerr << "show picture" << std::endl;
        return app.exec();
    }

结果生成的有问题的图片点击图片栏即可看到。


我觉得问题应该处在RGB数据转换成JPG格式图片的那部分里面,但是总是无法解决,希望各位兄弟姐妹可以帮助,小弟不胜感激!!!

camera.jpg (10.6 KB, 下载次数: 54)

camera.jpg

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
2 [报告]
发表于 2010-08-15 22:30 |只看该作者
原图能贴出来看看不?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2010-08-16 16:47 |只看该作者
jpg 格式的图片,本来就压缩率太高, 花屏很正常,

换成 bmp 或 png 格式的,应该就正常了

论坛徽章:
0
4 [报告]
发表于 2010-08-17 10:30 |只看该作者
回复 3# goldenfort


    这位大哥,那这样转换成JPG格式,有没有解决花屏的办法呢,我需要转换成JPG格式的图片呢

论坛徽章:
0
5 [报告]
发表于 2010-08-17 10:30 |只看该作者
回复 2# T-Bagwell


    原图见上面的camera.jpg

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
6 [报告]
发表于 2010-08-17 20:16 |只看该作者
回复  T-Bagwell


    原图见上面的camera.jpg
wcy0556 发表于 2010-08-17 10:30



   
我的意思是有正常的图片拿出来吗?
比如RGB的原图

论坛徽章:
0
7 [报告]
发表于 2010-08-18 16:45 |只看该作者
回复 6# T-Bagwell


   

论坛徽章:
0
8 [报告]
发表于 2010-08-18 16:47 |只看该作者
本帖最后由 wcy0556 于 2010-08-18 16:49 编辑

T-Bagwell大哥您好!原图和转换后的JPG格式图我已经传上来了,您会发现这两个图大小和采集到的图像都是一样的,只是转换后的图片有很多彩色的瑕疵,麻烦您帮忙看下是什么原因,小弟在这拜谢了!!

论坛徽章:
0
9 [报告]
发表于 2010-08-18 17:02 |只看该作者
  1. [font=黑体][/font]
  2.                        struct jpeg_compress_struct jcs;
  3.                        struct jpeg_error_mgr jem;
  4.                        jcs.err = jpeg_std_error(&jem);
  5.                        jpeg_create_compress(&jcs);                           
  6.                        jpgFile=fopen("01.jpg","wb");
  7.                        if (jpgFile==NULL)
  8.                        {
  9.                        delete [] data;
  10.                        delete pdata;
  11.                        return 0;
  12.                        }
  13.                        jpeg_stdio_dest(&jcs, jpgFile);
  14.                      
  15.                        jcs.image_width = 160;      /*为图的宽和高,单位为像素*/
  16.                        jcs.image_height = 128;
  17.                        jcs.input_components = 3;     /*色彩通道数 在此为1,表示灰度图, 如果是彩色位图,则为3*/
  18.                        jcs.in_color_space = JCS_RGB; /*色彩空间 ,JCS_GRAYSCALE表示灰度图, JCS_RGB 表示彩色图像*/
  19.                        jpeg_set_defaults(&jcs);
  20.                        jpeg_set_quality(&jcs, 60, true);/*压缩质量*/
  21.                     /*上面的工作准备完成后,就可以压缩了,压缩过程非常简单,首先调用 jpeg_start_compress,
  22.                                        然后可以对每一行进行压缩,也可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,如下:*/
  23.                        jpeg_start_compress(&jcs, true);
  24.                        JSAMPROW row_pointer[1]; /*一行位图*/
  25.                        int row_stride;          /*每一行的字节数*/
  26.                        row_stride = jcs.image_width*3;  /*如果不是索引图,此处需要乘以3*/ /*480*/
  27.                      
  28.                        /*对每一行进行压缩*/
  29.                         while(jcs.next_scanline <128)
  30.                         {
  31.                         row_pointer[0] = & buff[jcs.next_scanline * row_stride];
  32.                         jpeg_write_scanlines(&jcs, row_pointer, 1);
  33.                         }
  34.                         jpeg_finish_compress(&jcs);//压缩完成后,记得要调用jpeg_finish_compress函数
  35.                        /*5、最后就是释放压缩工作过程中所申请的资源了,主要就是jpeg压缩对象,由于在本例中我是直接用的局部变量,
  36.                                                 所以只需调用jpeg_destroy_compress这个函数即可,如下:*/
  37.                         jpeg_destroy_compress(&jcs);
复制代码
这是小弟压缩图片的代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2010-08-19 14:17 |只看该作者
彩色的条纹,  是因为 jpeg 使用的压缩方法,是把空域转化的频域 来保存数据。

压缩后,图象的复原, 每个点的色彩, 是用多个正弦函数组合相加计算出来的。
当然会有 彩色的曲线条纹了。

但是,压缩方法能不能调整, 我也不了解。 知道的说下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP