openCV直方图相关函数

来源:互联网 发布:电子软件开发 编辑:程序博客网 时间:2024/05/23 05:07

灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像素的个数:其横坐标是灰度级,纵坐标是该灰度出现的频率(像素的个数)。

在opencv中可以通过cvCreateHist()来生成直方图

CvHistogram* cvCreateHist(    int dims,           int* sizes,       int type,        float** ranges=NULL,     int uniform=1      )    dims       //直方图包含的维数    sizes     //数组的长度等于dims,数组中每个整数表示分配给对应维数的的bin的个数    type      //表示存储类型,CV_HIST_ARRAy表示用密集多维矩阵结构存储直方图,CV_HIST_SPARSE表示数据已稀疏矩阵方式存储    ranges=NULL,     //浮点数对的构成的数组,每个浮点数对表示对应维数的bin的区间的上下界    uniform=1      //非0表示均匀直方图,为NULL表示未知,即在后面可以设置。CvHistogram* cvCreateHist(  
使用cvCalcHist()函数来计算直方图

void cvCalcHist(IplImage** image,CvHistogram* hist,int accmulate=0,const CvArr* mask=NULL)image  //是一个指向数组的IplImage*类型的指针,着允许利用多个图像通道hist   //要计算的直方图accmulate //非0时,表示直方图hist在读入图像之前没有被清零mask //如果为非NULL,则只有与mask非零元素对应的像素点会被包含在计算直方图中。

1.单通道图像的直方图

#include "stdafx.h"#include <highgui.h>#include <math.h>#include <cv.h>int main(){IplImage* sourceImage=0;//以单通道读入图像if(!(sourceImage=cvLoadImage("YAYA.jpg",0)))return -1;int hdims=51;      //分配给对应维数的bin的个数float rangesArray[]={0,255};float* ranges[]={rangesArray};float maxValue;CvHistogram* histogram=0;histogram=cvCreateHist(1,&hdims,CV_HIST_ARRAY,ranges,1);IplImage* histImage;      //用来显示直方图histImage=cvCreateImage(cvGetSize(sourceImage),8,3);cvZero(histImage);//计算直方图cvCalcHist(&sourceImage,histogram,0,0);//获取最大值cvGetMinMaxHistValue(histogram,0,&maxValue,0,0);cvConvertScale(histogram->bins,histogram->bins,maxValue?255./maxValue:0,0);float binsWidth;binsWidth=histImage->width/hdims;CvScalar color=CV_RGB(255,255,255);for(int i=0;i<hdims;i++){double value=(cvGetReal1D(histogram->bins,i)*histImage->height/255);cvRectangle(histImage,cvPoint(i*binsWidth,histImage->height),cvPoint((i+1)*binsWidth,(int)(histImage->height-value)),color,1,8,0);}//显示cvNamedWindow("sourceImage",0);cvNamedWindow("histImage",0);cvShowImage("sourceImage",sourceImage);cvShowImage("histImage",histImage);//释放资源cvDestroyAllWindows();cvReleaseImage(&sourceImage);cvReleaseImage(&histImage);cvReleaseHist(&histogram);cvWaitKey(-1);return 0;}
运行结果:


多通道图像的直方图

因为ccCalHist()只接受单通道图像,所以在调用cvCalcHist()之前,首先用cvSplit()将多通道图像分解为单通道图像。

