opencv中直方图的反向投影之cvCalcBackProjectPatch

cvCalcBackProjectPatch()是用于在被查找图像上查找给定的模版的位置,这也是反向投影的主要用途。具体算法如下:

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
1)从输入图像的左上角(0,0)开始,切割一块(0,0)(10,10)的临时图像;
2)生成临时图像的直方图;
3)用临时图像的直方图和模板图像的直方图对比,对比结果记为c
4)直方图对比结果c,就是结果图像(0,0)处的像素值;
5)切割输入图像从(0,1)(10,11)的临时图像,对比直方图,并记录到结果图像;
6)重复(1)~(5)步直到输入图像的右下角。

具体看下面例子:

#include<cv.h>
#include<highgui.h>
#include<stdio.h>

int main(int argc,char *argv[])
{
    cvNamedWindow("source");
    cvNamedWindow("result");
    IplImage *src  = cvLoadImage(argv[1]);
    IplImage *temp = cvLoadImage(argv[2]);
    IplImage *src_hsv = cvCreateImage(cvGetSize(src),8,3);
    IplImage *temp_hsv = cvCreateImage(cvGetSize(temp),8,3);
    cvCvtColor(src,src_hsv,CV_BGR2HSV);
    cvCvtColor(temp,temp_hsv,CV_BGR2HSV);

    //创建模版直方图
    IplImage *temp_h = cvCreateImage(cvGetSize(temp),8,1);
    IplImage *temp_s = cvCreateImage(cvGetSize(temp),8,1);
    IplImage *temp_v = cvCreateImage(cvGetSize(temp),8,1);
    cvSplit(temp_hsv,temp_h,temp_s,temp_v,NULL);
    int sizes[] = {30,32,32};
    float h_range[] = {0,180};
    float s_range[] = {0,255};
    float v_range[] = {0,255};
    float *ranges[] = {h_range,s_range,v_range};
    CvHistogram *hist = cvCreateHist(3,sizes,CV_HIST_ARRAY,ranges,1);
    IplImage *temp_planes[] = {temp_h,temp_s,temp_v};
    cvCalcHist(temp_planes,hist,0,NULL);
    cvNormalizeHist(hist,1);

    //进行反向投影
    IplImage *src_h = cvCreateImage(cvGetSize(src),8,1);
    IplImage *src_s = cvCreateImage(cvGetSize(src),8,1);
    IplImage *src_v = cvCreateImage(cvGetSize(src),8,1);
    cvSplit(src_hsv,src_h,src_s,src_v,NULL);
    IplImage *src_planes[] = {src_h,src_s,src_v};
    IplImage *dst = cvCreateImage(cvSize(src->width - temp->width + 1,src->height - temp->height + 1),IPL_DEPTH_32F,1);
    cvCalcBackProjectPatch(src_planes,dst,cvGetSize(temp),hist,CV_COMP_CORREL,1);
    
    //找出最匹配的位置
    CvPoint max_loc;
    cvMinMaxLoc(dst,NULL,NULL,NULL,&max_loc);
    max_loc.x += cvRound(temp->width / 2);
    max_loc.y += cvRound(temp->height / 2);
    cvCircle(src,max_loc,5,CV_RGB(255,0,0),-1);

    cvShowImage("source",src);
    cvShowImage("result",dst);
    cvWaitKey(0);

    cvReleaseImage(&src);
    cvReleaseImage(&dst);
    cvReleaseImage(&src_hsv);
    cvReleaseImage(&src_h);
    cvReleaseImage(&src_s);
    cvReleaseImage(&src_v);
    cvReleaseImage(&temp);
    cvReleaseImage(&temp_hsv);
    cvReleaseImage(&temp_h);
    cvReleaseImage(&temp_s);
    cvReleaseImage(&temp_v);
    cvDestroyWindow("source");
    cvDestroyWindow("result");
    return 0;
}

运行结果如下:

注意:该函数运行速度比较慢,本程序大概要运行2分钟左右

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值