查表法中的表是一个一维,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; }
原图 处理后