0015-OpenCV环境下计算并绘制HSV空间的H-S的二维联合直方图

上篇博文(https://blog.csdn.net/lehuoziyuan/article/details/84064822)介绍了灰度直方图的计算,是一维的直方图,这篇博文介绍运用calcHist计算二维联合直方图的方法以HSV空间的H-S的二维联合直方图为例
需要说明的是,二维直方图并不是一个通道一个通道的分别独立平行计算,而是将两个通道的数据整合起来计算出的二维直方图。
calcHist函数就不介绍了,上一篇帖子已经讲进了,详情见我的上篇博客!
直接上源码吧
源码中使用的图像下载链接:http://pan.baidu.com/s/1jHHh7sM 密码:78cr

图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!

//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>

#include <iostream>

using namespace cv;
using namespace std;

int main()
{
        Mat srcImage = imread("linger.jpg");
        imshow("【原图】", srcImage);

        Mat hsvImage;
        //因为要计算H-S的直方图,所以需要得到一个HSV空间的图像  
        cvtColor(srcImage, hsvImage, CV_BGR2HSV);
        //imshow("【HSV空间的原图】", hsvImage);

        //为计算直方图配置变量  
        //首先是需要计算的通道编号,就是需要计算哪个通道的直方图(BGR空间需要确定计算,计算方法见帖子中对相关参数的说明)
        int channels[] = { 0, 1 };
        //然后是定义直方图计算结果的存储空间
        Mat dstHist;
        //接下来是直方图的每一个维度的数目(这个数目用于将每一维度的数值分组) 
        int histSize[] = { 30, 32 };
        //最后是确定每个维度的取值范围,就是每一维度的横坐标的取值范围  
        //首先得定义两个数组用来存储两个维度的取值范围
        float HRanges[] = { 0, 180 };
        float SRanges[] = { 0, 256 };

        //然后把这两个数组再放到一个二维数组中
        const float *ranges[] = { HRanges, SRanges };

        //准备工作做好后,就可以调用calcHis函数计算直方图数据了
        calcHist(&hsvImage, 1, channels, Mat(), dstHist, 2, histSize, ranges, true, false);

        //calcHist函数调用结束后,dstHist变量中将储存直方图数据 

        ///接下来绘制直方图
        //首先先创建一个黑底的图像,为了可以显示彩色,所以该绘制图像是一个8位的3通道图像  
        Mat drawImage = Mat::zeros(Size(300, 320), CV_8UC3);

        //因为数据矩阵中的某个值的总个数可能会超出所定义的图像的尺寸,所以要对个数进行归一化处理  
        //先用 minMaxLoc函数来得到计算直方图中的最大数据,这个函数的使用方法大家一看函数原型便知
        double g_dHistMaxValue;
        minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);

        //遍历直方图数据,对数据进行归一化和绘图处理 
        for (int i = 0; i < 30; i++)
        {
                for (int j = 0; j < 32; j++)
                {
                        int value = cvRound(dstHist.at<float>(i, j) * 256 / g_dHistMaxValue);

                        rectangle(drawImage, Point(10 * i, j * 10), Point((i + 1) * 10 - 1, (j + 1) * 10 - 1), Scalar(value), -1);
                }
        }

        imshow("【H-S二维联合直方图】", drawImage);

        waitKey(0);

        return 0;
}


代码说明
rectangle的两个point参数分别为一个矩阵的左上角顶点坐标和右下角顶点坐标!
运行结果截图如下


 

猜你喜欢

转载自blog.csdn.net/lehuoziyuan/article/details/84065188
今日推荐