OpenCV入门(二十四)-- 图块的反向投影

来源:互联网 发布:mt4软件平台 编辑:程序博客网 时间:2024/06/12 01:03
 

CalcBackProjectPatch有两种用法:当采样窗口小于目标时,作为区域检测器,当采样窗口和目标窗口一般大时,作为目标检测器。

CalcBackProjectPatch


用直方图比较来定位图像中的模板

void cvCalcBackProjectPatch( IplImage** image, CvArr* dst,                             CvSize patch_size, CvHistogram* hist,                             int method, double factor );
image
输入图像 (可以传递 CvMat** )
dst
输出图像.
patch_size
扫描输入图像的补丁尺寸
hist
直方图
method
比较方法,传递给 cvCompareHist (见该函数的描述).
factor
直方图的归一化因子,将影响输出图像的归一化缩放。如果为 1,则不定。 /*归一化因子的类型实际上是double,而非float*/

函数 cvCalcBackProjectPatch 通过输入图像补丁的直方图和给定直方图的比较,来计算反向投影。提取图像在 ROI 中每一个位置的某种测量结果产生了数组 image. 这些结果可以是色调, x 差分, y 差分, Laplacian 滤波器, 有方向 Gabor 滤波器等中 的一个或多个。每种测量输出都被划归为它自己的单独图像。 image 图像数组是这些测量图像的集合。一个多维直方图 hist 从这些图像数组中被采样创建。最后直方图被归一化。直方图 hist 的维数通常很大等于图像数组 image 的元素个数。

在选择的 ROI 中,每一个新的图像被测量并且转换为一个图像数组。在以锚点为“补丁”中心的图像 image 区域中计算直方图 (如下图所示)。用参数 norm_factor 来归一化直方图,使得它可以与 hist 互相比较。计算出的直方图与直方图模型互相比较, (hist 使用函数 cvCompareHist ,比较方法是 method=method). 输出结果被放置到概率图像 dst 补丁锚点的对应位置上。这个过程随着补丁滑过整个 ROI 而重复进行。迭代直方图的更新可以通过在原直方图中减除“补丁”已复盖的尾象素点或者加上新复盖的象素点来实现,这种更新方式可以节省大量的操作,尽管目前在函数体中还没有实现。

Back Project Calculation by Patches

Image:Backprojectpatch.png


举例,采样窗口小于目标:

原始图形:


检测区域:



代码:

/*区域检测*/#include "highgui.h"#include "cv.h"#include "cxcore.h"void dobackProject2(IplImage* img){IplImage* patch = cvLoadImage("ad.gif");IplImage* hsv = cvCreateImage(cvGetSize(patch), 8, 3);cvCvtColor(patch,hsv,CV_BGR2HSV);IplImage* h_plane = cvCreateImage(cvGetSize(patch), 8, 1);IplImage* s_plane = cvCreateImage(cvGetSize(patch), 8, 1);IplImage* v_plane = cvCreateImage(cvGetSize(patch), 8, 1);cvSplit(hsv, h_plane, s_plane, v_plane, 0);IplImage* planes[] = {h_plane, s_plane};//设置直方图每个灰度级的数目int h_bins = 30;int 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 = cvCreateHist(2,hist_size, CV_HIST_ARRAY, ranges);cvCalcHist(planes, hist);cvNormalizeHist(hist,1);//目标图像IplImage* img_hsv = cvCreateImage(cvGetSize(img),8,3);cvCvtColor(img, img_hsv, CV_BGR2HSV);IplImage* h_planei = cvCreateImage(cvGetSize(img), 8, 1);IplImage* s_planei = cvCreateImage(cvGetSize(img), 8, 1);IplImage* v_planei = cvCreateImage(cvGetSize(img), 8, 1);cvSplit(img_hsv, h_planei, s_planei, v_planei, 0);IplImage* planesi[] = {h_planei, s_planei};int iwidth = img->width - patch->width + 1;int iheight = img->height - patch->height + 1;IplImage* dst = cvCreateImage(cvSize(iwidth, iheight), 32, 1);//利用相关法cvCalcBackProjectPatch(planesi,dst,cvSize(patch->width, patch->height), hist,CV_COMP_CORREL,1);cvNamedWindow("dst",1);cvShowImage("dst", dst);double minv;double maxv;CvPoint minl;CvPoint maxl;cvMinMaxLoc(dst, &minv,&maxv,&minl,&maxl,NULL);cvRectangle(img,cvPoint(maxl.x, maxl.y),cvPoint((maxl.x+patch->width),(maxl.y + patch->height)),CV_RGB(255,0,0),1);cvNamedWindow("match",1);cvShowImage("match",img);cvWaitKey(0);}

输出结果:



参考:

http://wiki.opencv.org.cn/index.php/Cv%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86#CompareHist

0 0
原创粉丝点击