zoukankan      html  css  js  c++  java
  • 直方图均衡化原理

    直方图均衡化的作用是图像增强。

    有两个问题比较难懂,一是为什么要选用累积分布函数,二是为什么使用累积分布函数处理后像素值会均匀分布。

    第一个问题。均衡化过程中,必须要保证两个条件:①像素无论怎么映射,一定要保证原来的大小关系不变,较亮的区域,依旧是较亮的,较暗依旧暗,只是对比度增大,绝对不能明暗颠倒;②如果是八位图像,那么像素映射函数的值域应在0和255之间的,不能越界。综合以上两个条件,累积分布函数是个好的选择,因为累积分布函数是单调增函数(控制大小关系),并且值域是0到1(控制越界问题),所以直方图均衡化中使用的是累积分布函数。

    第二个问题。累积分布函数具有一些好的性质,那么如何运用累积分布函数使得直方图均衡化?比较概率分布函数和累积分布函数,前者的二维图像是参差不齐的,后者是单调递增的。直方图均衡化过程中,映射方法是

    其中,n是图像中像素的总和,是当前灰度级的像素个数,L是图像中可能的灰度级总数。

    来看看通过上述公式怎样实现的拉伸。假设有如下图像:

    得图像的统计信息如下图所示,并根据统计信息完成灰度值映射:

    映射后的图像如下所示:

    以上就是直方图映射均衡化的步骤,当然还有一些基于此的更优算法,比如Photoshop中的方法,在此就不一一列举了,大同小异。

    下附源码:

    // HistogramGrayEqualizeHist.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    
    #include <iostream>
    #include <opencv2/core/core.hpp>   //cvGetSize  cvCreateImage
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/opencv.hpp>  //cvResize cvInitMatHeader cvGetMinMaxHistValue cvCvtColor
    #include <opencv2/imgproc/imgproc.hpp>
    
    #ifdef _DEBUG
    #pragma comment(lib, "opencv_core244d")
    #pragma comment(lib, "opencv_highgui244d")
    #pragma comment(lib, "opencv_imgproc244d")  //cvResize
    #else
    #pragma comment(lib, "opencv_core244d")
    #pragma comment(lib, "opencv_highgui244d")
    #pragma comment(lib, "opencv_imgproc244d")  //cvResize
    #endif
    #define cvQueryHistValue_1D(hist,idx0) ((float)cvGetReal1D( (hist)->bins, (idx0)))
    
    using namespace std;  
    #pragma comment(linker, "/subsystem:"windows" /entry:"mainCRTStartup"")  
    void FillWhite(IplImage *pImage)  
    {  
        cvRectangle(pImage, cvPoint(0, 0), cvPoint(pImage->width, pImage->height), CV_RGB(255, 255, 255), CV_FILLED);  
    }  
    // 创建灰度图像的直方图  
    CvHistogram* CreateGrayImageHist(IplImage **ppImage)  
    {  
        int nHistSize = 256;  
        float fRange[] = {0, 255};  //灰度级的范围    
        float *pfRanges[] = {fRange};    
        CvHistogram *pcvHistogram = cvCreateHist(1, &nHistSize, CV_HIST_ARRAY, pfRanges);  
        cvCalcHist(ppImage, pcvHistogram);  
        return pcvHistogram;  
    }  
    // 根据直方图创建直方图图像  
    IplImage* CreateHisogramImage(int nImageWidth, int nScale, int nImageHeight, CvHistogram *pcvHistogram)  
    {  
        IplImage *pHistImage = cvCreateImage(cvSize(nImageWidth * nScale, nImageHeight), IPL_DEPTH_8U, 1);  
        FillWhite(pHistImage);  
      
        //统计直方图中的最大直方块  
        float fMaxHistValue = 0;  
        cvGetMinMaxHistValue(pcvHistogram, NULL, &fMaxHistValue, NULL, NULL);  
      
        //分别将每个直方块的值绘制到图中  
        int i;  
        for(i = 0; i < nImageWidth; i++)  
        {  
            float fHistValue = cvQueryHistValue_1D(pcvHistogram, i); //像素为i的直方块大小  
            int nRealHeight = cvRound((fHistValue / fMaxHistValue) * nImageHeight);  //要绘制的高度  
            cvRectangle(pHistImage,  
                cvPoint(i * nScale, nImageHeight - 1),  
                cvPoint((i + 1) * nScale - 1, nImageHeight - nRealHeight),  
                cvScalar(i, 0, 0, 0),   
                CV_FILLED  
                );   
        }  
        return pHistImage;  
    }  
    int main( int argc, char** argv )  
    {     
        const char *pstrWindowsSrcTitle = "原图";  
        const char *pstrWindowsGrayTitle = "灰度图";  
        const char *pstrWindowsHistTitle = "直方图";  
        const char *pstrWindowsGrayEqualizeTitle = "灰度图-均衡化后";  
        const char *pstrWindowsHistEqualizeTitle = "直方图-均衡化后";  
          
        // 从文件中加载原图  
        // IplImage *pSrcImage = cvLoadImage("./images/yangmi.jpg", CV_LOAD_IMAGE_UNCHANGED);  
        IplImage *pSrcImage = cvLoadImage("./images/beauty.png", CV_LOAD_IMAGE_UNCHANGED);  
        IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  
        IplImage *pGrayEqualizeImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);  
          
        // 灰度图  
        cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);  
        // 直方图图像数据  
        int nHistImageWidth = 255;  
        int nHistImageHeight = 150;   
        int nScale = 2;    
      
        // 灰度直方图及直方图图像  
        CvHistogram *pcvHistogram = CreateGrayImageHist(&pGrayImage);  
        IplImage *pHistImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogram);  
      
        // 均衡化 
        //函数功能:直方图均衡化,该函数能归一化图像亮度和增强对比度
        //第一个参数表示输入图像,必须为灰度图(8位,单通道图)
        //第二个参数表示输出图像
        //该函数采用如下法则对输入图像进行直方图均衡化:
            //1:计算输入图像的直方图H。
            //2:直方图归一化,因此直方块和为255。
            //3:计算直方图积分,H'(i) = Sum(H(j)) (0<=j<=i)。
            //4:采用H'作为查询表:dst(x, y) = H'(src(x, y))进行图像变换。
        cvEqualizeHist(pGrayImage, pGrayEqualizeImage);  
      
        // 均衡化后的灰度直方图及直方图图像  
        CvHistogram *pcvHistogramEqualize = CreateGrayImageHist(&pGrayEqualizeImage);         
        IplImage *pHistEqualizeImage = CreateHisogramImage(nHistImageWidth, nScale, nHistImageHeight, pcvHistogramEqualize);  
      
        // 显示  
        cvNamedWindow(pstrWindowsSrcTitle); 
        cvNamedWindow(pstrWindowsGrayTitle); 
        cvNamedWindow(pstrWindowsGrayEqualizeTitle); 
        cvNamedWindow(pstrWindowsHistTitle); 
        cvNamedWindow(pstrWindowsHistEqualizeTitle); 
        cvShowImage(pstrWindowsSrcTitle,pSrcImage);
        cvShowImage(pstrWindowsGrayTitle,pGrayImage);
        cvShowImage(pstrWindowsGrayEqualizeTitle,pGrayEqualizeImage);
        cvShowImage(pstrWindowsHistTitle,pHistImage);
        cvShowImage(pstrWindowsHistEqualizeTitle,pHistEqualizeImage);
        cvWaitKey(0);  
        //回收资源代码…  
        cvDestroyWindow(pstrWindowsSrcTitle);
        cvDestroyWindow(pstrWindowsGrayTitle);
        cvDestroyWindow(pstrWindowsGrayEqualizeTitle);
        cvDestroyWindow(pstrWindowsHistTitle);
        cvDestroyWindow(pstrWindowsHistEqualizeTitle);
        cvReleaseImage(&pSrcImage);
        cvReleaseImage(&pGrayImage);
        cvReleaseImage(&pGrayEqualizeImage);
        cvReleaseImage(&pHistImage);
        cvReleaseImage(&pHistEqualizeImage);
        return 0;  
    }  
    View Code

    实验结果:

    本文参考:

    http://blog.csdn.net/rushkid02/article/details/9178117

    http://blog.csdn.net/zrongh/article/details/7302816               直方图均衡化原理

    http://bbs.ednchina.com/BLOG_ARTICLE_219471.HTM     直方图均衡化

  • 相关阅读:
    php命令注入
    mysql事物
    安装php环境
    移除服务器缓存实例
    show user profile synchronization tools
    manual start user profile import
    JSON is undefined. Infopath Form People Picker in SharePoint 2013
    asp.net web 应用站点支持域账户登录
    Load sharepoint envirement by powershell
    sharepoint 2016 download
  • 原文地址:https://www.cnblogs.com/tianyalu/p/5687782.html
Copyright © 2011-2022 走看看