小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

學(xué)習(xí)opencv 使用反向塊投影搜尋圖像中的物體的位置 cvCalcBackProject...

 oskycar 2012-10-24

前一篇講了使用cvCalcBackProject 尋找 手 的膚色地方 

這一篇講 在一幅圖像中尋找 某個特定的小物體


步驟:

1.使用一幅只包含小物體的圖片(圖片大小和物體一樣大即可, 不需要向上一篇同樣大),計算其二維直方圖 (HSV空間中的 h(亮度)和 s (飽和度) 二維直方圖   (還可以和圖像的梯度和(或)梯度角度結(jié)合起來,查找紋理相似 和(或) 顏色相似

2.輸入一幅待搜索的圖片, 轉(zhuǎn)化為HSV空間 ,只取h 和 s 分量

3. 設(shè)置搜索塊大小和物體大小相同(即和第1步中圖片大小相同) ,使用cvCalcBackProjectPatch反向塊投影 和圖片result

4.在result中取最大值所在位置,即可得到物體在輸入圖片中的位置了。 (或者設(shè)定一個閾值)

示例程序如下:

 #include <iostream>
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>
using namespace std;
void GetHSV(const IplImage *image,IplImage **h,IplImage **s,IplImage **v);
int main()
{
 IplImage *src = cvLoadImage("f:\\images\\bluecup.jpg");
 IplImage *h_src = NULL ,*s_src = NULL;
 GetHSV(src,&h_src,&s_src,NULL);
 IplImage *images[] = {h_src,s_src};
 CvHistogram *hist_src;
 {//計算二維直方圖
  int dims = 2;
  int size[] = {30,32}; // 這個地方不要取的太大!
  //當(dāng)取為size[] = {180,256}時E7200CPU會運(yùn)行長達(dá)10幾分鐘的!
  float range_h[] = {0,180} //再用cvCvtColor轉(zhuǎn)換時h已經(jīng)歸一化到180了
   ,range_s[] = {0,256};
  float *ranges[] = {range_h,range_s};
  hist_src = cvCreateHist(dims,size,CV_HIST_ARRAY,ranges);
  cvCalcHist(images,hist_src);
  cvNormalizeHist(hist_src,1);
 }
 IplImage *dst = cvLoadImage("f:\\images\\adrian1.jpg");
 IplImage *h_dst = NULL,*s_dst = NULL;
 GetHSV(dst,&h_dst,&s_dst,NULL);
 images[0] = h_dst ,images[1] = s_dst;
 CvSize patch_size = cvSize(src->width,src->height);
 IplImage *result = cvCreateImage(cvSize(h_dst->width - patch_size.width +1,h_dst->height - patch_size.height +1)
  ,IPL_DEPTH_32F,1);//塊搜索時處理邊緣是直接舍去,故result的大小比dst小path_size大小
 //32F類型,取值為0~1最亮為1,可直接顯示
 //CV_COMP_CORREL相關(guān)度,1時最匹配,0時最不匹配
 cvCalcBackProjectPatch(images,result,patch_size,hist_src,CV_COMP_CORREL,1);
 cvShowImage("result",result);
 
 //找出最大值位置,可得到此位置即為杯子所在位置
 CvPoint max_location;
 cvMinMaxLoc(result,NULL,NULL,NULL,&max_location,NULL);
 //加上邊緣,得到在原始圖像中的實(shí)際位置
 max_location.x += cvRound(patch_size.width/2);
 max_location.y += cvRound(patch_size.height/2);
 //在dst圖像中用紅色小圓點(diǎn)標(biāo)出位置
 cvCircle(dst,max_location,3,CV_RGB(255,0,0),-1);
 cvShowImage("dst",dst);
 cvWaitKey();
 cvReleaseImage(&src);
 cvReleaseImage(&dst);
 cvReleaseImage(&h_src);
 cvReleaseImage(&h_dst);
 cvReleaseImage(&s_dst);
 cvReleaseImage(&s_src);
 cvReleaseHist(&hist_src);
 cvReleaseImage(&result);
 cvDestroyAllWindows();
}
void GetHSV(const IplImage *image , IplImage **h,IplImage **s,IplImage **v)
{
 IplImage *hsv = cvCreateImage(cvGetSize(image),8,3);
 cvCvtColor(image,hsv,CV_BGR2HSV);
 
 if((h != NULL) && (*h == NULL))
  *h = cvCreateImage(cvGetSize(image),8,1);
 if((s != NULL) && (*s == NULL))
  *s = cvCreateImage(cvGetSize(image),8,1);
 if((v != NULL) && (*v == NULL))
  *v = cvCreateImage(cvGetSize(image),8,1);

 cvSplit(hsv,*h,(s == NULL)?NULL:*s,(v==NULL)?NULL:*v,NULL);
 cvReleaseImage(&hsv);
}
 
第一步物體圖片src剛好包含要搜索的物體:



第二步輸入圖像即待搜索的圖像如下:

 

在我的E7200 CPU , 1GB內(nèi)存 上大概運(yùn)行了20秒內(nèi)吧,將size內(nèi)的數(shù)應(yīng)該可以再適當(dāng)改的更小此,速度就會提高更多了

結(jié)果如下(見圖中紅色小圓圈標(biāo)記出來):



若待搜索的圖片里有多個此物體,也是可以通過這種方法找出來的


產(chǎn)于cvCalcBackProjectPatch的大概意義 ,

按我的理解的話,應(yīng)該是通過塊窗口搜索圖像,比較窗口中對應(yīng)像素的二維直方圖與給定直方圖的差異,若完全相同,那當(dāng)然就越匹配

對于不同的相關(guān)度方法,越匹配,其值由相關(guān)度方法而定,

如本程序使用的是

CV_COMP_CORREL  

即越相似,則值越接近1. 反之則趨于0


其實(shí)使用的時候還可以將圖像的梯度考慮進(jìn)去求解,

如求出圖像的梯度+色彩的多維直方圖,這樣就能得搜索到一定紋理特征和顏色特征的物體了。

ps:此方法搜索是通過統(tǒng)計學(xué)特征相似度!和模板匹配法是不同的,各有個的用途

如果只是為了檢測某個不變的實(shí)物,,還不如使用模板匹配函數(shù),更快

轉(zhuǎn)載請注明出處,若有錯誤,請大家指正.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多