图像处理opencv直方图均值化-学习笔记2

原创 2015年11月21日 14:33:33

直方图均值化

实验简述

实验要求:
下载一曝光不足和一曝光过度的彩色图片,对彩色图片进行直方图均衡化,并保存和展示。

原理简述

直方图概念

直方图(Histogram)又称质量分布图、柱状图,是一种统计报告图,也是表示资料变化情况的一种主要工具。直方图由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据类型,纵轴表示分布情况——–百度百科

图像的直方图是以横坐标为像素值(本实验以[0-255]为范围),纵坐标为像素个数(图像以横坐标值为像素值的个数)。

直方图均值化

直方图均值化直观感受

直方图均值化就是把集中在某个值域的像素按某种方法拉伸到整个值域,获得更美观的视觉。
附上图片更容易说明。

未均值化的直方图
这是一张集中于小像素的直方图。

均值化后
均值化后的直方图。

均值化后,图片就更平和不会出现偏亮或偏暗。
附上图片更容易说明。

均值化前图像
均值化前图像

均值化后图像
这里写图片描述

直方图均值化一种原理说明

通过函数将一个小的范围映射到一个大范围,一种原理就是按如下公式进行映射

h(v)=round((cdf(v)-cdfmin)/(M*N-cdfmin)*(L-1))

cdf(v)为累加函数代表像素值小于等于v的个数。
cdfmin为累加函数。
M*N 分别代表长宽像素,其乘积为整幅图的像素。
round()取整函数。
L为256,L-1像素最大值255。

opencv实现

直方图均值化

1。因为直方图均值化需要单通道图像,所以需用split()函数进行分通道,最后需用 merge(bgr, 3, bgr_res);函数合并通道。
代码如下

Mat img = imread("D:\\\\2.jpg");
    Mat bgr[3];
    split(img, bgr);

2。opencv提供均值化函数,计算的必为单通道的图像。

#include "opencv2/imgproc/imgproc.hpp" //直方图均值化函数头件for (int i = 0;i < 3;i++)
equalizeHist(bgr[i], bgr[i]);

3。注意计算直方图时,计算的必为单通道的图像。

    MatND hist;//直方图
    int channels[] = { 0 };//所传图像通道
    int dims = 1;//直方图维数
    int histSize[] = { 256,256 };//直方图大小256*256的正方形
    float granges[] = { 0, 255 };//直方图搜索像素范围
    const float *ranges[] = { granges };//因为有多维度的直方图所以,要将范围以指针形式传出。比如,如果二维就可以再传个范围
    calcHist(&image, 1, channels, Mat(), hist, dims, histSize, ranges);/*第一个参数计算图像,第二个参数为所传图像个数,
    第四个参数,为掩码统计部分图像时用(统计整幅图像则按上所填即可),其余参数均已说明*/

4。计算完成我们现在需要显示直方图。

int scaleY = 1, scaleX = 1;
    Mat showImage(scaleY * 256, scaleX * 256, CV_8U, Scalar(255));
    int i;
    double maxValue = 0;
    minMaxLoc(hist, 0, &maxValue, 0, 0);
    for (i = 0; i < 256; i++)
    {
        float value = hist.at<float>(i);
        int intensity = saturate_cast<int>(256 * scaleY - 256 * scaleY * (value / maxValue));
        rectangle(showImage, Point(i*scaleX, scaleY * 256 - 1), Point((i + 1)*scaleX - 1, intensity), Scalar(0));
    }

简单解释一下scale为最终显示直方图的的规格。1为 256*256;
hist.at(i);(为访问hist矩阵元素的值,即为像素为(i)的值有多少个);
minMaxLoc计算出hist图的最大值并传入maxValue;
for循环为在直方图上刻画一个个小矩形条;

声明: 画图的代码参考了网上的一些优秀的代码。
这样就完成了直方图均值化。

完整源码如下

#include<iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include "opencv2/imgproc/imgproc.hpp" //直方图均值化函数头文件
using namespace std;
using namespace cv;

MatND getHistogram(Mat &image);
Mat getHistogramImage(Mat &image, int scaleX, int scaleY);
int main()
{
    Mat img = imread("D:\\乱\\2.jpg");
    Mat bgr[3];
    Mat bgr_res;
    /**********************************************/

    split(img, bgr);


    Mat hist1 = getHistogramImage(bgr[0], 1, 1);

    for (int i = 0;i < 3;i++)
    equalizeHist(bgr[i], bgr[i]);

    Mat hist2 = getHistogramImage(bgr[0], 1, 1);


    merge(bgr, 3, bgr_res);
    namedWindow("原直方图");
    imshow("原直方图", hist1);
    namedWindow("输出直方图");
    imshow("输出直方图", hist2);
    namedWindow("输出均值化后图");
    imshow("输出均值化后图", bgr_res);
    waitKey(0);
    return 0;
}




