找回密码
 注册
搜索
查看: 1343|回复: 1

[讨论] 2440 保存高分辨率图片(OV9650)问题!

[复制链接]
发表于 2007-1-22 23:12:51 | 显示全部楼层 |阅读模式
我使用ARM9 S3C2440平台,SENSOR用OV9650,OS用LINUX2.4.18,LCD为320*240
现在能实现在LCD上正常PREVIEW模式,和保存640*480的图片.但是OV的配置参数是30W的.
我现在想保存较大分辨率的图片,比如960*1000,或者1024*768,或1280*1024的.于是遇到了一些问题:
1.我想在驱动中想为YUV分配130W像素的缓冲,即我将
//#define YUV_TUPLE_SIZE (1024*768*2) // maximum
改为//#define YUV_TUPLE_SIZE (1280*1024*2) // maximum
然后提示无法分配这么大的内存,我做了实验,最大可定义为
//#define YUV_TUPLE_SIZE (1080*960*2) // maximum
我想问除了用consistent_alloc这个函数分配外,还有其它什么函数能代替?怎么才能保证内存分配成功,我的内存我现在用的版本是2.4.18
2.如1所述,如果我分配1080*960的YUV空间,
而定义
#define        FIXED_SOURCE_WIDTH1          960
#define        FIXED_SOURCE_HEIGHT1         1000
即保存的图片大小为960*1000.
在LCD上只能显示一部分.
我看提供的DEMO程序来看,也只能显示那么多,也就是LCD本来是240*320的,但是显示出来是240*250的.
还是因为分配的YUV空间太小,假如扩大到1280*1024就没问题.但目前因为内存分配失败无法实现.
这是show_cam_image函数即图片显示函数中的一部分代码.fb_buf为LCD Framebuffer
for(i=0; i<4; i++) {        //0,1,2,3
                if((image_width2>>i)<=fb_xres) {
                        f = 0;
                        w = min(image_width2>>i, fb_xres);
                        h = min(image_height2>>i, fb_yres);
                        break;
                }
                if((image_height2>>i)<=fb_yres) {
                        f = 1;
                        w = min(image_width2>>i, fb_yres);
                        h = min(image_height2>>i, fb_xres);
                        break;
                }
        }
