直方图原理和应用

概念:在分析图像、物体、视频信息的过程中,我们常常把眼中的看到的物体用直方图(histogram)表示。

应用:直方图可以用来描述各种不同的事情,如物体的彩色分布、物体边缘梯度模板、以及表示物体目标位置的当前假设的概率分布。

直方图可以用来进行快速姿态识别、检测视频中的场景变换。

原理:直方图就是对数据进行统计,将统计值组织到一系列实现定义好的bin中。bin中的数值是从数据中计算出的特征的统计量,这些数据可以是梯度、方向、色彩或者任何其它特征。


直方图示例用法,取自《学习OpenCV》P227

该程序的作用是计算输入图像的色相饱和度(hue-saturation)直方图。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

#define cvQueryHistValue_2D( hist, idx0, idx1 )   cvGetReal2D( (hist)->bins, (idx0), (idx1) )

int main(int argc, const char * argv[]) {
    /*1、载入一个图像*/
    const char filename[] = "/Users/linwang/Downloads/Lena.jpg";
    IplImage * src = cvLoadImage(filename,1);
    
    /*2、创建hsv并进行色彩空间转换*/
    IplImage * hsv = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
    cvCvtColor(src, hsv, CV_RGB2HSV);
    
    /*3、分别创建h、s、v单个颜色通道*/
    IplImage * h_plane = cvCreateImage(cvGetSize(src), src->depth, 1);
    IplImage * s_plane = cvCreateImage(cvGetSize(src), src->depth, 1);
    IplImage * v_plane = cvCreateImage(cvGetSize(src), src->depth, 1);
    IplImage * planes[] = { h_plane , s_plane};  //指针数组,指向两个图片矩阵
    cvSplit(hsv, h_plane, s_plane, v_plane, 0);  //分离通道
    
    /*4、构建hist结构*/
    int h_bins = 30;
    int s_bins = 32;
    CvHistogram  * hist;
    int hist_size[] = {h_bins , s_bins} ;  //数组 , 大小和维度保持一致
    float h_ranges[] = {0, 180};
    float s_ranges[] = {0, 255};
    float * ranges[] = { h_ranges , s_ranges };
    hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY , ranges , 1); //稠密矩阵,并且ranges是均匀分布的
    
    /*5、从图像中计算直方图*/
    cvCalcHist(planes, hist);  //参数一是一个IplImage类型的指针
    
    /*6、归一化*/
    cvNormalizeHist(hist, 1.0);
    
    /*7、创建一个图片*/
    int scale = 10;
    IplImage * hist_img = cvCreateImage(cvSize(h_bins * scale, s_bins * scale), 8, 3);
    cvSetZero(hist_img);
    
    /*8、进行可视化操作*/
    float max_value = 0;
    cvGetMinMaxHistValue(hist, 0, &max_value,0,0);  //获取直方图最大值和最小值
    for(int h = 0;h<h_bins;h++)
    {
        for(int s = 0;s<s_bins;s++)
        {
            float bin_val = cvQueryHistValue_2D(hist, h , s);
            int intensity = cvRound( bin_val * 255 / max_value);
            cvRectangle(hist_img, cvPoint(h * scale, s * scale), cvPoint((h+1)*scale-1, (s+1)*scale - 1),
                                                            CV_RGB(intensity,intensity,intensity),CV_FILLED);
        }
    }
    cvShowImage("Source", src);
    cvShowImage("Hist_Img", hist_img);
    cvWaitKey(0);
    cvReleaseImage(&src);
    cvReleaseHist(&hist);
    cvReleaseImage(&hist_img);
    return 0;
}


发布了192 篇原创文章 · 获赞 14 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/u011559236/article/details/78707476