(OpenCV)直方图的基本操作指令

来源:互联网 发布:lol提升fps终极优化 编辑:程序博客网 时间:2024/05/17 01:56

直方图的基本操作:

1)归一化直方图

cvNormalizeHist(CvHistogram * hist,double factor);factor通常设为1

2)阈值函数

cvThreshHist(CvHistogram * hist,double factor);factor是一个开关阈值

3)复制直方图

void cvCopyHist(const CvHistogram * src,CvHistogram ** dst);

4)获得直方图的最小最大值

void cvGetMinMaxHistValue(const CvHistogram * hist,float * min_value,

float * max_value,int * min_idx=NULL,int * max_idx=NULL);

5)计算直方图

void cvCalcHist(IplImage ** image,CvHistogram * hist,int accumulate=0,

const CvArr * mask=NULL);

6)对比两个直方图

double cvCompareHist(const CvHIstogram *hist1,const CvHistogram *hist2,int method);

7)创建直方图

CvHistogram * cvCreateHist(int dims,int *size,int type, float ** ranges=NULL,int uniform=1);

举例:  

   int h_bins=30,s_bins=32;
   int hist_size[]={ h_bins, s_bins};
   float h_ranges[]={0,180};
   float s_ranges[]={0,255};
   float * ranges[]={h_ranges,s_ranges};
   CvHistogram * hist;
   hist=cvCreateHist(2,hist_size,CV_HIST_ARRAY,ranges,1);

8)在使用直方图之前给rangs设置数值

void cvSetHistBinRanges(CvHistogram * hist,float ** ranges,int uniform=1);

注意:

    I)uniform 说明直方图是否有均匀的bin,如果设置为非零值,则直方图是均匀的,也可以设置为NULL,意味着rangs是未知的。

    II)这个范围的用处是确定何时计算直方图或决定反向映射

9)释放直方图

如果想重用直方图,可以对其进行清零操作(即设置所有bins为0),或者使用通常的释放函数释放直方图

void cvClearHist(CvHistogram * hist);

void cvReleaseHist(CvHistogram ** hist);

10)根据已给出的数据创建直方图

CvHistogram * cvMakeHistHeaderForArray(int dims,int * sizes,CvHistogram * hist,float * data,float ** ranges=NULL);

11)访问直方图

double cvQueryHistValue_1D(CvHistogram * hist,int idx0);

double cvQueryHistValue_2D(CvHistogram * hist,int idx0,int idx1);

double cvQueryHistValue_3D(CvHistogram * hist,int idx0,int idx1,int idx2);

double cvQueryHistValue_nD(CvHistogram * hist,int * idxN);

12)反向投影

#include <cv.h> 
 #include <highgui.h>   
#include"stdio.h"
int main()
{
 IplImage*src= cvLoadImage("hand.jpg", 1);   
 IplImage*templ=cvLoadImage("part.jpg",1);
 cvNamedWindow( "Source" );   
    cvShowImage( "Source", src );  

    IplImage* h_plane2 = cvCreateImage( cvGetSize(src), 8, 1 );       
   IplImage* s_plane2 = cvCreateImage( cvGetSize(src), 8, 1 );     
   IplImage* v_plane2 = cvCreateImage( cvGetSize(src), 8, 1);  
   IplImage* planes2[] = { h_plane2, s_plane2,v_plane2 };
          IplImage* hsv2 = cvCreateImage( cvGetSize(src), 8, 3 ); 
   cvCvtColor( src, hsv2, CV_BGR2HSV );     
    cvSplit( hsv2, h_plane2, s_plane2, v_plane2, 0 ); 
     printf("h%d",h_plane2->widthStep);
      printf("s%d",h_plane2->widthStep);
    printf("v%d",h_plane2->widthStep);
      IplImage* h_plane = cvCreateImage( cvGetSize(templ), 8, 1 );       
   IplImage* s_plane = cvCreateImage( cvGetSize(templ), 8, 1 );     
   IplImage* v_plane = cvCreateImage( cvGetSize(templ), 8, 1);     
   IplImage* planes[] = { h_plane, s_plane,v_plane };
    IplImage* hsv = cvCreateImage( cvGetSize(templ), 8, 3 );   
     cvCvtColor( templ, hsv, CV_BGR2HSV );     
     cvSplit( hsv, h_plane, s_plane, v_plane, 0 ); 
    printf("h%d\n",h_plane->widthStep);
     printf("s%d\n",s_plane->widthStep);
      printf("v%d\n",v_plane->widthStep);
     int h_bins = 30, s_bins = 32,v_bins=32;
     int hist_size[] = {h_bins, s_bins,v_bins};
     float h_ranges[] = { 0, 180 };
    float s_ranges[]={0,255};
    float v_ranges[]={0,255};
     float* ranges[] = { h_ranges, s_ranges,v_ranges}; 
     CvHistogram* hist; 
     hist = cvCreateHist( 3, hist_size, CV_HIST_ARRAY, ranges, 1 );  
      cvCalcHist( planes, hist, 0, 0 ); 
      //1.double a=1.f;
   //2.cvNormalizeHist(hist,a);
   //templ's hist is just calculate

   IplImage*back_project=cvCreateImage(cvGetSize(src),8,1);
      cvZero(back_project);          
      //NOW we begin calculate back project

   cvCalcBackProject(planes2,back_project,hist);

        cvNamedWindow( "back_project" );   
    cvShowImage( "back_project", back_project );  

    cvWaitKey(0);

        return 0;
}

