您的位置:首页 > 其它

Camera 插值

2012-12-20 14:12 357 查看
插值(Interpolation),有时也称为“重置样本”,是在不生成像素的情况下增加图像像素大小的一种方法,在周围像素色彩的基础上用数学公式计算丢失像素的色彩。有些相机使用插值,人为地增加图像的分辨率

在扫描过程中,根据所需的已知数值制作出估计的像素值,这一过程叫做插值。当我们要求扫描分辨率和放大率与扫描仪的光学分辨率和1:1的放大率不同时,扫描仪必须做出某种形式的插值和缩放。

在扫描时,插值可以用来减少或增大信息量。如果碰巧选择了一个准确的数值,它与扫描仪光学分辨率正好成分数或倍数关系,那么相对来说,增值插值和减值插值就变得简单多了。

如将把600dpiX600dpi的信息转换成300dpiX300dpi,或者通过估算一些像素值,输出1200dpiX1200dpi的图像。将600dpiX600dpi扫描转换成300dpiX300dpi要抛弃一些像素才能完成,模仿1200dpiX1200dpi的分辨率则涉及到要复制更多的像素。如果要得到其它的分辨率,扫描仪不只是抛弃或复制像素,而且要检查可能得到的像素,并根据在原取样点找到的数据制作新像素。

在扫描中插值与在Photoshop中重新取样(在Photoshop中放大或缩小图像,或改变图像的分辨率)是相同的。因此可以选择是在图像输入Photoshop之前,在扫描仪内插值或直接按比例缩放图像,还是等到图像输入Photoshop后,对图像进行重新取样处理。前者可能比较快,尤其是在处理大型图像时更是如此。而后者能让我们更好的控制对图像的这种处理 .

插值:用来填充图像变换时像素之间的空隙。

插值运算,是一种图像处理算法。基本原理是在离散数据的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点。插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。

当这一算法应用到图像处理的图片改变时(大多用在放大),像素也相应地增加,增加的过程就是“插值”程序自动选择信息较好的像素作为增加的像素,而并非只使用临近的像素,所以在放大图像时,图像看上去会比较平滑、干净。不过需要说明的是插值并不能增加图像信息。通俗地讲插值的效果实际就是给一杯香浓的咖啡兑了一些白开水。

★ 常见的插值方法及其原理

1. 最临近像素插值:图像出现了马赛克和锯齿等明显走样的原因。不过最临近插值法的优点就是速度快。

2. 线性插值(Linear):线性插值速度稍微要慢一点,但效果要好不少。所以线性插值是个不错的折中办法。

3. 其他插值方法:立方插值,样条插值等等,它们的目的是试图让插值的曲线显得更平滑,为了达到这个目的,它们不得不利用到周围若干范围内的点,不过计算量显然要比前两种大许多。

在以上的基础上,有的软件还发展了更复杂的改进的插值方式譬如S-SPline、Turbo Photo等。它们的目的就是使边缘的表现更完美。

值最明显的体现就是数码相机/数码摄像机上的“数字变焦”功能。

所以,相信你看了以上的解释之后,会明白拍摄时最好不要用数字变焦功能。所以,买数码设备的时候,不要看数字变焦是多少多少倍,而要关注“光学变焦”这个参数。

Camera插值介绍

1. 首先要用到的就是sensor_capability.h设置图像容量的相关宏,即使能图像大小的开关在此设置:
#if (defined(MT9P012_RAW)||defined(S5K3E2FX_RAW)||defined(RJ53S1BA0C_RAW)||defined(OV5630_RAW))

#define __IMAGE_SENSOR_5M__

#else 。。。。。。。

#else

//#error

#endif

在合适的位置,或者关闭所有宏,设置新的宏__IMAGE_SENSOR_XM__ ;X=1,2,3,5,7,8等

2. 然后在MMI_features_camera.h文件中设置图片具体分辨率
#if defined(__IMAGE_SENSOR_3M__) && (defined(MT6235) || defined(MT6235B))

#define CAMERA_FEATURE_IMAGE_SIZE_LL_WIDTH (2048)

#define CAMERA_FEATURE_IMAGE_SIZE_LL_HEIGHT (1536)

#define CAMERA_FEATURE_IMAGE_SIZE_L_WIDTH (800)

#define CAMERA_FEATURE_IMAGE_SIZE_L_HEIGHT (600)

#define CAMERA_FEATURE_IMAGE_SIZE_M_WIDTH (640)

#define CAMERA_FEATURE_IMAGE_SIZE_M_HEIGHT (480)

