和之前的一篇blog【http://blog.csdn.net/lu597203933/article/details/14104505】一样,这篇是opencv2的Mat格式。
一:一维直方图
Code:
- int main()
- {
- Mat image = imread("F:\\huangrong.jpg", 0);
- if(!image.data)
- {
- cout << "fail to load image" << endl;
- return 0;
- }
- MatND hist; // 在cv中用CvHistogram *hist = cvCreateHist
- int dims = 1;
- float hranges[] = {0, 255};
- const float *ranges[] = {hranges}; // 这里需要为const类型
- int size = 256;
- int channels = 0;
- // 计算图像的直方图
- calcHist(&image, 1, &channels, Mat(), hist, dims, &size, ranges); // cv 中是cvCalcHist
- int scale = 1;
- Mat imageShow(size * scale, size, CV_8U, Scalar(0));
- // 获取最大值和最小值
- double minVal = 0;
- double maxVal = 0;
- minMaxLoc(hist,&minVal, &maxVal, 0, 0); // cv中用的是cvGetMinMaxHistValue
- //显示直方图的图像
- int hpt = saturate_cast<int>(0.9 * size);
- for(int i = 0; i < 256; i++)
- {
- float value = hist.at<float>(i); // 注意hist中是float类型 cv中用cvQueryHistValue_1D
- int realValue = saturate_cast<int>(value * hpt/maxVal);
- //line(imageShow, Point(i, size - 1), Point(i, size - realValue), Scalar(0));
- rectangle(imageShow,Point(i*scale, size - 1), Point((i+1)*scale - 1, size - realValue), Scalar(255));
- }
- namedWindow("showImage");
- imshow("showImage", imageShow);
- waitKey(0);
- return 0;
- }
Explaination:
<1>代码中有注释将mat格式与cv格式进行了比对,大家注意
<2> float value = hist.at<float>(i);
要注意直方图数据为浮点类型
<3>画出直方图其实有多种方式,可以使用line或rectangle都可以
Result:
二:二维直方图
Code:
- int main()
- {
- Mat image = imread("F:\\baboon.jpg", 1);
- if(!image.data)
- {
- cout << "fail to load image" << endl;
- return 0;
- }
- MatND hist; // 在cv中用CvHistogram *hist = cvCreateHist
- int dims = 2;
- float r_hranges[] = {0, 255};
- float g_hranges[] = {0, 255};
- const float *ranges[] = {r_hranges, g_hranges}; // 这里需要为const类型
- int size[2] = {256, 256};
- int channels[] ={0,1}; //代表 r g通道 2代表b通道
- // 计算图像的直方图
- calcHist(&image, 1, channels, Mat(), hist, dims, size, ranges); // cv 中是cvCalcHist
- int scale = 1;
- Mat imageShow(size[0] * scale, size[1]*scale, CV_8UC3, Scalar(255));
- // 获取最大值和最小值
- double minVal = 0;
- double maxVal = 0;
- minMaxLoc(hist,&minVal, &maxVal, 0, 0); // cv中用的是cvGetMinMaxHistValue
- //显示直方图的图像
- //int hpt = saturate_cast<int>(0.9 * size[]);
- for(int i = 0; i < 256; i++)
- {
- for(int j = 0; j < 256; j++)
- {
- float value = hist.at<float>(i,j); // 注意直方图的值是float类型 cv中用cvQueryHistValue_1D
- int realValue = saturate_cast<int>(value * size[0]/maxVal);
- //line(imageShow, Point(i, size - 1), Point(i, size - realValue), Scalar(0));
- rectangle(imageShow,Point(i*scale, j*scale), Point( ((i+1)*scale - 1), (j+1)*scale - 1), Scalar(realValue,realValue, realValue));
- }
- }
- namedWindow("baboon");
- namedWindow("showImage");
- imshow("showImage", imageShow);
- imshow("baboon", image);
- waitKey(0);
- return 0;
- }
Explaination:
需要注意的是取二维的通道数是通过变量channels来取得的,不需要将图片再进行split
Result:
另外推荐小魏的blog,关于直方图的描述写的也非常好:
链接:http://blog.csdn.net/xiaowei_cqu/article/details/8833799【Mat格式】
http://blog.csdn.net/xiaowei_cqu/article/details/7600666【cv】
作者:小村长 出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)