码迷,mamicode.com
首页 > 编程语言 > 详细

[blogs 算法原理 ]局部标准差实现对比度增强

时间:2015-10-06 22:04:53      阅读:710      评论:0      收藏:0      [点我收藏+]

标签:

基于“局部标准差”的图像增强(原理、算法、代码)

一、理论
         图像增强算法的基本原则是“降低低频区域,突出高频区域”,以此强化边缘,达到增强的目的。最简单的例子就是通过原始图像减去高斯模糊处理后的图像,就能够将边缘强化出来。
         直方图均衡化也是一种非常常见的增强方法。但是为了避免背景的干扰,更倾向于采用“局部”方法进行处理。我们这里着重研究自适应对比度增强(ACE)的相关内容。
        ACE的定义和原理(TODO)
        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算法对于特定情况下的图片细节增强是显著的,但是并不是适用于所有的情况,并且其参数需要手工进行调整。了解它的特性,就能够解决一系列的问题,有效地增强现实。
 
 





[blogs 算法原理 ]局部标准差实现对比度增强

标签:

原文地址:http://www.cnblogs.com/jsxyhelu/p/4857721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!