#define CAMERA_FEATURE_IMAGE_SIZE_S_WIDTH (320)

#define CAMERA_FEATURE_IMAGE_SIZE_S_HEIGHT (240)

#define CAMERA_FEATURE_IMAGE_SIZE_SS_WIDTH (240)

#define CAMERA_FEATURE_IMAGE_SIZE_SS_HEIGHT (400)
#elif defined(__IMAGE_SENSOR_2M__) && (defined(MT6235) || defined(MT6235B))

从LL,L,M,S,SS五种大小分辨率LL是超大,SS超小,选一组做修改,大小常考下面的表格:

分辨率 乘积 对应像素

640 X 480 307200 30万

1024 X  768 786432 80万

1600 X 1200 1920000 200万

2048 X 1536 3145728 320万

2304 X 1728 3981312 400万

2580 X 1936 4994880 500万

2816 X 2112 5947392 600万

3072 X 2304 7077888 700万

3200 X 2400 7680000 770万

3264 X 2448 7990272 800万

3876 X 2584 10015584 1000万

需要注意的是宏开关与前面的设置要一样,#if defined(__IMAGE_SENSOR_XM__) && (defined(MT6235) || defined(MT6235B)),所以在此添加一个#elif defined()避免与其他旧数据冲突。

3. 最后编译即可

出现问题: 差值5M出现拍照死机

解决方案:

1. 通过trace跟踪发现在cam_msg_handler.c文件中代码处

ASSERT(capture_isp_param.v_address + capture_isp_param.v_size <=

cam_context_p->capture_buffer_p + MAX_CAM_CAPTURE_ISP_BUF_SIZE);

这部分死机,表明内存分配可能不足。

2. 往上查看cam_msg_handler.c中

img_width = (req_p->image_width%16==0)? req_p->image_width : 16 - (req_p->image_width%16) + req_p->image_width;

img_height = (req_p->image_height%16==0)? req_p->image_height : 16 - (req_p->image_height%16) + req_p->image_height;

cam_context_p->channel_size = img_width*img_height;

if (capture_isp_param.jpeg_gray_mode ==0)

{

/* color mode */

capture_isp_param.y_size = cam_context_p->channel_size;

capture_isp_param.u_size = cam_context_p->channel_size/4;

capture_isp_param.v_size = cam_context_p->channel_size/4;

capture_isp_param.y_address = cam_context_p->y_address =

(kal_uint32)(cam_context_p->capture_buffer_p + MAX_JPEG_ENCODE_MARGIN_LEN);

capture_isp_param.u_address = cam_context_p->u_address =

(kal_uint32)(cam_context_p->y_address + capture_isp_param.y_size);

capture_isp_param.v_address = cam_context_p->v_address =

(kal_uint32)(cam_context_p->u_address + capture_isp_param.u_size);
ASSERT(capture_isp_param.v_address + capture_isp_param.v_size <=

cam_context_p->capture_buffer_p + MAX_CAM_CAPTURE_ISP_BUF_SIZE);

}

由以上程序可知capture_isp_param.v_address+ capture_isp_param.v_size =cam_context_p->capture_buffer_p+ MAX_JPEG_ENCODE_MARGIN_LEN + capture_isp_param.u_size+ capture_isp_param.y_size+ capture_isp_param.v_size<=cam_context_p->capture_buffer_p
+ MAX_CAM_CAPTURE_ISP_BUF_SIZE

最后的结果就是MAX_JPEG_ENCODE_MARGIN_LEN + capture_isp_param.u_size+ capture_isp_param.y_size+ capture_isp_param.v_size<=MAX_CAM_CAPTURE_ISP_BUF_SIZE;
3. 搜索MAX_CAM_CAPTURE_ISP_BUF_SIZE找到

else

{

file_buffer_size = MAX_CAM_CAPTURE_MEM_BUF_SIZE;

}
/* solution for burst shot */

if (cam_context_p->snapshot_number > 1)

{

/* to release the memory allocated in MED_MODE_BUFFER mode */

CAM_FREE_CAPTURE_BUFFER();

cam_context_p->capture_buffer_p = (kal_uint32) med_alloc_ext_mem(file_buffer_size);

ASSERT (cam_context_p->capture_buffer_p != NULL);

result = MED_RES_OK;

}
中cam_context_p->capture_buffer_p = (kal_uint32) med_alloc_ext_mem(file_buffer_size);分配了首地址给cam_context_p->capture_buffer_p,大小为MAX_CAM_CAPTURE_MEM_BUF_SIZE
找到宏MAX_CAM_CAPTURE_MEM_BUF_SIZE