#include "stdafx.h"#include <highgui.h>#include <math.h>#include <cv.h>int main(){    IplImage* sourceImage=0;    if(!(sourceImage=cvLoadImage("YAYA.jpg",1)))        return -1;    IplImage* hsvImage=cvCreateImage(cvGetSize(sourceImage),8,3);    cvCvtColor(sourceImage,hsvImage,CV_BGR2HSV);    IplImage* h_plane=cvCreateImage(cvGetSize(sourceImage),8,1);    IplImage* s_plane=cvCreateImage(cvGetSize(sourceImage),8,1);    IplImage* v_plane=cvCreateImage(cvGetSize(sourceImage),8,1);    cvSplit(hsvImage,h_plane,s_plane,v_plane,0);        int h_bins=30,s_bins=32;    CvHistogram* histogram;    {        int hist_size[]={h_bins,s_bins};        float h_ranges[]={0,180};        float s_ranges[]={0,255};        float* ranges[]={h_ranges,s_ranges};        histogram=cvCreateHist(            2,            hist_size,            CV_HIST_ARRAY,            ranges,            1            );    }    IplImage* planes[]={h_plane,s_plane};    cvCalcHist(planes,histogram,0,0);    cvNormalizeHist(histogram,1.0);    int scale=10;    IplImage* histImage=cvCreateImage(        cvSize(h_bins*scale,s_bins*scale),8,3);    cvZero(histImage);    float maxValue;    cvGetMinMaxHistValue(histogram,0,&maxValue,0,0);        for(int h=0;h<h_bins;h++)        for(int s=0;s<s_bins;s++)        {            float binValue=cvQueryHistValue_2D(histogram,h,s);            int intensity=cvRound(binValue*255./maxValue);            cvRectangle(                histImage,                cvPoint(h*scale,s*scale),                cvPoint((h+1)*scale-1,(s+1)*scale-1),                CV_RGB(intensity,intensity,intensity),                CV_FILLED                );        }        cvNamedWindow("hsvImage",1);        cvNamedWindow("histImage",1);        cvShowImage("hsvImage",hsvImage);        cvShowImage("histImage",histImage);        cvWaitKey(-1);        cvDestroyAllWindows();        cvReleaseImage(&sourceImage);        cvReleaseImage(&histImage);        cvReleaseHist(&histogram);        return 0;}

运行结果:


直方图的相似度

计算直方图相似度的函数如下:

double cvCompareHist(const CvHistogram* hist1,const CvHistogram* hist2,int method;           //距离标准)
method的取值有:

CV_COMP_CORREL     完全匹配为1,完全不匹配为-1,数值越大越匹配

CV_COMP_CHISQR      低分比高分匹配的程度高,完全匹配的值为0,完全不匹配为无限值

CV_COMP_INTERSECT   高分表示好匹配,低分表示坏匹配

CV_COMP_BHATTACHARYYA     低分表示好匹配,高分表示换匹配。完全匹配为0,完全不匹配为0.

#include "stdafx.h"#include <highgui.h>#include <math.h>#include <cv.h>using namespace std;//对比两个直方图的相似度int main(){    IplImage* templateImage=cvLoadImage("YAYA.jpg");    if(!templateImage)        return -1;    IplImage* grayImage=cvCreateImage(cvGetSize(templateImage),8,1);    cvCvtColor(templateImage,grayImage,CV_BGR2GRAY);    //首先加载图片,然后将图片变为灰度图        int hist_size=51;    float range[]={0,255};    float* ranges[]={range};    CvHistogram* histogram;    histogram=cvCreateHist(        1,        &hist_size,      //size  元素为对应bin的个数        CV_HIST_ARRAY,        ranges,        1        );    cvCalcHist(&grayImage,histogram,0,0);    IplImage* compareImage=cvLoadImage("YAYA2.jpg");    if(!compareImage)        return -1;    IplImage* compareGrayImage=cvCreateImage(cvGetSize(compareImage),8,1);    cvCvtColor(compareImage,compareGrayImage,CV_BGR2GRAY);    //首先加载图片,然后将图片变为灰度图        CvHistogram* compareHistogram;    compareHistogram=cvCreateHist(        1,        &hist_size,        CV_HIST_ARRAY,        ranges,        1        );    cvCalcHist(&compareGrayImage,compareHistogram,0,0);    //对直方图进行归一化操作    cvNormalizeHist(histogram,1);    cvNormalizeHist(compareHistogram,1);    //计算匹配系数    double degree=cvCompareHist(histogram,compareHistogram,        CV_COMP_CHISQR);    cout<<degree<<endl;    cvWaitKey(10000000);    cvDestroyAllWindows();    cvReleaseImage(&templateImage);    cvReleaseImage(&grayImage);    cvReleaseImage(&compareImage);    cvReleaseImage(&compareGrayImage);    cvReleaseHist(&compareHistogram);    cvReleaseHist(&histogram);    return 0;}

0 0
原创粉丝点击