您的位置:首页 > 运维架构

直方图均衡原理及opencv实现

2016-12-24 21:43 323 查看
        直方图均衡化处理技术是用累计分布函数作变换函数的直方图修正方法,用累积分布函数作为变换函数可产生一幅灰度级分布具有均匀概率密度的图像。其在数学上的变换函数如下:



其中,w 是积分的假变量。r 表示待处理图像的灰度,区间为[0,L-1],且 r = 0 表示黑色,r = L-1 表示白色。s 表示已处理图像的灰度,区间为[0,L-1],且 s = 0 表示黑色,s = L-1 表示白色。公式右边是随机变量 r 的累积分布函数。
该变换的离散变换形式为:



其中,MN 是图像中像素的总数,nk 是灰度为 rk的像素个数。与 rk 相对的 Pr(rk)图形通常称为直方图。

     使用opencv实现,其代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

/* 输入原图,画出该图的直方图 */
int DrawHist(Mat image1, Mat* hist1)
{
// 获取直方图
int histsize[] = { 256 }; // 项的数量
float range[] = { 0,256 }; // 像素值的范围
const float *ranges[] = { range };
int channels[] = { 0 }; // 通道

Mat hist; // 直方图结果
calcHist(&image1, 1, channels, Mat(), hist, 1, histsize, ranges);

// 以图形方式显示直方图
// 获取最大值和最小值
double maxVal = 0;
double minVal = 0;
minMaxLoc(hist, &minVal, &maxVal, 0, 0);

// 显示直方图的图像
Mat hist_img(256, 256, CV_8U, Scalar(255));

// 设置最高点为图的90%
int high_pt = static_cast<int>(0.9 * 256);

// 每个条目绘制一条垂直线
for (int h = 0; h < 256; h++) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*high_pt / maxVal);
line(hist_img, Point(h, 256), Point(h, 256 - intensity),Scalar::all(0));
}
hist_img.copyTo(*hist1);

return 0;

}

int main(int argc, char* argv[]) {

// 读入图片
Mat image1 = imread("2.tif"),image2;

// 把图片转为灰度图
cvtColor(image1, image1, CV_RGB2GRAY);

// 直方图均衡化前后直方图
Mat hist1,hist2;

DrawHist(image1, &hist1);

equalizeHist(image1, image2);

DrawHist(image2, &hist2);

Mat image(image1.rows, image1.cols * 2+5, CV_8U);
Mat hist(hist1.rows, hist1.cols * 2+5, CV_8U);

image1.copyTo(image(Rect(0, 0, image1.cols, image1.rows)));
image2.copyTo(image(Rect(image1.cols+5,0, image1.cols, image1.rows)));

hist1.copyTo(hist(Rect(0, 0, hist1.cols, hist1.rows)));
hist2.copyTo(hist(Rect(hist1.cols+5,0, hist1.cols, hist1.rows)));

imshow("原图及直方图均衡化后的图", image);
imshow("原图直方图及均衡后的直方图",hist);

waitKey(0);
return 0;
}



结果如下:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opencv 直方图均衡