OpenCV基础04(直方图与匹配)

来源:互联网 发布:四班三倒排班表软件 编辑:程序博客网 时间:2024/05/16 01:57
第七章 直方图与匹配

详细请看:http://blog.csdn.net/xiaowei_cqu/article/details/7600666
1)直方图数据结构:
typename struct CvHistogram{int type;CvArr* bins;float thresh[CV_MAX_DIM][2];float** thresh2;CvMatND mat;//很多数据都在这个矩阵中,可以访问}CvHistogram;
    直方图的创建、计算和访问,匹配:
//创建直方图CvHistogram* cvCreateHist(...);CvHistogram* cvMakeHistHeaderForArray(..);//根据已知的数据创建直方图;void cvCalcHist(..);//从图像计算直方图,调用之前要用cvSplit()进行通道分割void cvSetHistBinRanges(...);//设置直方图ranges范围void cvReleaseHist(..);//释放直方图//直方图的访问void cvQueryHistValue_1D(...);//对应有_2D,_3D,_nD,访问直方图bins中的数据,也可以hist->bins来访问。float* cvGetHistValue_1D(...);//同上。//直方图操作cvNormalizeHist(...);//直方图归一化cvThreshHist(..);//直方图阈值(对bins值的阈值)cvCopyHist(..);//复制double cvCompareHist(...);//直方图匹配,可以选择距离测量的方法

2)陆地移动距离(EMD)

     光线的变化能引起图像颜色值的漂移,尽管这些漂移没有改变颜色直方图的形状,但是这些漂移引起了颜色值位置的变化,从而导致匹配策略失效。

陆地移动距离是一种度量准则,它实际上市度量怎样将一个直方图转变为另一个直方图的形状,包括移动直方图的部分(或全部)到一个新的位置,可以在任何维的直方图上进行这种度量。

CalcEMD2

两个加权点集之间计算最小工作距离

float cvCalcEMD2( const CvArr* signature1, const CvArr* signature2, int distance_type,                  CvDistanceFunction distance_func=NULL, const CvArr* cost_matrix=NULL,                  CvArr* flow=NULL, float* lower_bound=NULL, void* userdata=NULL );typedef float (*CvDistanceFunction)(const float* f1, const float* f2, void* userdata);
例子,来自:http://blog.csdn.net/thystar/article/details/40934073
/*用EMD度量两个分布的相似性这里,用lena和lena直方图均衡化的结果度量。*/#include "highgui.h"#include "cv.h"#include<iostream>using namespace std;void doEMD2(IplImage* img){/*对输入的图像做直方图均衡化处理,生成img2*/IplImage* pImageChannel[4] = {0, 0, 0, 0};IplImage* img2 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);for(int i = 0; i < img->nChannels; i++){pImageChannel[i] = cvCreateImage(cvGetSize(img), img->depth,1);}//信道分离cvSplit(img, pImageChannel[0], pImageChannel[1], pImageChannel[2],pImageChannel[3]);for(int i = 0; i < img2->nChannels; i++){//直方图均衡化cvEqualizeHist(pImageChannel[i], pImageChannel[i]);}//信道组合cvMerge(pImageChannel[0],pImageChannel[1], pImageChannel[2],pImageChannel[3], img2);//绘制直方图int h_bins = 16, s_bins = 8;int hist_size[] = {h_bins, s_bins};//H 分量的变化范围float h_ranges[] = {0,180};//S 分量的变化范围float s_ranges[] = {0,255};float* ranges[] = {h_ranges,s_ranges};IplImage* hsv = cvCreateImage(cvGetSize(img), 8, 3);IplImage* hsv2 = cvCreateImage(cvGetSize(img2), 8, 3);IplImage* h_plane = cvCreateImage(cvGetSize(img), 8, 1);IplImage* s_plane = cvCreateImage(cvGetSize(img), 8, 1);IplImage* v_plane = cvCreateImage(cvGetSize(img), 8, 1);IplImage* planes[] = {h_plane, s_plane};IplImage* h_plane2 = cvCreateImage(cvGetSize(img2), 8, 1);IplImage* s_plane2 = cvCreateImage(cvGetSize(img2), 8, 1);IplImage* v_plane2 = cvCreateImage(cvGetSize(img2), 8, 1);IplImage* planes2[] = {h_plane2, s_plane2};// 将两幅图像转换到HSV颜色空间cvCvtColor(img, hsv, CV_BGR2HSV);cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, 0);cvCvtColor(img2, hsv2, CV_BGR2HSV);cvCvtPixToPlane(hsv2, h_plane2, s_plane2, v_plane2, 0);// 创建直方图CvHistogram* hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);CvHistogram* hist2 = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1);// 根据H,S两个平面数据统计直方图cvCalcHist(planes, hist, 0, 0);cvCalcHist(planes2, hist2, 0, 0);//获取直方图统计///float max_value;//float max_value2;//cvGetMinMaxHistValue(hist, 0, &max_value, 0,0);//cvGetMinMaxHistValue(hist2, 0, &max_value2, 0, 0);//设置直方图显示图像int height = 240;int width = (h_bins * s_bins * 6);IplImage* hist_img = cvCreateImage(cvSize(width, height), 8, 3);IplImage* hist_img2 = cvCreateImage(cvSize(width, height), 8, 3);cvZero(hist_img);cvZero(hist_img2);//用来进行HSV到RGB颜色转换的临时图像//IplImage* hsv_color = cvCreateImage(cvSize(1,1), 8, 3);//IplImage* rgb_color = cvCreateImage(cvSize(1,1), 8, 3);//int bin_w = width/(h_bins * s_bins);//CvMat* sig1, *sig2;int numrows = h_bins*s_bins;sig1 = cvCreateMat(numrows, 3, CV_32FC1);sig2 = cvCreateMat(numrows, 3, CV_32FC1);for(int h = 0; h < h_bins; h++){for(int s = 0; s < s_bins; s++){//int i = h * s_bins + s;// 获得直方图中的统计次数, 计算显示在图中的高度float bin_val = cvQueryHistValue_2D(hist, h,s);cvSet2D(sig1, h*s_bins + s, 0, cvScalar(bin_val));cvSet2D(sig1, h*s_bins + s, 1, cvScalar(h));cvSet2D(sig1, h*s_bins + s, 2, cvScalar(s));bin_val = cvQueryHistValue_2D(hist2,h,s);cvSet2D(sig2, h*s_bins + s, 0, cvScalar(bin_val));cvSet2D(sig2, h*s_bins + s, 1, cvScalar(h));cvSet2D(sig2, h*s_bins + s, 2, cvScalar(s)); }}float emd = cvCalcEMD2(sig1,sig2,CV_DIST_L2);cout<< emd<<endl;}

3)反投影
void cvCalcBackProjectPatch( IplImage** image, CvArr* dst,                             CvSize patch_size, CvHistogram* hist,                             int method, double factor );





0 0
原创粉丝点击