局部標准差實現對比度增強


基於“局部標准差”的圖像增強(原理、算法、代碼)

一、理論
         圖像增強算法的基本原則是“降低低頻區域,突出高頻區域”,以此強化邊緣,達到增強的目的。最簡單的例子就是通過原始圖像減去高斯模糊處理后的圖像,就能夠將邊緣強化出來。
         直方圖均衡化也是一種非常常見的增強方法。但是為了避免背景的干擾,更傾向於采用“局部”方法進行處理。我們這里着重研究自適應對比度增強(ACE)的相關內容。
        ACE的定義和原理看上去還是比較簡單的。這里的 都可以根據圖像本身計算出來。而 則需要單獨計算。

          可以為單獨的常量,或者通過來代替。這里的D是一個全局的值,比如平均值。

二、實現
        涉及到局部的運算,自然而然會想到使用卷積的方法。更好的是Opencv提供了專門的函數用來做這個工作—BLUR
文檔中寫到:
那么正是我們想要的結果。
//ace 自適應對比度均衡研究
//by  jsxyhelu
//感謝 imageshop
# include  "stdafx.h"
# include  <iostream >
# include  "opencv2/core/core.hpp"
# include  "opencv2/highgui/highgui.hpp"
# include  "opencv2/imgproc/imgproc.hpp"
using  namespace std;
using  namespace cv;
//點乘法 elementWiseMultiplication
cv : :Mat EWM(cv : :Mat m1,cv : :Mat m2){
    Mat dst =m1.mul(m2);
     return dst;
}
void main()
{
    Mat src  = imread( "hand.jpg", 0);
    Mat meanMask;
    Mat varMask;
    Mat meanGlobal;
    Mat varGlobal;
    Mat dst;
    Mat tmp;
    Mat tmp2;
     int C  =  30;
     int D  =  133;
     //全局均值和均方差
    blur(src.clone(),meanGlobal,src.size());
    varGlobal  = src  - meanGlobal;
    varGlobal  = EWM(varGlobal,varGlobal);
    blur(src.clone(),meanMask,Size( 50, 50)); //meanMask為局部均值
    tmp  = src  - meanMask;                        
    varMask  = EWM(tmp,tmp);              
    blur(varMask,varMask,Size( 50, 50));     //varMask為局部方差
    
    dst  = meanMask  + C *tmp;
    imshow( "src",src);
    imshow( "dst",dst);
     
    waitKey();
}
接下來,為了實現 那么需要計算局部標准差和全局均值或方差
前面已經計算出了局部均值,那么
tmp  = src  - meanMask;  
    varMask  = EWM(tmp,tmp);         
    blur(varMask,varMask,Size( 50, 50));     //varMask為局部方差   
計算出局部方差
//換算成局部標准差
    varMask.convertTo(varMask,CV_32F);
     for ( int i = 0;i <varMask.rows;i ++){
         for ( int j = 0;j <varMask.cols;j ++){
            varMask.at < float >(i,j)  =  ( float)sqrt(varMask.at < float >(i,j));
        }
    }
換算成局部標准差
meanStdDev(src,meanGlobal,varGlobal);  //meanGlobal為全局均值 varGlobal為全局標准差
是opencv提供的全局均值和標准差計算函數。
全部代碼進行重構后如下
//ace 自適應對比度均衡研究
//by  jsxyhelu
//感謝 imageshop
# include  "stdafx.h"
# include  <iostream >
# include  "opencv2/core/core.hpp"
# include  "opencv2/highgui/highgui.hpp"
# include  "opencv2/imgproc/imgproc.hpp"
using  namespace std;
using  namespace cv;
//點乘法 elementWiseMultiplication
cv : :Mat EWM(cv : :Mat m1,cv : :Mat m2){
    Mat dst =m1.mul(m2);
     return dst;
}
//圖像局部對比度增強算法
cv : :Mat ACE(cv : :Mat src, int C  =  4, int n = 20, int MaxCG  =  5){
    Mat meanMask;
    Mat varMask;
    Mat meanGlobal;
    Mat varGlobal;
    Mat dst;
    Mat tmp;
    Mat tmp2;
    blur(src.clone(),meanMask,Size( 50, 50)); //meanMask為局部均值 
    tmp  = src  - meanMask;  
    varMask  = EWM(tmp,tmp);         
    blur(varMask,varMask,Size( 50, 50));     //varMask為局部方差   
     //換算成局部標准差
    varMask.convertTo(varMask,CV_32F);
     for ( int i = 0;i <varMask.rows;i ++){
         for ( int j = 0;j <varMask.cols;j ++){
            varMask.at < float >(i,j)  =  ( float)sqrt(varMask.at < float >(i,j));
        }
    }
    meanStdDev(src,meanGlobal,varGlobal);  //meanGlobal為全局均值 varGlobal為全局標准差
    tmp2  = varGlobal /varMask;
     for ( int i = 0;i <tmp2.rows;i ++){
         for ( int j = 0;j <tmp2.cols;j ++){
             if (tmp2.at < float >(i,j) >MaxCG){
                tmp2.at < float >(i,j)  = MaxCG;
            }
        }
    }
    tmp2.convertTo(tmp2,CV_8U);
    tmp2  = EWM(tmp2,tmp);
    dst  = meanMask  + tmp2;
    imshow( "D方法",dst);
    dst  = meanMask  + C *tmp;
    imshow( "C方法",dst);
     return dst;
}
void main()
{
    Mat src  = imread( "plant.bmp", 0); 
    imshow( "src",src);
    ACE(src);
    waitKey();
}
三、小結
      從結果上來看,ACE算法對於特定情況下的圖片細節增強是顯著的,但是並不是適用於所有的情況,並且其參數需要手工進行調整。了解它的特性,就能夠解決一系列的問題,有效地增強現實。
 
 






免責聲明!

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



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