C/C++图像处理实验(三)——灰度直方图

简介

灰度直方图反映的是一幅图像中各灰度级像素出现的频率或者次数关系。

性质

  1. 灰度直方图只能反映图像的灰度分布状况,不能反映图像像素的位置,丢失了像素的位置信息。
  2. 一幅图像的灰度直方图是确定的,反之不然。
  3. 将图像分为多个区域,各个区域的直方图之和为原图像的直方图。

作用

  1. 直方图的作用可以判断图像像素分布是否合适,如果像素集中在某个区域,则意味着图像的对比度较低,图像有可能不清晰。
  2. 直方图可以用于确定图像的二值化阈值。
  3. 用于计算物体的图像面积。
  4. 计算图像信息量H(熵)
    H = − ∑ i = 0 L − 1 p i log ⁡ 2 p i H=-\sum_{i=0}^{L-1}p_{i}\log_{2}p_{i} H=i=0L1pilog2pi
    式子中的 p i p_{i} pi为各灰度级i的出现概率。

实现过程

//计算图像的灰度直方图,传入图像二维数组和存储直方图的数组,存储直方图数据的数组长度必须不小于256
void Histogram(unsigned char img_gray[][Width],  unsigned int height, unsigned int width,unsigned int histogram[])
{
	for (int i = 0; i < 256; i++)
	{
		histogram[i] = 0;
	}//需要注意的是,在C语言中,未初始化的全局变量的数组默认值为0,不需要手动初始化为0,但是局部变量要
	//所以此处的初始化可以根据实际传入的histogram数组类型进行取舍
	for (unsigned int i = 0; i < height; i++)
	{
		for (unsigned int j = 0; j < width; j++)
		{
			histogram[img_gray[i][j]]++;
		}
	}
}

主函数调用过程:

#include <opencv2/opencv.hpp>
#include "test_algorithm/test.h"
using namespace cv;
int main()
{
	Mat image_gray = imread("./test.png", 0);
	unsigned char img_gray[Height][Width];
	unsigned int hist[256];
	Mat2array(image_gray, img_gray,Height,Width);
	Histogram(img_gray,Height,Width, hist);
	Mat img_test = plot_Line_chart(hist, 256);
	imshow("image_test", img_test);
	waitKey(0);
	return 0;
}

为了让结果可视化,编写一个函数将得到的直方图数据绘制出来,横轴是像素值分布,纵轴是像素点的个数,为了让图像在纵轴上得到拉伸,以最多的像素值的数量进行归一化处理:

//将输入的一维数组绘制成折线图,输入为一维数组和它的长度
cv::Mat plot_Line_chart(unsigned int y[], unsigned int col)
{
	unsigned int max = y[0];
	for (unsigned int i = 1; i < col; i++)
	{
		max = (max > y[i]) ? max : y[i];
	}//选出数组中的最大值作为归一化的分母
	cv::Mat hist(480, 640, CV_8UC1, cv::Scalar(0));

	line(hist, cv::Point(20, 0), cv::Point(20, 480), cv::Scalar(255, 255, 255), 1);
	line(hist, cv::Point(0, 460), cv::Point(640, 460 ), cv::Scalar(255, 255, 255), 1);//画出两个轴
	if (max == 0)
	{
		return hist;
	}
	for (unsigned int i = 0; i < col-1; i++)
	{
		//在绘制过程中以数组最大值为顶点,其余点的坐标由其与最大值的比值得出
		line(hist, cv::Point((int)(i*600/col) + 20,460 - (unsigned int)(y[i] * 450 / max) ), cv::Point((int)(i * 600 / col) + 20,460 - (unsigned int)(y[i+1] * 450 / max)), cv::Scalar(255, 255, 255), 1); // 绘制一条白色的直线,宽度为1
	}
	return hist;
}

运行结果

在这里插入图片描述

总结

灰度直方图是图像较为重要的性质,常用于其它算法的预处理,如大津法等。灰度直方图有多种呈现形式,如本次实验中总结用数组存储各像素值出现的个数,也有的还会在这个基础上,将数值与图像总的像素数量相除,得到其出现的频率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>