学院网站的作用,潮州专业网站建设报价,做一个小说网站需要多少钱,泰安五险一金的工作最新招聘目录
1.直方图统计
2.直方图均衡化
3.直方图匹配 1.直方图统计 直方图统计是一种用于分析图像或数据的统计方法#xff0c;它通过统计每个数值或像素值的频率分布来了解数据的分布情况。 在OpenCV中#xff0c;可以使用函数cv::calcHist()来计算图像的直方图。
calcHist(…目录
1.直方图统计
2.直方图均衡化
3.直方图匹配 1.直方图统计 直方图统计是一种用于分析图像或数据的统计方法它通过统计每个数值或像素值的频率分布来了解数据的分布情况。 在OpenCV中可以使用函数cv::calcHist()来计算图像的直方图。
calcHist() 函数的原型如下 void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform true, bool accumulate false); 参数说明 images: 输入图像数组可以是单张图像或多张图像的数组。 nimages: 输入图像的数量。 channels: 要计算直方图的通道索引数组。例如对于灰度图像只有一个通道因此 channels 设置为 {0}而对于彩色图像可以指定 {0, 1, 2} 对应于 B、G、R 三个通道。 mask: 掩码图像用于指定计算直方图的区域。如果不需要使用掩码可以传入空的 Mat()。 hist: 输出的直方图用于存储计算结果。 dims: 直方图的维度通常为 1。 histSize: 直方图的大小即每个维度的条目数量。 ranges: 直方图的范围可以使用 {0, 256} 表示像素值范围为 [0, 256)。 uniform: 指示直方图条目是否均匀分布默认为 true。 accumulate: 指示是否累积直方图默认为 false。
下面是一个示例代码展示如何使用cv::calcHist()函数计算图像的直方图
#include opencv2/opencv.hpp
void hist(Mat image){
// 定义直方图参数
int histSize 256; // 直方图条目数量
const int channels[1]{0};//通道索引
float range[] { 0, 256 }; // 像素值范围
const float* histRange { range };
bool uniform true; // 直方图条目是否均匀分布
bool accumulate false; // 直方图是否累积
// 计算直方图
cv::Mat hist;
cv::calcHist(image, 1, channels, cv::Mat(), hist, 1, histSize, histRange, uniform, accumulate);// 绘制直方图
int histWidth 512;
int histHeight 400;
int binWidth cvRound((double)histWidth / histSize);
cv::Mat histImage(histHeight, histWidth, CV_8UC4, cv::Scalar(0, 0, 0));
cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());
for (int i 1; i histSize; i){
cv::line(histImage, cv::Point(binWidth * (i - 1), histHeight - cvRound(hist.atfloat(i - 1))),
cv::Point(binWidth * (i), histHeight - cvRound(hist.atfloat(i))),
cv::Scalar(255, 255, 255), 2, 8, 0);
}
// 显示直方图
cv::imwrite(/sdcard/DCIM/histImage.jpg, histImage);
}
示例代码中将原图像image转换为单通道灰度图像。然后定义了直方图的参数包括直方图条目数量、像素值范围、均匀性和累积性。接下来使用 cv::calcHist() 函数计算了图像的直方图存储在 hist 中。最后通过绘制直方图数据到 histImage 中实现了直方图的可视化。 2.直方图均衡化 直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分布图像像素值的频率分布来增强图像的亮度和细节。
在OpenCV中可以使用cv::equalizeHist()函数来进行直方图均衡化。该函数的原型如下 void equalizeHist(InputArray src, OutputArray dst); 参数说明 src:需要直方图均衡化的CV 8UC1图像。 dst: 直方图均衡化后的输出图像与src具有相同尺寸和数据类型
下面是一个示例代码展示如何使用cv::equalizeHist()函数来进行直方图均衡化
#include opencv2/opencv.hpp
void drawHist(Mat hist,string name){//归一化并绘制直方图函数int histSize 256; // 直方图条目数量// 绘制直方图int histWidth 512;int histHeight 400;int binWidth cvRound((double)histWidth / histSize);cv::Mat histImage(histHeight, histWidth, CV_8UC4, cv::Scalar(0, 0, 0));cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());for (int i 1; i histSize; i){cv::line(histImage, cv::Point(binWidth * (i - 1), histHeight - cvRound(hist.atfloat(i - 1))),cv::Point(binWidth * (i), histHeight - cvRound(hist.atfloat(i))),cv::Scalar(255, 255, 255), 2, 8, 0);}// 显示直方图cv::imwrite(/sdcard/DCIM/name.jpg, histImage);}
void EqualImage(Mat image){//灰度化Mat gray;cvtColor(image,gray,COLOR_BGR2GRAY);//将灰度图进行直方图均衡化Mat equalImg;equalizeHist(gray,equalImg);cv::imwrite(/sdcard/DCIM/equalImg.jpg, equalImg);// 定义直方图参数int histSize 256; // 直方图条目数量const int channels[1]{0};//通道索引float range[] { 0, 256 }; // 像素值范围const float* histRange { range };bool uniform true; // 直方图条目是否均匀分布bool accumulate false; // 直方图是否累积// 计算直方图cv::Mat hist;cv::calcHist(equalImg, 1, channels, cv::Mat(), hist, 1, histSize, histRange, uniform, accumulate);drawHist(hist,hist1);}
示例代码中将原图像image转换为单通道灰度图像然后将灰度图进行直方图均衡化之后定义了直方图的参数包括直方图条目数量、像素值范围、均匀性和累积性。接下来使用 cv::calcHist() 函数计算了图像的直方图存储在 hist 中。最后通过绘制直方图数据到 histImage 中实现了直方图的可视化。 3.直方图匹配 直方图匹配Histogram Matching是一种图像处理技术用于将一副图像的直方图映射到另一副图像上从而使它们的亮度分布或颜色分布相似。该技术常用于图像增强、风格转换、颜色校正等应用中。
以下是一个使用OpenCV实现直方图匹配的示例代码 #include opencv2/opencv.hpp
#include iostreamusing namespace cv;
using namespace std;void drawHist(Mat hist,string name){//归一化并绘制直方图函数int histSize 256; // 直方图条目数量// 绘制直方图int histWidth 512;int histHeight 400;int binWidth cvRound((double)histWidth / histSize);cv::Mat histImage(histHeight, histWidth, CV_8UC4, cv::Scalar(0, 0, 0));cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());for (int i 1; i histSize; i){cv::line(histImage, cv::Point(binWidth * (i - 1), histHeight - cvRound(hist.atfloat(i - 1))),cv::Point(binWidth * (i), histHeight - cvRound(hist.atfloat(i))),cv::Scalar(255, 255, 255), 2, 8, 0);}// 显示直方图cv::imwrite(/sdcard/DCIM/name.jpg, histImage);}
void Histogram_matching(Mat img1,Mat img2){Mat hist1,hist2;//计算两张图像直方图const int channels[1]{0};float inRanges[2]{0,255};const float *ranges[1]{inRanges};const int bins[1]{256};calcHist(img1,1,channels,Mat(),hist1,1,bins,ranges);calcHist(img2,1,channels,Mat(),hist2,1,bins,ranges);//归一化两张图像的直方图drawHist(hist1,hist1);drawHist(hist2,hist2);//计算两张图像直方图的累计概率float hist1_cdf[256]{hist1.atfloat(0)};float hist2_cdf[256]{hist2.atfloat(0)};for(int i1;i256;i){hist1_cdf[i]hist1_cdf[i-1]hist1.atfloat(i);hist2_cdf[i]hist2_cdf[i-1]hist1.atfloat(i);}//构建累积概率误差矩阵float diff_cdf[256][256];for(int i0; i256; i){for(int j0; j256; j){diff_cdf[i][j] fabs(hist1_cdf[i] - hist2_cdf[j]);}}uchar lutone[256];for(int i0;i256;i){//查找源灰度级为i的映射灰度//和i的累积概率差值最小的规定化灰度float mindiff_cdf[i][0];int index0;//寻找累积概率误差矩阵中每一行中的最小值for(int j1;j256;j){if(mindiff_cdf[i][j]){mindiff_cdf[i][j];indexj;}}lutone[i]index;}//生成LUT映射表Mat lut(1,256,CV_8UC1,lutone);Mat result,hist3;LUT(img1,lut,result);imwrite(/sdcard/DCIM/result.png,result);calcHist(result,1,channels,Mat(),hist3,1,bins,ranges);drawHist(hist3,hist3);}
示例代码计算原始图像和目标图像的直方图归一化直方图计算累计直方图构建累积概率误差矩阵根据最小差值构建映射表最后将原始图像的灰度级根据映射表调整为目标图像的灰度级。下面是原始图像和直方图匹配后图片可以看出直方图匹配后的图片使得图像中的细节更加清晰可见。 原图 直方图匹配的结果