欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > Opencv学习-calcHist()、normalize()函数

Opencv学习-calcHist()、normalize()函数

2024/10/25 6:26:59 来源:https://blog.csdn.net/m0_63893772/article/details/141320880  浏览:    关键词:Opencv学习-calcHist()、normalize()函数

1. calcHist函数

1.1 calcHist函数原型

void cv::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:待统计直方:图的图像数组,数组中所有的图像应具有相同的尺寸和数据类型,并且数据类型只能是 CV_8U、CV_16U 和 CV_32F 这 3 种中的一种,但是不同图像的通道数可以不同。
  • nimages:输入的图像数量。
  • channels:需要统计的通道索引数组,第一个图像的通道索引从 0 到 images[0].channels()−1,第二个图像通道索引从 images[0].channels()到 images[0].channels()+ images[1].channels()−1,依此类推。
  • mask:可选的操作掩码。如果是空矩阵,那么表示图像中所有位置的像素都计入直方图中;如果矩阵不为空,那么必须与输入图像尺寸相同且数据类型为 CV_8U。
  • hist:输出的统计直方图结果,是一个 dims 维度的数组。
  • dims:需要计算直方图的维度,必须是整数,并且不能大于 CV_MAX_DIMS,在 OpenCV 4.0 和 OpenCV 4.1 版中为 32。
  • histSize:存放每个维度直方图的数组的尺寸。
  • ranges:每个图像通道中灰度值的取值范围。
  • uniform:直方图是否均匀的标志符,默认状态下为均匀(true)。
  • accumulate:是否累积统计直方图的标志,如果累积(true),那么,在统计新图像的直方图时,之前图像的统计结果不会被清除,该参数主要用于统计多个图像整体的直方图。
        该函数用于统计图像中每个灰度值像素的个数,例如统计一幅 CV_8UC1 的图像,需要统计灰度值从 0 255 中每一个灰度值在图像中的像素个数,如果某个灰度值在图像中没有,那么该灰度值的统计结果就是 0 。由于该函数具有较多的参数,并且每个参数都较为复杂,因此作者建议在使用该函数时只统计单通道图像的灰度值分布,对于多通道图像,可以将图像每个通道分离后再进行统计。
        为了使读者更加了解函数的使用方法,代码清单 4-2 中提供了绘制灰度图像的图像直方图的示例程序。在该程序中,首先使用 calcHist() 函数统计灰度图像中每个灰度值的数目,之后通过不断绘制矩形的方式实现直方图的绘制。由于图像中部分灰度值像素数目较多,因此将每个灰度值数目缩小为原来的 1/20 后再进行绘制,绘制的直方图如图 4-1 所示。在该程序中,使用了 OpenCV 4 提供的四舍五入的取整函数 cvRound() ,该函数输入参数为 double 类型的变量,返回值为对该变量四舍五入后的 int 型数值。

2. normalize()函数

2.1 normalize()函数原型

void cv::normalize(InputArray src, 
InputOutputArray dst, 
double alpha = 1, 
double beta = 0, 
int norm_type = NORM_L2, 
int dtype = -1, 
InputArray mask = noArray() 
)
  • src:输入数组矩阵。
  • dst:输入与 src 相同大小的数组矩阵。
  • alpha:在范围归一化的情况下,归一化到下限边界的标准值。
  • beta:范围归一化时的上限范围,它不用于标准规范化。
  • norm_type:归一化过程中数据范数种类标志,常用的可选择参数在表 4-1 中给出。
  • dtype:输出数据类型选择标志。如果其为负数,那么输出数据与 src 拥有相同的类型,否则与 src 具有相同的通道数,但是数据类型不同。
  • mask:掩码矩阵。 
        该函数输入一个存放数据的矩阵,通过参数 alpha 设置将数据缩放到最大范围,然后通过norm_type 参数选择计算范数的种类,之后将输入矩阵中的每个数据分别除以求取的范数数值,最 后得到缩放的结果。输出结果是一个 CV_32F 类型的矩阵,可以将输入矩阵作为输出矩阵,或者重新定义一个新的矩阵用于存放输出结果。该函数的第 5 个参数用于选择计算数据范数的种类,常用的可选择参数以及计算范数的公式在表 4-1 中给出。计算不同的范数,最后的结果也不相同,例如选择 NORM_L1 标志,输出结果为每个灰度值所占的比例;选择 NORM_INF 参数,输出结果为除以数据中最大值,将所有的数据归一化为 0 1
