相機插值

微博搜索  bindingfly 歡迎關注

==============

插值的基本概念:

插值(Interpolation),有時也稱爲“重置樣本”,是在不生成像素的情況下增加圖像像素大小的一種方法,在周圍像素色彩的基礎上用數學公式計算丟失像素的色彩。有些相機使用插值,人爲地增加圖像的分辨率

在掃描過程中,根據所需的已知數值製作出估計的像素值,這一過程叫做插值。當我們要求掃描分辨率和放大率與掃描儀的光學分辨率和11的放大率不同時,掃描儀必須做出某種形式的插值和縮放。

在掃描時,插值可以用來減少或增大信息量。如果碰巧選擇了一個準確的數值,它與掃描儀光學分辨率正好成分數或倍數關係,那麼相對來說,增值插值和減值插值就變得簡單多了。

如將把600dpiX600dpi的信息轉換成300dpiX300dpi,或者通過估算一些像素值,輸出1200dpiX1200dpi的圖像。將600dpiX600dpi掃描轉換成300dpiX300dpi要拋棄一些像素才能完成,模仿1200dpiX1200dpi的分辨率則涉及到要複製更多的像素。如果要得到其它的分辨率,掃描儀不只是拋棄或複製像素,而且要檢查可能得到的像素,並根據在原取樣點找到的數據製作新像素。

在掃描中插值與在Photoshop中重新取樣(在Photoshop中放大或縮小圖像,或改變圖像的分辨率)是相同的。因此可以選擇是在圖像輸入Photoshop之前,在掃描儀內插值或直接按比例縮放圖像,還是等到圖像輸入Photoshop後,對圖像進行重新取樣處理。前者可能比較快,尤其是在處理大型圖像時更是如此。而後者能讓我們更好的控制對圖像的這種處理 .

插值:用來填充圖像變換時像素之間的空隙。

 

插值運算,是一種圖像處理算法。基本原理是在離散數據的基礎上補插連續函數,使得這條連續曲線通過全部給定的離散數據點。插值是離散函數逼近的重要方法,利用它可通過函數在有限個點處的取值狀況,估算出函數在其他點處的近似值。

當這一算法應用到圖像處理的圖片改變時(大多用在放大),像素也相應地增加,增加的過程就是“插值”程序自動選擇信息較好的像素作爲增加的像素,而並非只使用臨近的像素,所以在放大圖像時,圖像看上去會比較平滑、乾淨。不過需要說明的是插值並不能增加圖像信息。通俗地講插值的效果實際就是給一杯香濃的咖啡兌了一些白開水。

 

 常見的插值方法及其原理

 

1. 最臨近像素插值:圖像出現了馬賽克和鋸齒等明顯走樣的原因。不過最臨近插值法的優點就是速度快。

 

2. 線性插值(Linear):線性插值速度稍微要慢一點,但效果要好不少。所以線性插值是個不錯的折中辦法。

 

3.其他插值方法:立方插值,樣條插值等等,它們的目的是試圖讓插值的曲線顯得更平滑,爲了達到這個目的,它們不得不利用到周圍若干範圍內的點,不過計算量顯然要比前兩種大許多。

 

在以上的基礎上,有的軟件還發展了更復雜的改進的插值方式譬如S-SPline、TurboPhoto等。它們的目的就是使邊緣的表現更完美。

值最明顯的體現就是數碼相機/數碼攝像機上的“數字變焦”功能。

所以,相信你看了以上的解釋之後,會明白拍攝時最好不要用數字變焦功能。所以,買數碼設備的時候,不要看數字變焦是多少多少倍,而要關注“光學變焦”這個參數。

 

出現問題: 差值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 inMED_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__)

            #defineMAX_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文件中

voidOV2655_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 thisdummy*/
                  OV2655_dummy_lines=0;
   } 
OV2655_write_cmos_sensor(0x3011,0x03);//48M/(3+1)=12M改變幀率爲12M



發佈了72 篇原創文章 · 獲贊 13 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章