OpenCV图像处理开发实战(13) --直方图与均衡化

1、前言

(1)直方图
灰度直方图是灰度级的统计图,统计图像中各个灰度级的像元的个数。确定图像像元的灰度值范围,以适当的灰度间隔为单位将其划分为若干等级,以横轴表示灰度级,以纵轴表示每一灰度级具有的像元数或该像元数占总像元数的比例值,做出的条形统计图即为灰度直方图。

直方图反映了图像中的灰度分布规律,描述每个灰度级具有的像元个数。

(2)直方图均衡化
利用直方图实现灰度映射从而达到图像增强的目的。进行归一化的一个非常好的方法,也可以增强图像的对比度。

2、有关函数

(1)equalizeHist() 均一化

void equalizeHist( InputArray src, OutputArray dst )

(2)calcHist()

void calcHist(
const Mat* images, // 源图像数组,它们有同样的位深CV_8U或 CV_32F ,同样的尺寸;图像阵列中的每一个图像都可以有任意多个通道;
int nimages, // 源图像的数目。
const int* channels, // 维度通道序列,第一幅图像的通道标号从0~image[0].channels( )-1。Image[0]表示图像数组中的第一幅图像,channels()表示该图像的通道数量。同理,图像阵列中的第二幅图像,通道标号从image[0].channerls( )开始,到image[1].channels( )-1为止;第三、四幅图像的通道标号顺序依此类推;也就是说图像阵列中的所有图像的通道根据图像排列顺序,排成一个通道队列。
InputArray mask,// 可选择的mask。如果该矩阵不空的话,它必须是一个8-bit的矩阵,与images[i]同尺寸。在图像中,只有被mask覆盖的区域的像素才参与直方图统计。如果这个参数想用默认值,输入Mat()就可以了。
OutputArray hist, // 输出直方图, 它是一个稠密或稀疏矩阵,具有dims个维度;
int dims, // 直方图的维度,一定是正值, CV_MAX_DIMS(当前OpenCV版本是32个);
const int* histSize,// 数组,即histSize[i]表示第i个维度上bin的个数;这里的维度可以理解为通道。
const float** ranges, // 当uniform=true时,ranges是多个二元数组组成的数组;当uniform=false时,ranges是多元数组组成的数组。
bool uniform = true, // 标识,用于说明直方条bin是否是均匀等宽的。
bool accumulate = false // 累积标识。如果该项设置,当直方图重新分配时,直方图在开始清零。这个特征可以使你通过几幅图像,累积计算一个简单的直方图,或者及时更新直方图。
);

(3)compareHist()直方图比较

double compareHist(
const SparseMat& H1,
const SparseMat& H2,
int method // 指定比较方法
)
int method :
HISTCMP_CORREL // 相关性,越接近1表示越像
HISTCMP_CHISQR // 卡方, 越接近0表示越像
HISTCMP_INTERSECT // 十字交叉性, 数值越大表示越像
HISTCMP_BHATTACHARYYA(=HISTCMP_HELLINGER)// 常态分布比对的BHATTACHARYYA 巴氏距离距离法 越接近0表示越像
HISTCMP_CHISQR_ALT //
HISTCMP_KL_DIV //

3、实战源代码

Mat equalizeImg;
	cvtColor(srcImg1, grayImg, CV_BGR2GRAY);

	equalizeHist(grayImg, equalizeImg);

	vector<Mat> planes;
	split(srcImg1, planes);
	Mat histMat[3];
	Mat histMat_norm[3];
	int histSize = 256;
	float range[] = { 0,256 };
	Mat histMat1;
	const float *histRanges = { range };

	for (int i = 0; i < 3; i++)
	{
		calcHist(&planes[i], 1, 0, Mat(), histMat1, 1, &histSize, &histRanges, true, false);
		normalize(histMat1, histMat_norm[i], 0, srcImg1.rows, NORM_MINMAX, -1, Mat());
	}
	Mat histImage(srcImg1.rows, 256 * 4, CV_8UC3, Scalar(0, 0, 0));

	for (int i = 0; i < 3; i++)
	{
		int rows = histMat_norm[i].rows;
		for (int h = 0; h < rows; h++)
		{
			int h1 = histMat_norm[i].at<float>(h, 0);
			int x = h * 4 + i;
			line(histImage,
				Point(x, srcImg1.rows),
				Point(x, srcImg1.rows - h1),
				Scalar(255 * (i == 2), 255 * (i == 1), 255*(i==0))
				);
		}
	}

	double val = compareHist(histMat_norm[1], histMat_norm[0], HISTCMP_CORREL);
	string text;
	char ctext[20];
	sprintf(ctext, "compare=%f", val);
	text = ctext;
	putText(histImage, text, Point(20, 30), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));

	imshow("灰度图", grayImg);// 显示
	imshow("均一化图", equalizeImg);// 显示
	imshow("直方图", histImage);// 显示
	imshow("灰度图", grayImg);// 显示
	imshow("均一化图", equalizeImg);// 显示
	imshow("直方图", histImage);// 显示

在这里插入图片描述在这里插入图片描述

4、下载工程项目源代码

本文源码在Debug – x64下编译通过。

ZIP包中包含开发环境,下载解压可直接编译运行。

下载源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值