• 局部标准差实现对比度增强


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

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





  • 相关阅读:
    CentOS 7 如何设置默认启动方式为命令行模式
    Virtual Box配置CentOS7网络
    序列化后成对象转map,再添加到dataList
    centos7 ping: www.baidu.com: Name or service not known
    协议1
    idea查看接口方法实现
    centos关闭防火墙
    myeclipse配置svn
    eas固定ip避免多次申请许可
    jvm配置
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/4857721.html
Copyright © 2020-2023  润新知