opencv直方图之查表法,均衡化

查表法中的表是一个一维,256的数组,其意思在于对于一个像素点的灰度值进行变换,即如果原像素的灰度值为i,则查表转化后假设负片效果,就是灰度值为255-i。

在画出直方图后,想均衡化,增强对比度的话,可以这样,检测直方图中非零项的最低和最高,将最低设置成0,最高设置成255,其中间则按这种规律转化。

以下为代码:

// opencv_2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv245.h>

using namespace cv;
using namespace std;


class Histogram1D
{
private:
	int histsize[1];
	float hranges[2];
	const float* ranges[1];
	int channels[1];

public:
	Histogram1D() 	
	{
		histsize[0] = 256 ;
		hranges[0] = 0.0;
		hranges[1] = 255.0;
		ranges[0] = hranges;
		channels[0] = 0;
		
	}

	Mat getHistogram(const Mat &image);
	Mat getHistogramImage(const Mat &image);
	Mat applyLookUp(const Mat &image);
	Mat stretch(const Mat &image, int minValue);
	
};

Mat Histogram1D::getHistogram(const Mat &image)
{
	Mat hist;
	calcHist(&image, 1, channels, Mat(), hist, 1, histsize, ranges);
	return hist;
}


Mat Histogram1D::getHistogramImage(const Mat &image)
{
	Mat hist = getHistogram(image);

	double maxVal = 0;
	double minVal = 0;
	minMaxLoc(hist, &minVal, &maxVal);

	Mat histImg(histsize[0],histsize[0],CV_8UC3,Scalar(255,255,255));

	int hpt = static_cast<int>(0.9*histsize[0]);

	for (int h = 0; h < histsize[0]; h++)
	{
		float binVal = hist.at<float>(h);
		int intensity = static_cast<int>(binVal * hpt / maxVal);
		line(histImg, Point(h, histsize[0]),
			          Point(h,histsize[0] - intensity),
					  Scalar(0,255,0));
	}

	return histImg;



}

//Mat Histogram1D::applyLookUp(const Mat &image)
//{
//	Mat result;
//	Mat lookup(1, 256, CV_8U);
//
//	for (int i = 0; i < 256; i++)
//	{
//		lookup.at<uchar>(i) = 255 -i;
//	}
//
//
//	LUT(image, lookup, result);
//	return result;
//}


Mat Histogram1D::stretch(const Mat &image, int minValue  = 0 )
{
	Mat hist = getHistogram(image);
	int imin = 0;
	for (; imin < histsize[0]; imin++)
	{
		if (hist.at<float>(imin) > minValue )
		{
			break;
		}
	}

	int imax = histsize[0] - 1;
    for(; imax >=0; imax--)
	{
		if (hist.at<float>(imax) > minValue)
		{
			break;
		}
	}

	int dim(256);
	Mat lookup(1, &dim, CV_8U);
	for (int i = 0; i < 256; i++)
	{
		if (i < imin )
		{
			lookup.at<uchar>(i) = 0;
		}
		else if (i > imax)
		{
			lookup.at<uchar>(i) = 255;
		}
		else
		{
			lookup.at<uchar>(i) = static_cast<uchar>(255.0*(i - imin)/(imax - imin) + 0.5);
		}
	}

	Mat result;
	LUT(image,lookup,result);

	return result;

}


int _tmain(int argc, _TCHAR* argv[])
{
	Mat image = imread("C:\\Users\\sony\\Desktop\\pic\\Lena.jpg",0);
	int sum = 0;
	int max = 0;
	Histogram1D h;
	/*Mat histo = h.getHistogramImage(image);*/

	//for (int i = 0; i < 256; i++)
	//{
	//	if (histo.at<float>(i) > max)
	//	{
	//		max = histo.at<float>(i);
	//	}
	//	/*cout<<"Value"<<i<<"="<<histo.at<float>(i)<<endl;*/
	//	/*sum += histo.at<float>(i);*/
	//	
	//}
	//cout<<max<<endl;

	/*Mat dst = h.applyLookUp(image);*/

	Mat dst = h.stretch(image);
	imshow("src",image);
	imshow("dst", dst);

	imshow("src H", h.getHistogramImage(image));
	imshow("dst H", h.getHistogramImage(dst));
	waitKey(0);
	

	return 0;
}

效果图如下:

opencv直方图之查表法,均衡化_第1张图片      opencv直方图之查表法,均衡化_第2张图片

                              原图                                                                         处理后

你可能感兴趣的:(opencv直方图之查表法,均衡化)