for(y=0; y<H; y++) {
    for(x=0; x<W; 2 calculate { x+="2)" times
     if(i) {
      fb_buf[x]   = Conv_YCbCr_Rgb(y_buf[x&lt;<I],
         y_buf[(x&lt;<I)+1],
         cb_buf[(x&lt;<I)>&gt;1],
         cr_buf[(x&lt;<I)>&gt;1]);
      fb_buf[x+1] = Conv_YCbCr_Rgb(y_buf[(x&lt;<I)+YUV_INTERVAL[I]],
         y_buf[(x&lt;<I)+1+YUV_INTERVAL[I]],
         cb_buf[((x&lt;<I)+YUV_INTERVAL[I])>&gt;1],
         cr_buf[((x&lt;<I)+YUV_INTERVAL[I])>&gt;1]);
     } else {
      rgb_data = Conv_YCbCr_Rgb(y_buf[x&lt;<I],
         y_buf[(x&lt;<I)+1],
         cb_buf[(x&lt;<I)>&gt;1],
         cr_buf[(x&lt;<I)>&gt;1]);
      fb_buf[x]   = rgb_data;
      fb_buf[x+1] = rgb_data&gt;&gt;16;
     }
    }
    fb_buf += fb_xres;
    y_buf += image_width&lt;<I;
    cb_buf += (image_width&lt;<I)>&gt;1;
    cr_buf += (image_width&lt;<I)>&gt;1;
   }
这段代码的意思是否只抽取YUV缓冲中的部分数据放到LCD的Framebuffer中?
3.假如我按960*1000来保存图片.
保存的图片质量很差,还出现了三个排开的同样的图片,
因为我向OV的厂家要了130W的寄存器参数对OV SENSOR重新进行了配置,那么YUV缓冲中应该是至少100W左右的数据,即使不能捕获130W的数据,那么正常保存的图片不应该这样呀.我把YUV_BUFFER中的的数据完全打印出来,好像也没看见重复的数据.
我想问问如果从原来输出30W象素的设置改变为配置OV为130W的像素输出,除了配置I2C的100多个寄存器外,其它还需要配置什么吗?
另外当我配置捕获的图片为960*1000的时候,LCD上虽只显示240*250的图片,但是显示效果还是可以的.并且原来当OV SENSOR配置为30W输出的时候,也能正常保存640*480的图片,并且图片质量也不错.以下是保存图片的程序,请帮忙分析下,难道不适合保存960*1000的图片,好像没看见这个限制呀.
static void save_picture(unsigned char *src)
{
        int y, x;
        char name[64];
        unsigned long rgb_data;
        unsigned short w = image_width1;
        unsigned short h = image_height1;
        unsigned char *src_y = src;
        unsigned char *src_cb = src_y+image_width1*image_height1;
        unsigned char *src_cr = src_cb+image_width1*image_height1/2;
        int palette = optional_image_format[image_format].palette;              
        image_buffer = malloc(w*h*3);        //RGB24
        if(image_buffer==NULL) {
                printf("allocate memory fail in saving picture!\n");
                return;
        }

        if(palette==VIDEO_PALETTE_RGB565)
                for(y=0; y<H; y++)
                        for(x=0; x<W; x++) {
                                image_buffer[(y*w+x)*3]   = (((__u16 *)src)[y*w+x]&amp;0xf800)&gt;&gt;8;
                                image_buffer[(y*w+x)*3+1] = (((__u16 *)src)[y*w+x]&amp;0x07e0)&gt;&gt;3;
                                image_buffer[(y*w+x)*3+2] = (((__u16 *)src)[y*w+x]&amp;0x001f)&lt;&lt;3;
                        }
        else if(palette==VIDEO_PALETTE_YUV422P)
                for(y=0; y<H; y++)
                        for(x=0; x<W x++) 3; {
                                rgb_data = Conv_YCbCr_Rgb(src_y[y*w+x], src_y[y*w+x+1],
                                                                                        src_cb[(y*w+x)&gt;&gt;1], src_cr[(y*w+x)&gt;&gt;1]);
                                image_buffer[(y*w+x)*3]   = (rgb_data&amp;0xf800)&gt;&gt;8;
                                image_buffer[(y*w+x)*3+1] = (rgb_data&amp;0x07e0)&gt;&gt;3;
                                image_buffer[(y*w+x)*3+2] = (rgb_data&amp;0x001f)&lt;&lt;3;
                                x++;
                                image_buffer[(y*w+x)*3]   = (rgb_data&amp;0xf8000000)&gt;&gt;24;
                                image_buffer[(y*w+x)*3+1] = (rgb_data&amp;0x07e00000)&gt;&gt;19;
                                image_buffer[(y*w+x)*3+2] = (rgb_data&amp;0x001f0000)&gt;&gt;13;
                          
                          
                        }
        else {
                printf("unsupported input image format for saving jpeg file\n");
                free(image_buffer);
                return;
        }
         printf("h=%d,w=%d",h,w);
        for(y=0;y<H;Y++)
        for(x=0;x<W;X++)
          {
          if(x%10==0)            
           printf("\n");
           printf("0x%2x ",src[y*w+x]);
          }
        memset(name, 0, sizeof(name));
        sprintf(name, "%s%04d.jpg", image_file, file_index++);
        write_JPEG_file(name, optimization);
        free(image_buffer);
}
 楼主| 发表于 2007-1-22 23:12:51 | 显示全部楼层 |阅读模式
我使用ARM9 S3C2440平台,SENSOR用OV9650,OS用LINUX2.4.18,LCD为320*240
现在能实现在LCD上正常PREVIEW模式,和保存640*480的图片.但是OV的配置参数是30W的.
我现在想保存较大分辨率的图片,比如960*1000,或者1024*768,或1280*1024的.于是遇到了一些问题:
1.我想在驱动中想为YUV分配130W像素的缓冲,即我将
//#define YUV_TUPLE_SIZE (1024*768*2) // maximum
改为//#define YUV_TUPLE_SIZE (1280*1024*2) // maximum
然后提示无法分配这么大的内存,我做了实验,最大可定义为
//#define YUV_TUPLE_SIZE (1080*960*2) // maximum
我想问除了用consistent_alloc这个函数分配外,还有其它什么函数能代替?怎么才能保证内存分配成功,我的内存我现在用的版本是2.4.18
2.如1所述,如果我分配1080*960的YUV空间,
而定义
#define        FIXED_SOURCE_WIDTH1          960
#define        FIXED_SOURCE_HEIGHT1         1000
即保存的图片大小为960*1000.
在LCD上只能显示一部分.
我看提供的DEMO程序来看,也只能显示那么多,也就是LCD本来是240*320的,但是显示出来是240*250的.
还是因为分配的YUV空间太小,假如扩大到1280*1024就没问题.但目前因为内存分配失败无法实现.
这是show_cam_image函数即图片显示函数中的一部分代码.fb_buf为LCD Framebuffer
for(i=0; i&lt;4; i++) {        //0,1,2,3
                if((image_width2&gt;&gt;i)&lt;=fb_xres) {
                        f = 0;
                        w = min(image_width2&gt;&gt;i, fb_xres);
                        h = min(image_height2&gt;&gt;i, fb_yres);
                        break;
                }
                if((image_height2&gt;&gt;i)&lt;=fb_yres) {
                        f = 1;
                        w = min(image_width2&gt;&gt;i, fb_yres);
                        h = min(image_height2&gt;&gt;i, fb_xres);
                        break;
                }
        }
for(y=0; y<H; y++) {
    for(x=0; x<W; 2 calculate { x+="2)" times
     if(i) {
      fb_buf[x]   = Conv_YCbCr_Rgb(y_buf[x&lt;<I],
         y_buf[(x&lt;<I)+1],
         cb_buf[(x&lt;<I)>&gt;1],
         cr_buf[(x&lt;<I)>&gt;1]);
      fb_buf[x+1] = Conv_YCbCr_Rgb(y_buf[(x&lt;<I)+YUV_INTERVAL[I]],
         y_buf[(x&lt;<I)+1+YUV_INTERVAL[I]],
         cb_buf[((x&lt;<I)+YUV_INTERVAL[I])>&gt;1],
         cr_buf[((x&lt;<I)+YUV_INTERVAL[I])>&gt;1]);
     } else {
      rgb_data = Conv_YCbCr_Rgb(y_buf[x&lt;<I],
         y_buf[(x&lt;<I)+1],
         cb_buf[(x&lt;<I)>&gt;1],
         cr_buf[(x&lt;<I)>&gt;1]);
      fb_buf[x]   = rgb_data;
      fb_buf[x+1] = rgb_data&gt;&gt;16;
     }
    }
    fb_buf += fb_xres;
    y_buf += image_width&lt;<I;
    cb_buf += (image_width&lt;<I)>&gt;1;
    cr_buf += (image_width&lt;<I)>&gt;1;
   }
这段代码的意思是否只抽取YUV缓冲中的部分数据放到LCD的Framebuffer中?
3.假如我按960*1000来保存图片.
保存的图片质量很差,还出现了三个排开的同样的图片,
因为我向OV的厂家要了130W的寄存器参数对OV SENSOR重新进行了配置,那么YUV缓冲中应该是至少100W左右的数据,即使不能捕获130W的数据,那么正常保存的图片不应该这样呀.我把YUV_BUFFER中的的数据完全打印出来,好像也没看见重复的数据.
我想问问如果从原来输出30W象素的设置改变为配置OV为130W的像素输出,除了配置I2C的100多个寄存器外,其它还需要配置什么吗?
另外当我配置捕获的图片为960*1000的时候,LCD上虽只显示240*250的图片,但是显示效果还是可以的.并且原来当OV SENSOR配置为30W输出的时候,也能正常保存640*480的图片,并且图片质量也不错.以下是保存图片的程序,请帮忙分析下,难道不适合保存960*1000的图片,好像没看见这个限制呀.
static void save_picture(unsigned char *src)
{
        int y, x;
        char name[64];
        unsigned long rgb_data;
        unsigned short w = image_width1;
        unsigned short h = image_height1;
        unsigned char *src_y = src;
        unsigned char *src_cb = src_y+image_width1*image_height1;
        unsigned char *src_cr = src_cb+image_width1*image_height1/2;
        int palette = optional_image_format[image_format].palette;              
        image_buffer = malloc(w*h*3);        //RGB24
        if(image_buffer==NULL) {
                printf("allocate memory fail in saving picture!\n");
                return;
        }

        if(palette==VIDEO_PALETTE_RGB565)
                for(y=0; y<H; y++)
                        for(x=0; x<W; x++) {
                                image_buffer[(y*w+x)*3]   = (((__u16 *)src)[y*w+x]&amp;0xf800)&gt;&gt;8;
                                image_buffer[(y*w+x)*3+1] = (((__u16 *)src)[y*w+x]&amp;0x07e0)&gt;&gt;3;
                                image_buffer[(y*w+x)*3+2] = (((__u16 *)src)[y*w+x]&amp;0x001f)&lt;&lt;3;
                        }
        else if(palette==VIDEO_PALETTE_YUV422P)
                for(y=0; y<H; y++)
                        for(x=0; x<W x++) 3; {
                                rgb_data = Conv_YCbCr_Rgb(src_y[y*w+x], src_y[y*w+x+1],
                                                                                        src_cb[(y*w+x)&gt;&gt;1], src_cr[(y*w+x)&gt;&gt;1]);
                                image_buffer[(y*w+x)*3]   = (rgb_data&amp;0xf800)&gt;&gt;8;
                                image_buffer[(y*w+x)*3+1] = (rgb_data&amp;0x07e0)&gt;&gt;3;
                                image_buffer[(y*w+x)*3+2] = (rgb_data&amp;0x001f)&lt;&lt;3;
                                x++;
                                image_buffer[(y*w+x)*3]   = (rgb_data&amp;0xf8000000)&gt;&gt;24;
                                image_buffer[(y*w+x)*3+1] = (rgb_data&amp;0x07e00000)&gt;&gt;19;
                                image_buffer[(y*w+x)*3+2] = (rgb_data&amp;0x001f0000)&gt;&gt;13;
                          
                          
                        }
        else {
                printf("unsupported input image format for saving jpeg file\n");
                free(image_buffer);
                return;
        }
         printf("h=%d,w=%d",h,w);
        for(y=0;y<H;Y++)
        for(x=0;x<W;X++)
          {
          if(x%10==0)            
           printf("\n");
           printf("0x%2x ",src[y*w+x]);
          }
        memset(name, 0, sizeof(name));
        sprintf(name, "%s%04d.jpg", image_file, file_index++);
        write_JPEG_file(name, optimization);
        free(image_buffer);
}
高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-6-7 08:02 , Processed in 0.055262 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表