normalize()函数归一化常用标志参数

3. 代码示例

#include <opencv2/opencv.hpp> 
#include <iostream> using namespace cv; 
using namespace std; int main() 
{ vector<double> positiveData = { 2.0, 8.0, 10.0 }; vector<double> normalized_L1, normalized_L2, normalized_Inf, normalized_L2SQR,normalized_MINMAX; //测试不同归一化方法normalize(positiveData, normalized_L1, 1.0, 0.0, NORM_L1); //绝对值求和归一化cout <<"normalized_L1=["<< normalized_L1[0]<<", " << normalized_L1[1]<<", "<< normalized_L1[2] <<"]"<< endl; normalize(positiveData, normalized_L2, 1.0, 0.0, NORM_L2); //模长归一化cout << "normalized_L2=[" << normalized_L2[0] << ", " << normalized_L2[1] << ", " << normalized_L2[2] << "]" << endl; normalize(positiveData, normalized_Inf, 1.0, 0.0, NORM_INF); //最大值归一化cout << "normalized_Inf=[" << normalized_Inf[0] << ", " << normalized_Inf[1] << ", " << normalized_Inf[2] << "]" << endl; normalize(positiveData, normalized_MINMAX, 1.0, 0.0, NORM_MINMAX); //偏移归一化cout << "normalized_MINMAX=[" << normalized_MINMAX[0] << ", " << normalized_MINMAX[1] << ", " << normalized_MINMAX[2] << "]" << endl;Mat img = imread("../pic/gril.jpg"); if (img.empty()) { cout << "请确认图像文件名称是否正确" << endl; return -1; } Mat gray; //cvtColor(img, gray, COLOR_BGR2GRAY); Mat imgs[3],imgs0,imgs1,imgs2; split(img, imgs); imgs0 = imgs[0]; imgs1 = imgs[1]; imgs2 = imgs[2];//设置提取直方图的相关变量Mat b_hist,g_hist,r_hist; //用于存放直方图计算结果const int channels[1] = { 0 }; //通道索引float inRanges[2] = { 0,255 }; const float* ranges[1] = { inRanges }; //像素灰度值范围const int bins[1] = { 256 }; //直方图的维度,其实就是像素灰度值的最大值calcHist(&imgs[0], 1, 0, Mat(), b_hist, 1, bins, ranges, true, false); //计算图像直方图calcHist(&imgs[1], 1, 0, Mat(), g_hist, 1, bins, ranges, true, false); //计算图像直方图calcHist(&imgs[2], 1, 0, Mat(), r_hist, 1, bins, ranges, true, false); //计算图像直方图//准备绘制直方图int hist_w = 500; int hist_h = 400; int width = 2; Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());//归一化normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());for (int i = 1; i <= 255; i++) { line(histImage, Point(width*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),Point(width*(i), hist_h - cvRound(b_hist.at<float>(i)/2)), Scalar(255, 0, 0),2);line(histImage, Point(width*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),Point(width*(i), hist_h - cvRound(g_hist.at<float>(i)/2)), Scalar(0, 255, 0),2);line(histImage, Point(width*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),Point(width*(i), hist_h - cvRound(r_hist.at<float>(i)/2)), Scalar(0, 0, 255),2);} namedWindow("histImage", WINDOW_AUTOSIZE); imshow("histImage", histImage); imshow("img", img); waitKey(0); return 0; 
}

4. 测试结果

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com