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

 

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值