opencv實現camera模組的暗電流和lenshading補償 .


目錄(?)[-]

  1. 簡介
  2. 基本原理
    1. 產生原因
    2. 校正補償原理
  3. 具體實現
    1. 框架搭建
    2. 功能實現
      1. 暗電流
      2. lenshading補償
    3. 效果演示
      1. 圖片處理
    4. 效果演示

簡介

  在接觸過的qcom和mtk平台中,camera調試軟件和流程基本都是大同小異。所以查了點資料,然后模仿這些軟件,自己練習寫了下最開始的
兩步:暗電流和len shading補償。

基本原理

產生原因

  在camera模組中,會因為sensor本身的暗電流,從而對圖像參數噪聲。同時也會因為模組鏡頭的原因,導致拍攝照片的亮度,中間亮而四周相對較暗。
所以在模組工作中,我們需要對模組做暗電流的校正和len shading相關的補償。對這方面深入的了解,請自己查詢相關資料吧,這里只簡單講解下。

校正補償原理

  理解到了暗電流和len shading產生原因之后,就可以通過如下步驟開始進行校正。
  暗電流校正:1、用黑膠布遮住攝像頭,然后在全黑環境下拍攝一張全尺寸的照片。
                2、軟件讀取並保存住這張圖片的值,這里面非0的值,都是由sensor的暗電流產生的噪點,當對照片處理的時候,
                   需要減去這些對應的噪聲。
  lenshading補償:1、用毛玻璃蓋住模組,在燈箱下拍攝一張照片。正常情況下,可以看到照片是中心亮,而四周相對較暗。
                    2、將拍攝的照片通過處理,找出照片中最亮位置的亮度,然后用這個亮度為基准,記錄下整個圖片中,每個像素位置亮度和
                       這個亮度的比值。當對照片處理的時候,對應像素位置乘以這個比值。

具體實現

框架搭建

  根據前面一篇提到的《opencv模擬button》,構建出了基本軟件背景界面和三個操作按鍵。分別對應為暗電流、len shading補償、圖片處理。
效果如下:
         
                   

  軟件的運行如下:./XXX darkcurrent.jpg lenshading.jpg tmp.jpg
  darkcurrent.jpg:拍攝的暗電流照片。
  lenshading.jpg:拍攝的len shading照片。
  tmp.jpg:需要被處理的照片。

功能實現

  所以我們需要關心的就是那三個控件對應的事件處理功能。
void on_button(int buttonNow, Mat img){ if(buttonNow == 0){ doDarkCurrent(img); }else if(buttonNow == 1){ lenrollOff(img); }else if(buttonNow == 2){ pic_process(img); } buttonFlag[buttonNow] = true; }

暗電流

void doDarkCurrent(Mat mat){ IplImage pI = mat; IplImage pI_2 = img3; int width = mat.rows; int height = mat.cols; CvScalar s; int i, j; double b_count = 0, g_count = 0, r_count = 0;   for(i=0; i<height; i++){ for(j=0; j<width; j++){ s = cvGet2D(&pI, j, i); cvSet2D(&pI_2, j, i, s); } } }
  實現很簡單,就是將darkcurrent.jpg的照片數據保存到img3中,作為暗電流操作的操作數據。

lenshading補償

void lenrollOff(Mat img){ int *address; double maxLight; address = (int *)malloc(2); IplImage pI = img; getMaxLight(img, address, &maxLight); /* 找到圖像中最亮的點位置,address為最亮點所在的坐標 */ lenShading(maxLight, img, img4); }
  img對應為傳入的lenshading.jpg。首先通過函數getMaxLight,建立一個8X8的矩陣,然后該圖片中從頭到尾計算出矩陣包圍的圖片區域亮度,
並找出最高的位置和對應平均亮度。
  接着使用函數lenShading,計算出圖片所有像素和上一步得到的最大亮度之間比值,對應的保存在img4中。

效果演示

  使用步驟:1、運行軟件:./xxx ./res/dark.jpg ./res/lenoff.jpg ./res/1.jpg
            2、依次點擊控件:darkcurrent lenrolloff process。
            3、最后效果如下:

圖片處理

  在第一步和第二步處理完了之后,接着就可以進行第三步的圖片處理。
void pic_process(Mat img){ imshow("poc_process", img); /*process for DarkCurrent*/ proDark(img);   /*process for lenrollOff*/ prolenOff(img); imshow("prolenOff", img); }
  這一步中,首先顯示出來,需要被處理的照片,也就是之前傳入的tmp.jpg。接着使用proDark來減去暗電流產生的噪點。接着使用函數prolenOff進行
圖片lenshading的補償,最后將處理后的圖片也顯示出來。
void proDark(Mat img){ int width = img.rows; int height = img.cols; IplImage pI = img; int i, j; CvScalar s, s1; IplImage pI_2 = img3; int start_Haddr = img3.cols / 2 - height / 2; int end_Haddr = img3.cols / 2 + height / 2; int start_Waddr = img3.rows / 2 - width / 2; int end_Waddr = img3.rows / 2 + width / 2;   if((width > img3.rows) || (height > img3.cols)){ printf("proDark is error!!!!!!\n"); return; } for(i=start_Haddr; i < end_Haddr; i++){ for(j = start_Waddr; j < end_Waddr; j++){ s = cvGet2D(&pI_2, j, i); s1 = cvGet2D(&pI, j - start_Waddr, i - start_Haddr);   s1.val[0] = s1.val[0] - s.val[0]; s1.val[1] = s1.val[1] - s.val[1]; s1.val[2] = s1.val[2] - s.val[2];   cvSet2D(&pI, j - start_Waddr, i - start_Haddr, s1); } } }
  在傳入的處理圖片中,如果是被sensor裁剪過的話,那就從暗電流保存數據的中心開始,計算出和處理照片同樣大小的數據,然后處理照片再依次
減去對應的暗電流噪聲數據。
void prolenOff(Mat img){ int width = img.rows; int height = img.cols; IplImage pI = img; IplImage pI_2 = img4; int i, j; CvScalar s, s1;   cvCvtColor(&pI, &pI, CV_RGB2YCrCb); if((width > img4.rows) || (height > img4.cols)){ printf("prolenOff is error!!!!!!\n"); return; } int start_Haddr = img4.cols / 2 - height / 2; int end_Haddr = img4.cols / 2 + height / 2; int start_Waddr = img4.rows / 2 - width / 2; int end_Waddr = img4.rows / 2 + width / 2;   for(i=start_Haddr; i < end_Haddr; i++){ for(j = start_Waddr; j < end_Waddr; j++){ s = cvGet2D(&pI_2, j, i); s1 = cvGet2D(&pI, j - start_Waddr, i - start_Haddr); s1.val[0] = s1.val[0] * s.val[0] / 50;   cvSet2D(&pI, j - start_Waddr, i - start_Haddr, s1); } } cvCvtColor(&pI_2, &pI_2, CV_YCrCb2RGB); cvCvtColor(&pI, &pI, CV_YCrCb2RGB); }
  len shading補償也是一樣,根據處理圖片大小,從補償數據的中心開始,取出相應大小的數據,然后將圖片對應轉化為YCrCb,根據補償值從新調整
權重,接着將圖像轉換會RGB圖像。

效果演示

  使用步驟:1、運行軟件:./xxx ./res/dark.jpg ./res/lenoff.jpg ./res/1.jpg
            2、依次點擊控件:darkcurrent lenrolloff process。
            3、最后效果如下:
   

代碼下載:http://download.csdn.net/detail/u011630458/8691453


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM