[openCV]直方图均衡

1.图像的直方图

图像的直方图,代表了图像的灰度值的分布状况。从直方图上,我们可以很明确的知道,图像的偏暗程度和饱和程度。如果一幅数字图像中,假设作为水平轴的灰度值rk出现了nk次,那么对应于垂直轴的归一化后的函数如下所示。

pk=nkMN

这样的图像,被称为直方图。为了直观感受一下直方图的作用,我使用相机调节曝光补偿,拍摄了以下3枚图像。

从图像的上方的直方图就可以看出来,图像的偏暗程度与饱和程度。并且,可以将左图像与中央图像称为动态范围较窄的图像。相反的,对于右边图像,其动态范围较宽,图像得到了很好的显示。

2.直方图均衡

直方图均衡,可以用于调节动态范围较窄的图像,增强图像对比度。然而,灰度拉升或者其他的灰度变换同样可以达到这个目的。所以,直方图均衡的本质目的是,将图像的累积分布函数(Probability Density Function)调节为45°曲线。为此,直方图均衡的目的是明确的,而不是像灰度拉升这种操作那么暧昧。

具体的直方图均衡的原理,可以参照的之前的博文。

[数字图像处理]灰度变换——直方图处理

2.1代码实现

下面是openCV的代码,由于写得比较早,可能不是那么整洁。

//-------------------------------------------------------
// 内容:OpenCV 环境的配置
//       图像的读取
//       直方图的绘制与直方图均衡的实现
//       直方图的累积分布函数(PDF)的计算
//                                    2015.4.17
//                                    by zhou fan
// ------------------------------------------------------

#include "stdafx.h"

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>  

#define   RGB_image    1
#define  Gray_image    0
#define other_image   -1

using namespace cv;
using namespace std;  

int main(int argc, char** argv[])
{
    //IplImage * ori= cvLoadImage("..\\Data\\Fig0320(4)(bottom_left).tif",Gray_image);
    IplImage * ori= cvLoadImage("..\\Data\\EV.JPG",Gray_image);

    cvNamedWindow("Original",1);        //new window,
    cvShowImage("Original",ori);        //show

    int hist_xMax = 256;      //size
    int hist_yMax = 256;
    float range[] = {0,255};  //统计范围
    float* ranges[]={range};  

    //创建直方图
    CvHistogram* hist = cvCreateHist(1,&hist_xMax,CV_HIST_ARRAY,ranges,1);
    //统计概率
    cvCalcHist(&ori,hist,
               0,            //累積タイプではない
               0);
    //归一化
    cvNormalizeHist(hist,1.0);  

    //histogram  and PDF show
    {
        Mat HistImage(hist_xMax,hist_yMax,CV_8UC3,Scalar(255,255,255));
        IplImage hist_show = HistImage;

        Mat HistPDFImage(hist_xMax,hist_yMax,CV_8UC3,Scalar(255,255,255));
        IplImage hist_PDF_show = HistPDFImage;

        float HistPDF[256] = {0};

        float max_value = 0;
        float yMax_Limt = 0.1;
        cvGetMinMaxHistValue(hist,0,&max_value,0,0); 

        for(int x=0;x<hist_xMax;x++)
        {
            float yHistVal = cvGetReal1D((hist)->bins,x);   //取得1D数据的值
            int yVal = cvRound(yHistVal*hist_yMax/yMax_Limt);  //要绘制的高度  

            HistPDF[x] = (float)((x == 0)? cvGetReal1D((hist)->bins,x):
                                           cvGetReal1D((hist)->bins,x) + HistPDF[x-1]); 

            cvLine(&hist_show,
                   cvPoint(x,hist_yMax),
                   cvPoint(x,hist_yMax - yVal),
                   CV_RGB(0,0,0)); 

            cvLine(&hist_PDF_show,
                   cvPoint(x-1,hist_yMax - cvRound(HistPDF[x-1]*hist_yMax)),
                   cvPoint(  x,hist_yMax - cvRound(HistPDF[x]*hist_yMax)),
                   CV_RGB(0,0,0)); 

            //cout << yHistVal << "         "<<(HistPDF[x])<<"\n" ;
        }  

        //想要窗口内的图片随着窗口一起扩大的话,需要使用样式 WINDOW_NORMAL
        //cvNamedWindow("Histogram",WINDOW_NORMAL);

        cvNamedWindow("Histogram",1);             //new window,
        cvShowImage("Histogram",&hist_show);        //show

        cvNamedWindow("PDF",1);             //new window,
        cvShowImage("PDF",&hist_PDF_show);        //show
    }

    //直方图均衡
    cvEqualizeHist(ori,ori);

    cvNamedWindow("Result",1);        //new window,
    cvShowImage("Result",ori);      //show

    //计算均衡后的直方图
    cvCalcHist(&ori,hist,
               0,            //非累积
               0);
    //归一化
    cvNormalizeHist(hist,1.0);  

    //histogram  and PDF show
    {
        Mat HistImage(hist_xMax,hist_yMax,CV_8UC3,Scalar(255,255,255));
        IplImage hist_show = HistImage;

        Mat HistPDFImage(hist_xMax,hist_yMax,CV_8UC3,Scalar(255,255,255));
        IplImage hist_PDF_show = HistPDFImage;

        float HistPDF[256] = {0};

        float max_value = 0;
        float yMax_Limt = 0.1;
        cvGetMinMaxHistValue(hist,0,&max_value,0,0); 

        for(int x=0;x<hist_xMax;x++)
        {
            float yHistVal = cvGetReal1D((hist)->bins,x);   //取得1D数据的值
            int yVal = cvRound(yHistVal*hist_yMax/yMax_Limt);  //要绘制的高度  

            HistPDF[x] = (float)((x == 0)? cvGetReal1D((hist)->bins,x):
                                           cvGetReal1D((hist)->bins,x) + HistPDF[x-1]); 

            cvLine(&hist_show,
                   cvPoint(x,hist_yMax),
                   cvPoint(x,hist_yMax - yVal),
                   CV_RGB(0,0,0)); 

            cvLine(&hist_PDF_show,
                   cvPoint(x-1,hist_yMax - cvRound(HistPDF[x-1]*hist_yMax)),
                   cvPoint(  x,hist_yMax - cvRound(HistPDF[x]*hist_yMax)),
                   CV_RGB(0,0,0)); 

            //cout << yHistVal << "         "<<(HistPDF[x])<<"\n" ;
        }  

        cvNamedWindow("Histogram_Result",1);             //new window,
        cvShowImage("Histogram_Result",&hist_show);        //show

        cvNamedWindow("PDF_Result",1);             //new window,
        cvShowImage("PDF_Result",&hist_PDF_show);        //show
    }

    cvWaitKey(0);  

    return (int)0;
}