Mat getHistogramImage(Mat &image, int scaleX = 1, int scaleY = 1) 
{
    MatND hist;
    int channels[] = { 0 };
    int dims = 1;
    int histSize[] = { 256,256 };
    float granges[] = { 0, 255 };
    const float *ranges[] = { granges };
    calcHist(&image, 1, channels, Mat(), hist, dims, histSize, ranges);



    Mat showImage(scaleY * 256, scaleX * 256, CV_8U, Scalar(255));
    double maxValue = 0;
    minMaxLoc(hist, 0, &maxValue, 0, 0);
    for (int i = 0; i < 256; i++)
    {
        float value = hist.at<float>(i);
        int intensity = saturate_cast<int>(256 * scaleY - 256 * scaleY * (value / maxValue));
        rectangle(showImage, Point(i*scaleX, scaleY * 256 - 1), Point((i + 1)*scaleX - 1, intensity), Scalar(0));
    }
    return showImage;

}

opencv学习笔记9 直方图均衡化并绘制直方图

我第一次做绘制直方图的时候走了不少弯路,现将我学习直方图均衡化并将直方图绘制出来的学习心得发表出来,希望能帮到需要此知识的同学。 此博文主要讲解进行直方图均衡化需要用到的函数以及如何在一幅图像上将直方...
  • tercel_zhang
  • tercel_zhang
  • 2015年01月05日 15:16
  • 1313

图像处理理论(一)——直方图、二值化、滤波基础

直方图、二值化、滤波基础
  • antkillerfarm
  • antkillerfarm
  • 2016年08月22日 10:44
  • 5740

用C++(OpenCV)自己实现彩色直方图均衡化

对于直方图均衡化,我的理解是一个图像原来的像素集中在一个灰度范围里,我们对这种图不敏感,因为其灰度值集中,变化不明显。如果我们把这些像素点的灰度范围扩大,图像就会显得比较清晰。直方图均衡化就是通过一个...
  • Xiao13Yu14
  • Xiao13Yu14
  • 2015年05月28日 10:32
  • 2044

openCV—Python(8)—— 图像直方图及其直方图均衡化

一、函数简介1、calcHist—计算图像直方图函数原型:calcHist(images, channels, mask, histSize, ranges, hist=None, accumulat...
  • jnulzl
  • jnulzl
  • 2015年07月31日 16:02
  • 4616

Python OpenCV -- 直方图均衡化(十三)

直方图均衡化     直方图是图像中像素强度分布的图形表达方式。它统计了每一个强度值所具有的像素个数。                                                ...
  • u013220584
  • u013220584
  • 2014年02月25日 01:18
  • 2157

直方图均衡化

直方图均衡化的英文名称是Histogram Equalization.    图像对比度增强的方法可以分成两类:一类是直接对比度增强方法;另一类是间接对比度增强方法。直方图拉伸和直方图均衡化是两种最...
  • gflytu
  • gflytu
  • 2015年11月26日 22:44
  • 3174

opencv直方图均衡化算法及实现

1、为什么要直方图均衡化很多时候,我们的图片看起来的效果不是那么的清晰,这时候可以对图像进行一些处理来扩大图像像素值显示的范围。例如有些图像整体像素值偏低,图像中的一些特征看的不是很清晰,只是隐约看到...
  • qq_29441995
  • qq_29441995
  • 2016年09月11日 13:52
  • 481

彩色图像直方图均衡化 --- 基于OpenCV中EqualizeHist_Demo实现

1. 灰度图像直方图均衡化 2.
  • xdsheng0818
  • xdsheng0818
  • 2014年09月12日 16:48
  • 8118

Opencv2系列学习笔记4(灰度直方图)

和之前的一篇blog【http://blog.csdn.net/lu597203933/article/details/14104505】一样,这篇是opencv2的Mat格式。 一:一维直方图 C...
  • Lu597203933
  • Lu597203933
  • 2013年11月24日 21:10
  • 5790

opencv 2.x学习笔记(十二)直方图均衡化

对于前面的几篇文章的了解之后,接下来,我们将sh
  • zhbmd
  • zhbmd
  • 2014年07月16日 21:12
  • 846
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图像处理opencv直方图均值化-学习笔记2
举报原因:
原因补充:

(最多只允许输入30个字)