反向投影是一种记录像素点或者像素块如何适应直方图模型中分布的方式。

void cvCalcBackProject(IplImage ** image,CvArr * back_project,const CvHistogram * hist);

void cvCalcBackProjectPatch(IplImage ** image,CvArr * dst,CvSize patch_size,CvHistogram * hist ,int method,float factor);

应用:

I)如果我们有一个颜色直方图,可以利用反向投影在图像中找到该区域。

II)我们可以用函数cvCalcBackProject()计算一个像素是否是一个已知目标的一部分

III)也可以用函数cvCalcBackProjectPatch()计算一块区域是否包含已知的目标

13)画直方图

#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <cvaux.h>
using namespace std;

void showHist(IplImage * src){

IplImage* gray = cvCreateImage( cvGetSize(src), 8, 1 );
IplImage* rp = cvCreateImage(cvGetSize(src),8,1);
IplImage* gp = cvCreateImage(cvGetSize(src),8,1);
IplImage* bp = cvCreateImage(cvGetSize(src),8,1);
cvCvtColor( src, gray, CV_BGR2GRAY);
//将src图像转换为rgb三通道格式
cvCvtPixToPlane( src, rp, gp, bp, 0 );

int gray_bins = 64;
int h_size[] = {gray_bins};
int r_bins = 64;
int g_bins = 64;
int b_bins = 64;


float gray_ranges[] = { 0, 255 }; // hue is [0,180]
float * range = gray_ranges;

CvHistogram * hist = cvCreateHist(1,h_size,CV_HIST_ARRAY,&range,1);
CvHistogram * rhist = cvCreateHist(1,h_size,CV_HIST_ARRAY,&range,1);
CvHistogram * ghist = cvCreateHist(1,h_size,CV_HIST_ARRAY,&range,1);
CvHistogram * bhist = cvCreateHist(1,h_size,CV_HIST_ARRAY,&range,1);
cvCalcHist(&gray, hist, 0, 0 ); //Compute histogram
cvCalcHist(&rp, rhist, 0, 0 );
cvCalcHist(&gp, ghist, 0, 0 );
cvCalcHist(&bp, bhist, 0, 0 );
int scale = 5;
/** 创建直方图,一维, 每个维度上均分 */

IplImage* hist_img = cvCreateImage(cvSize(320,400),8,3);

cvZero( hist_img );

float max_value = 0;
float rmax = 0;
float gmax = 0;
float bmax = 0;
float val = 0.0;
int intensity = 0;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
cvGetMinMaxHistValue(rhist,0,&rmax,0,0);
cvGetMinMaxHistValue(ghist,0,&gmax,0,0);
cvGetMinMaxHistValue(bhist,0,&bmax,0,0);
for( int h = 0; h < gray_bins; h++ ) {


   //灰度图像的直方图
   val = cvQueryHistValue_1D( hist,h);
   intensity = cvRound(val*100/max_value);

   CvScalar color = CV_RGB(255,255,255); //(hsv2rgb(i*180.f/hdims);
   cvRectangle( hist_img, cvPoint(h*scale,100),cvPoint((h+1)*scale,(int)(100 - intensity)),color, -1, 8, 0 );
   //红色通道直方图
   val = cvQueryHistValue_1D( rhist,h);
   intensity = cvRound(val*100/rmax);
   color = CV_RGB(255,0,0); //(hsv2rgb(i*180.f/hdims);
   cvRectangle( hist_img, cvPoint(h*scale,200),cvPoint((h+1)*scale,(int)(200 - intensity)),color, -1, 8, 0 );
   //绿色    
   val = cvQueryHistValue_1D( ghist,h);
   intensity = cvRound(val*100/gmax);
   color = CV_RGB(0,255,0); 
   cvRectangle( hist_img, cvPoint(h*scale,300),cvPoint((h+1)*scale,(int)(300 - intensity)),color, -1, 8, 0 );
   // 蓝色  
   val = cvQueryHistValue_1D( bhist,h);
   intensity = cvRound(val*100/bmax);
   color = CV_RGB(0,0,255); //(hsv2rgb(i*180.f/hdims);
   cvRectangle( hist_img, cvPoint(h*scale,400),cvPoint((h+1)*scale,(int)(400 - intensity)),color, -1, 8, 0 );

}

cvNamedWindow("Histogram", 1 );
cvShowImage("Histogram", hist_img );

}

int main( int argc, char** argv )
{
   cvNamedWindow("video", CV_WINDOW_AUTOSIZE);
   const char * video = "huasha.avi";
   CvCapture* capture = cvCreateFileCapture(video);
   IplImage* frame;
   double hScale=1.0;
   double vScale=1.0;
   int    lineWidth=1;
   while(1) {
    frame = cvQueryFrame( capture );
    if( !frame ) break;
  
    showHist(frame);
    cvShowImage( "video", frame );
    char c = cvWaitKey(33);
    if( c == 27 ) break;
   }
   cvReleaseCapture( &capture );
   cvDestroyWindow( "video" );
   return 0;
}

0 0
原创粉丝点击