2.1执行结果

执行直方图均衡前的直方图与PDF

结果的直方图与PDF

执行直方图均衡前的直方图与PDF

结果的直方图与PDF

原文发于博客:http://blog.csdn.net/thnh169/

时间: 2024-11-05 21:37:10

[openCV]直方图均衡的相关文章

(原)opencv中使用限制对比度自适应直方图均衡CLAHE

转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5462656.html 1 Ptr<CLAHE> clahe = createCLAHE(); 2 clahe->setClipLimit(4); 3 clahe->apply(ucmatGaborResize, ucmatGaborResize);

OpenCV 数字验证码识别

本文针对OpenCv入门人士,因为我也不是专门做图像的,只是为了完成一次模式识别的小作业. 主要完成的功能就是自动识别图片中的数字,图片包括正常图片,有划痕图像和有噪点图像.分别如下 先上图,看识别效果! 接下来开始来点干货了: opencv的安装与配置:这个要是展开讲可以再写一篇博文了,我当时什么都不会配个opencv麻烦死了,最后参考网上studio2012的配置方法成功了,在此略过.看到这里你的opencv还不能用的话,赶紧别往下看了,先把opencv配好再来吧! opencv基本图片操作

图像直方图均衡化增强opencv与C语言版

本文实现彩色图像的全局直方图均衡.分别对R/G/B三通道均衡,读写图片采用OpenCV.代码如下: #include <opencv2/opencv.hpp> //#include <cv.h> //#include <cxcore.h> //#include <highgui.h> #include <time.h> #include <stdio.h> #include <math.h> #include "

《OpenCV图像处理编程实例》 目录

当当网购买地址:http://product.dangdang.com/23956649.html京东网购买地址:http://item.jd.com/11929148.html 内容简介 本书以 OpenCV 开源库为基础实现图像处理领域的很多通用算法,并结合当今图像处理领域前沿技术,对多个典型工程实例进行讲解及实现.全书内容覆盖面广,由基础到进阶,各个技术点均提供详细的代码实现,以帮助读者快速上手和深入学习.本书内容共三个部分,其中 1-2 章为基础篇, 3-6 章为进阶篇, 7-9 章为高

OpenCV成长之路:图像直方图

http://ronny.blog.51cto.com/8801997/1394115 2014-04-11 13:47:27 标签:opencv 直方图 统计表 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://ronny.blog.51cto.com/8801997/1394115 一.图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的.纵坐标代表了每一种

OpenCV入门教程之四 图像直方图

一.图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的.纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比. 图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征.在实际工程中,图像直方图在特征提取.图像匹配等方面都有很好的应用.  二.利用OpenCV计算图像的直方图 OpenCV中计算图像直方图像函数是calcHist,它的参数比较多,下面分析一下它的接口和用法. void calc

基于opencv的摄像头脸部识别抓取及格式储存(python)

刚接触opencv,参照opencv的sample例子做了一个视频头像抓取的小代码,顺便一起学习着用,先上视频抓取及存储代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # -*- coding: cp936 -*- import cv2 capture=cv2.VideoCapture(0) #将capture保存为motion-jpeg,cv_fourcc为保存格式 size

直方图均衡与平台直方图

直方图均衡化(Histogram Equalization) 直方图均衡化处理的"中心思想"是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布.直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同.直方图均衡化就是把给定图像的直方图分布改变成"均匀"分布直方图分布. 直方图均衡化的主要过程 统计每一个灰度值的像素点数和所占的百分比 累加每一个灰度值的百分比 利用新的灰度值的百分比,重新计算每一个灰度

【循序渐进地学好OpenCV&amp;3】OpenCV 2.0 API

概述 OpenCV(Open Source Computer Vision Library)是基于BSD开源许可协议的一套计算机视觉开源库,里面包含了几百个计算机视觉算法.在包括物体识别.人脸识别.图像处理等在内的多种计算机视觉应用领域中被大量应用. OpenCV的API目前分为1.0和2.0版本(3.0的正式版本在今年也已经出来了,但目前没有去尝试过),1.0版本是用C语言实现的,2.0主要是C++,2.0版本的已显著优化,所以我们学习的也将是2.0版本的OpenCV,我们在上一篇的实例其实使