#define MAX_CAM_CAPTURE_ISP_TOTAL_BUF_SIZE (MAX_JPEG_ENCODE_MARGIN_LEN + MAX_SW_JPG_YUV_BUFFER_SIZE)

#define MAX_CAM_CAPTURE_ISP_BUF_SIZE (MAX_CAM_CAPTURE_ISP_TOTAL_BUF_SIZE)
知道分配大小(MAX_JPEG_ENCODE_MARGIN_LEN + MAX_SW_JPG_YUV_BUFFER_SIZE),对比MAX_JPEG_ENCODE_MARGIN_LEN + capture_isp_param.u_size+ capture_isp_param.y_size+
capture_isp_param.v_size<=MAX_CAM_CAPTURE_ISP_BUF_SIZE;

知道capture_isp_param.u_size+ capture_isp_param.y_size+ capture_isp_param.v_size<=MAX_SW_JPG_YUV_BUFFER_SIZE
搜索MAX_SW_JPG_YUV_BUFFER_SIZE

#if defined(__SW_JPEG_CODEC_SUPPORT__)

#if defined(__IMAGE_SENSOR_03M__)

#define MAX_SW_JPG_YUV_BUFFER_SIZE (640*480*3/2)

#elif defined(__IMAGE_SENSOR_1M__)

#define MAX_SW_JPG_YUV_BUFFER_SIZE (1280*1024*3/2)

#elif defined(__IMAGE_SENSOR_2M__)

#define MAX_SW_JPG_YUV_BUFFER_SIZE (1600*1200*3/2)

#elif defined(__IMAGE_SENSOR_3M__)

#define MAX_SW_JPG_YUV_BUFFER_SIZE (2048*1536*3/2)

#elif defined(__IMAGE_SENSOR_5M__)

#define MAX_SW_JPG_YUV_BUFFER_SIZE (2592*1944*3/2)

知道MAX_SW_JPG_YUV_BUFFER_SIZE分配空间不够

需要在此更改大小为

#elif defined(__IMAGE_SENSOR_5M__)

#define MAX_SW_JPG_YUV_BUFFER_SIZE (2592*1952*3/2)

为什么?由capture_isp_param.u_size+ capture_isp_param.y_size+ capture_isp_param.v_size的最初来源

img_width = (req_p->image_width%16==0)? req_p->image_width : 16 - (req_p->image_width%16) + req_p->image_width;

img_height = (req_p->image_height%16==0)? req_p->image_height : 16 - (req_p->image_height%16) + req_p->image_height;

cam_context_p->channel_size = img_width*img_height;

if (capture_isp_param.jpeg_gray_mode ==0)

{

/* color mode */

capture_isp_param.y_size = cam_context_p->channel_size;

capture_isp_param.u_size = cam_context_p->channel_size/4;

capture_isp_param.v_size = cam_context_p->channel_size/4;

知道image_width和image_height应该是16的整数倍,不然会增加大小,补充相应非整数小部分,造成capture_isp_param.u_size+ capture_isp_param.y_size+ capture_isp_param.v_size>MAX_SW_JPG_YUV_BUFFER_SIZE

而MAX_SW_JPG_YUV_BUFFER_SIZE分配到的大小没有做16余数的补充~

问题2:5M的插值解决了,但是拍摄的照片有条纹

解决方案:通常是由于帧率太快

在image_sensor_OV2655.c文件中

void OV2655_Capture(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)

函数中

if ((image_window->image_target_width<=OV2655_IMAGE_SENSOR_FULL_WIDTH)&&

(image_window->image_target_height<=OV2655_IMAGE_SENSOR_FULL_HEIGHT))

{

#ifdef MCP_NOR_PAGING_MODE_PSRAM_OV2655

OV2655_capture_pclk_in_M = 36;

OV2655_dummy_pixels=0x300; /*If Capture fail, you can add this dummy*/

OV2655_dummy_lines=0;

。。。。。。。。

。。。。。。。。
最下面分支:else{ 处添加:

if ((image_window->image_target_width>=2500)&&

(image_window->image_target_height>=1900))

{

OV2655_write_cmos_sensor(0x3011,0x03);//48M/(3+1)=12M

OV2655_capture_pclk_in_M = 12;

OV2655_dummy_pixels=100; /*If Capture fail, you can add this dummy*/

OV2655_dummy_lines=0;
}

OV2655_write_cmos_sensor(0x3011,0x03);//48M/(3+1)=12M 改变帧率为12M

问题解决!!!!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: