【OpenCV学习笔记】二十一、直方图计算及绘制(一)

直方图计算及绘制(一)

1.计算直方图——calcHist()
2.完成了四种直方图的绘制:一维灰度直方图;一维灰度直方图(不均匀);BGR三色直方图;二维直方图。
先上ppt:
【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




【【OpenCV学习笔记】二十一、直方图计算及绘制(一)】【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片


代码:
1.一维灰度直方图


#include "opencv2/opencv.hpp" using namespace cv; #include using namespace std; int main() { ///一维灰度直方图 //1.计算直方图 Mat srcImg = imread("1.jpg",CV_LOAD_IMAGE_GRAYSCALE); int nimages = 1; //图像的个数 int channels = 0; //需要统计通道的索引 Mat mask = Mat(); Mat histImg; //存放输出的直方图 int dims = 1; //需要计算的直方图的维度 int histSize = 256; //计算的直方图的分组数 float range[] = { 0, 256 }; //表示直方图每一维度的取值范围[0,256) const float* ranges[] = { range }; //参数形式需要,表示每一维度数值的取值范围 calcHist(&srcImg,nimages,&channels,mask,histImg,dims,&histSize,ranges); //计算直方图 //2.绘制直方图 double minValue = https://www.it610.com/article/0; double maxValue = 0; minMaxLoc(histImg,&minValue,&maxValue); //得到计算出的直方图中的最小值和最大值 int width = histSize; //定义绘制直方图的宽度,令其等于histSize int height = 400; //定义绘制直方图的高度 Mat dstImg = Mat::zeros(Size(width,height),CV_8UC3); //宽为histSize,高为height for (int i = 0; i < histSize; i++)//遍历histImg { float binValue = histImg.at(i); //得到histImg中每一分组的值 cout <<"i: "<

运行结果: 【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




2.一维灰度直方图(不均匀)

#include "opencv2/opencv.hpp" using namespace cv; #include using namespace std; int main() { ///一维灰度直方图(不均匀) //1.计算直方图 Mat srcImg = imread("1.jpg", CV_LOAD_IMAGE_GRAYSCALE); int nimages = 1; //图像的个数 int channels = 0; //需要统计通道的索引 Mat mask = Mat(); Mat histImg; //存放输出的直方图 int dims = 1; //需要计算的直方图的维度 int histSize = 5; //计算的直方图的分组数 float range[] = { 0, 50,100,150,200,256 }; //表示直方图每一维度的取值范围 const float* ranges[] = { range }; //参数形式需要,表示每一维度数值的取值范围 //计算直方图,注意最后的直方图是否均匀的标识符置为false calcHist(&srcImg, nimages, &channels, mask, histImg, dims, &histSize, ranges,false); //2.绘制直方图 double minValue = https://www.it610.com/article/0; double maxValue = 0; minMaxLoc(histImg, &minValue, &maxValue); //得到计算出的直方图中的最小值和最大值 int width = 400; //定义绘制直方图的宽度 int height = 400; //定义绘制直方图的高度 Mat dstImg = Mat::zeros(Size(width, height), CV_8UC3); //宽为histSize,高为height for (int i = 0; i < histSize; i++)//遍历histImg { float binValue = histImg.at(i); //得到histImg中每一分组的值 cout << "i: " << i << " ,binValue: " << binValue << endl; float realValue = https://www.it610.com/article/(binValue / maxValue)*height; //归一化数据,缩放到图像的height之内 cout <<"i: " << i << " ,realValue: " << realValue << endl; //用矩形方法绘制直方图,注意左上点和右下点坐标的计算 rectangle(dstImg,Point(40*i,height-1-realValue),Point(40*i+20,height-1),Scalar(255,0,0),-1); } imshow("srcImg", srcImg); imshow("Histogram", dstImg); waitKey(0); return 0; }

运行结果:
【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




3.BGR三色直方图绘制

#include "opencv2/opencv.hpp" using namespace cv; #include using namespace std; int main() { ///BGR三色直方图绘制 //1.计算BGR三个通道的直方图 Mat srcImg = imread("1.jpg",CV_LOAD_IMAGE_COLOR); int nimages = 1; //图像的个数 Mat mask = Mat(); int dims = 1; //需要计算的直方图的维度 int histSize = 256; //计算的直方图的分组数 float range[] = { 0, 256 }; const float* ranges[] = { range }; //参数形式需要,表示直方图每一维度的取值范围 Mat histImg_B; //存放输出的蓝色通道的直方图 int channels_B = 0; //蓝色通道的索引 calcHist(&srcImg, nimages, &channels_B, mask, histImg_B, dims, &histSize, ranges); //计算蓝色通道直方图 Mat histImg_G; //存放输出的绿色通道的直方图 int channels_G = 1; //绿色通道的索引 calcHist(&srcImg, nimages, &channels_G, mask, histImg_G, dims, &histSize, ranges); //计算绿色通道直方图 Mat histImg_R; //存放输出的红色通道的直方图 int channels_R = 2; //红色通道的索引 calcHist(&srcImg, nimages, &channels_R, mask, histImg_R, dims, &histSize, ranges); //计算红色通道直方图 //2.绘制BGR三个通道的直方图 double minValue_B = 0; double maxValue_B = 0; minMaxLoc(histImg_B,&minValue_B,&maxValue_B); //得到蓝色通道直方图中的最小值和最大值 double minValue_G = 0; double maxValue_G = 0; minMaxLoc(histImg_G, &minValue_G, &maxValue_G); //得到绿色通道直方图中的最小值和最大值 double minValue_R = 0; double maxValue_R = 0; minMaxLoc(histImg_R, &minValue_R, &maxValue_R); //得到红色通道直方图中的最小值和最大值 int width = histSize; //定义绘制直方图的宽度,令其等于histSize int height = 400; //定义绘制直方图的高度 Mat dstImg = Mat::zeros(Size(3*histSize,height),CV_8UC3); //宽为3*histSize,高为height for (int i = 0; i < histSize; i++)//遍历histImg { //绘制蓝色通道直方图 float binValue_B = histImg_B.at(i); //得到histImg中每一分组的值 cout <<"i: "<(i); //得到histImg中每一分组的值 cout << "i: " << i << " ,binValue_G: " << binValue_G << endl; float realValue_G = (binValue_G / maxValue_G)*height; //归一化数据,缩放到图像的height之内 cout << "i: " << i << " ,realValue_G: " << realValue_G << endl; //用直线方法绘制直方图,两端点横坐标在之前的基础上加上histSize line(dstImg, Point(i + histSize, height - 1), Point(i + histSize, height - 1 - realValue_G), Scalar(0, 255, 0), 1); //绘制红色通道直方图 float binValue_R = histImg_R.at(i); //得到histImg中每一分组的值 cout << "i: " << i << " ,binValue_R: " << binValue_R << endl; float realValue_R = (binValue_R / maxValue_R)*height; //归一化数据,缩放到图像的height之内 cout << "i: " << i << " ,realValue_R: " << realValue_R << endl; //用直线方法绘制直方图,两端点横坐标在之前的基础上加上2*histSize line(dstImg, Point(i + 2 * histSize, height - 1), Point(i + 2 * histSize, height - 1 - realValue_R), Scalar(0, 0, 255), 1); } namedWindow("srcImg", CV_WINDOW_NORMAL); //定义一个窗口,CV_WINDOW_NORMAL大小可调整 imshow("srcImg", srcImg); namedWindow("BGR Histogram", CV_WINDOW_NORMAL); //定义一个窗口,CV_WINDOW_NORMAL大小可调整 imshow("BGR Histogram", dstImg); waitKey(0); return 0; }

运行结果:
【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




4.二维直方图

#include "opencv2/opencv.hpp" using namespace cv; #include using namespace std; int main() { ///二维直方图(对于二维直方图还不是太理解,目前理解是横纵坐标表示位置,用颜色强度反映其值) //1.计算直方图 Mat srcImg = imread("1.jpg", CV_LOAD_IMAGE_COLOR); int nimages = 1; //图像的个数 Mat mask = Mat(); int channels[2] = {0,1}; //0通道以及1通道 int dims = 2; //2维 Mat histImg; int histSize_B = 256; //蓝色通道直方图的分组数 int histSize_G = 256; //红色通道直方图的分组数 int histSize[2] = { histSize_B, histSize_G }; //存放每个维度的直方图尺寸的数组 float range_B[] = { 0, 256 }; //表示蓝色通道直方图的取值范围[0,256) float range_G[] = { 0, 256 }; //表示红色融到直方图的取值范围[0,256) const float* ranges[] = { range_B,range_G }; //表示每一维度数值的取值范围 calcHist(&srcImg, nimages, channels, mask, histImg, dims, histSize, ranges); //计算直方图 //2.绘制直方图 double minValue = https://www.it610.com/article/0; double maxValue = 0; minMaxLoc(histImg, &minValue, &maxValue); //得到计算出的直方图中的最小值和最大值 int width = histSize_B; //定义绘制直方图的宽度,令其等于histSize int height = histSize_G; //定义绘制直方图的高度 Mat dstImg = Mat::zeros(Size(width, height), CV_8UC3); //宽为histSize_B,高为histSize_G for (int i = 0; i < histSize_B; i++)//遍历histSize_B { for (int j = 0; j < histSize_G; j++)//遍历histSize_G { float binValue = histImg.at(i,j); //得到histImg中每一分组的值 //cout << "(i,j):(" << i <<","<

运行结果: 【OpenCV学习笔记】二十一、直方图计算及绘制(一)
文章图片




    推荐阅读