欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

灰度直方图及均衡化的实现

程序员文章站 2024-03-16 12:02:58
...

一、灰度直方图,就是对图像像素灰度值的统计,对于灰度图像,只有一个通道,其灰度范围为0-255,因此只需要将图像转成灰度图像,然后对不同灰度值进行像素个数统计,画出其直方图。下面借助Opencv,但为了让初学者更好的理解这个概念,直方图的代码按照自己的理解写一遍,这样也能锻炼自己的编程能力。

代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
	Mat image=imread("test.png",1);
	if(image.empty())
	{
		cout<<"failed to read the image"<<endl;
		return 0;
	}
	imshow("image",image);
	Mat grayImage;
	cvtColor(image,grayImage,CV_BGR2GRAY);    
	//遍历图像所有像素的灰度值
	int grayVal;
	vector<int> vectGrayVal;      
	for (int i=0;i<image.rows;i++)
	{
		for (int j=0;j<image.cols;j++)
		{
			grayVal=grayImage.at<uchar>(i,j);
			vectGrayVal.push_back(grayVal);
		}
	}
	//统计各个灰度值的像素个数
	int count=0;
	vector<int> vectCount;
	for (int k=0;k<256;k++)         
	{
		for (int i=0;i<vectGrayVal.size();i++)
		{
			if (vectGrayVal[i] == k)
			{
				count++;
			}
		}
		vectCount.push_back(count);
		count=0;
	}
	//画出直方图
	int maxCount=0;
	for (int k=0;k<255;k++)
	{
		if (maxCount<vectCount[k])
		{
			maxCount=vectCount[k];
		}
	}
	namedWindow("hist",WINDOW_NORMAL);
	Mat hist(maxCount,256,CV_8U,Scalar(255));
	for (int k=0;k<256;k++)
	{
		line(hist,Point(k,maxCount),Point(k,maxCount-vectCount[k]),Scalar(0));
	}
	imshow("hist",hist);
	waitKey(0);
	return 1;
}

灰度直方图及均衡化的实现    灰度直方图及均衡化的实现

效果很直观,但效率很差。

二、对灰度图实行均衡化,可以使图像对比度增强。直方图均衡化增强了靠近直方图极大值附近的亮度的对比度,减小了极小值附近的对比度。直方图均衡化的数学原理可以去看《图像处理、分析与机器视觉》中的第5章,讲的很清楚,而且也有算法原理,下面贴算法原理的图:

灰度直方图及均衡化的实现

 

灰度直方图及均衡化的实现

根据上述原理,其代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

void equalizeHist(Mat& image, Mat& result)
{
	if (image.channels() !=1)
	{
		cvtColor(image, image, CV_BGR2GRAY);
		imshow("gray", image);
	}
	vector<int> vectGrayVal;
	int grayVal;
	int Row = image.rows;
	int Col = image.cols;
	for (int i = 0; i < Row;i++)
	{
		for (int j = 0; j < Col;j++)
		{
			grayVal = image.at<uchar>(i, j);
			vectGrayVal.push_back(grayVal);
		}
	}
	int count = 0;
	vector<int> vectCount;
	for (int k = 0; k < 256;k++)
	{
		for (int i = 0; i < vectGrayVal.size(); i++)
		{
			if (vectGrayVal[i]==k)
			{
				count++;
			}
		}
		vectCount.push_back(count);
		count = 0;
	}
	result = Mat(Row, Col, CV_8UC1);
	//均衡化
	for (int k = 0; k < 256;k++)
	{
		if (k!=0)
		{
			vectCount[k] = vectCount[k - 1] + vectCount[k];
		}		
	}
	for (int k = 0; k < 256; k++)
	{
		vectCount[k] = vectCount[k]*255 / (Row*Col);
	}

	for (int i = 0; i < Row; i++)
	{
		for (int j = 0; j < Col; j++)
		{
			result.at<uchar>(i, j) = vectCount[image.at<uchar>(i, j)];
		}
	}
}

void main()
{
	Mat image = imread("test.png", 1);
	imshow("image", image);
	Mat result;
	equalizeHist(image, result);
	imwrite("2.png",result);
	cvtColor(result, result, CV_GRAY2BGR);
	imshow("result", result);
	waitKey(0);
	return;
}

灰度直方图及均衡化的实现

下图为处理后的图片的灰度直方图,可以看出其灰度分布并没有集中在某一区域。

灰度直方图及均衡化的实现