接着上节内容,本节添加两个方法 stretch() 方法和 applyLookUp() 方法。第一个方法用于拉伸直方图的准备工作,即排除直方图中没有像素值存在的项;第二个方法用查表法拉伸图像。现在贴出完整代码,Histogram1D.h 代码段如下:
#ifndef HISTOGRAM1D_H #define HISTOGRAM1D_H #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; class Histogram1D { public: Histogram1D(); MatND getHistogram(const Mat &source); Mat getHistogramImage(const Mat &source); Mat stretch(const Mat &source, int minValue);//新方法 Mat applyLookUp(const Mat &source, const Mat &lookup);//新方法 private: int histSize[1]; //直方图项数 int channels[1]; //通道数量 float histMinMax[2]; //像素最小值最大值 const float* ranges[1]; //像素值范围 }; #endif // HISTOGRAM1D_H
Histogram1D.cpp 代码段如下:
#include "histogram1d.h" Histogram1D::Histogram1D() { //1D参数初始化 histSize[0] = 256; histMinMax[0] = 0.0; histMinMax[1] = 255.0; ranges[0] = histMinMax; channels[0] = 0; } MatND Histogram1D::getHistogram(const Mat &source) { MatND Hist; calcHist(&source, 1, channels, Mat(), Hist, 1, histSize, ranges); return Hist; } Mat Histogram1D::getHistogramImage(const Mat &source) { MatND hist = getHistogram(source);//计算直方图 double maxVal = 0; double minVal = 0; minMaxLoc(hist, &minVal, &maxVal);//获取最大值和最小值 Mat histImg(histSize[0], histSize[0], CV_8U, Scalar(255));//用于显示直方图图像 int topPoint = static_cast<int>(0.9*histSize[0]); for ( int i = 0; i < histSize[0]; i ++ ) { float binVal = hist.at<float>(i); int intensity = static_cast<int>(binVal*topPoint/maxVal); line(histImg, Point(i, histSize[0]), Point(i, histSize[0]-intensity), Scalar::all(0)); } return histImg; } Mat Histogram1D::stretch(const Mat &source, int minValue = 0) { MatND hist = getHistogram(source);//计算直方图 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<float>(i) = 255; else lookup.at<uchar>(i) = static_cast<uchar>(255.0*(i-imin)/(imax-imin) + 0.5); } Mat result; result = applyLookUp( source, lookup ); return result; } Mat Histogram1D::applyLookUp(const Mat &source, const Mat &lookup) { Mat result; LUT( source, lookup, result); return result; }
函数介绍:
LUT() 为 OpenCV 函数,第一个参数为输入图像,第三个参数为输出图像,第二个参数是设定好的1D拉伸直方图向量,第四个参数默认为0,也必须为0,否则会报错。
主函数 main.cpp 代码如下:
#include <QCoreApplication> #include "histogram1d.h" using namespace cv; using namespace std; int main() { Mat src = imread("lena.jpg",0); Mat result; Histogram1D Hg; result = Hg.stretch(src, 50); Mat srcHg = Hg.getHistogramImage(src); Mat rltHg = Hg.getHistogramImage(result); namedWindow("src", 0); imshow("src", src); namedWindow("srcHg", 0); imshow("srcHg", srcHg); namedWindow("result", 0); imshow("result", result); namedWindow("rltHg", 0); imshow("rltHg", rltHg); waitKey(0); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-06 20:39:26