国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

opencv學(xué)習(xí)筆記(三十)反向投影

2019-11-06 06:48:25
字體:
供稿:網(wǎng)友

小知識: HSV中的H分量,則大概對光線的變化會不敏感。如果選擇的是V分量,當(dāng)然光線的變量會影響結(jié)果了。如果選擇的是圖像的梯度,那就是檢查紋路的了。等等。 工作原理: 簡單的講, 所謂反向投影就是首先計(jì)算某一特征的直方圖模型,然后使用模型去尋找圖像中存在的該特征。 我們使用膚色直方圖為例來解釋反向投影的工作原理: 假設(shè)你已經(jīng)通過下圖得到一個膚色直方圖(Hue-Saturation), 旁邊的直方圖就是模型直方圖 (代表手掌的皮膚色調(diào))。你可以通過掩碼操作來抓取手掌所在區(qū)域的直方圖: 這里寫圖片描述 下圖是另一張手掌圖(測試圖像) 以及對應(yīng)的整張圖像的直方圖: 這里寫圖片描述 我們要做的就是使用模型直方圖 (代表手掌的皮膚色調(diào)) 來檢測測試圖像中的皮膚區(qū)域。以下是檢測的步驟: a.對測試圖像中的每個像素 ( p(i,j) ),獲取色調(diào)數(shù)據(jù)并找到該色調(diào)這里寫圖片描述 在直方圖中的bin的位置。 b.查詢模型直方圖中對應(yīng)的bin - 這里寫圖片描述 - 并讀取該bin的數(shù)值。 c.將此數(shù)值儲存在新的圖像中(BackPRojection)。 你也可以先歸一化模型直方圖,這樣測試圖像的輸出就可以在屏幕顯示了。 d.通過對測試圖像中的每個像素采用以上步驟, 我們得到了下面的 BackProjection 結(jié)果圖: 這里寫圖片描述 e.使用統(tǒng)計(jì)學(xué)的語言, BackProjection 中儲存的數(shù)值代表了測試圖像中該像素屬于皮膚區(qū)域的 概率 。比如以上圖為例, 亮起的區(qū)域是皮膚區(qū)域的概率更大(事實(shí)確實(shí)如此),而更暗的區(qū)域則表示更低的概率(注意手掌內(nèi)部和邊緣的陰影影響了檢測的精度)。

backproject的基本過程是: 1. 拿到 特征圖像 (或模板圖像) 2. 得到 特征圖像的直方圖 3. 拿到源圖像,依據(jù)源圖像的每個像素的值,在特征圖像的直方圖中找到對應(yīng)的值,然后將直方圖的值賦給新的圖像,backproject算法就完成了。

對于calcBackProjectPatch,整個是基于塊的形式,利用直方圖做匹配,類似于模板匹配,只不過這些模板轉(zhuǎn)換為直方圖,而原圖中以某點(diǎn)為基準(zhǔn),摳出來作對比的部分也轉(zhuǎn)換為直方圖,兩個直方圖作匹配,匹配的結(jié)果作為此點(diǎn)的值。 結(jié)果會是一張概率圖,概率越大的地方,代表此區(qū)域與模板的相似度越高。而且,當(dāng)模板小于檢測的目標(biāo)時,得到的結(jié)果圖也能反映出檢測區(qū)域的形狀。利用直方圖的方式,就能去除光照變化、邊緣遮擋,旋轉(zhuǎn)等因素的影響。 反向投影用于在輸入圖像(通常較大)中查找特定圖像(通常較小或者僅1個像素,以下將其稱為模板圖像)最匹配的點(diǎn)或者區(qū)域,也就是定位模板圖像出現(xiàn)在輸入圖像的位置。

工作原理2: 反向投影如何查找(工作)? 查找的方式就是不斷的在輸入圖像中切割跟模板圖像大小一致的圖像塊,并用直方圖對比的方式與模板圖像進(jìn)行比較。

假設(shè)我們有一張100x100的輸入圖像,有一張10x10的模板圖像,查找的過程是這樣的: (1)從輸入圖像的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時圖像; (2)生成臨時圖像的直方圖; (3)用臨時圖像的直方圖和模板圖像的直方圖對比,對比結(jié)果記為c; (4)直方圖對比結(jié)果c,就是結(jié)果圖像(0,0)處的像素值; (5)切割輸入圖像從(0,1)至(10,11)的臨時圖像,對比直方圖,并記錄到結(jié)果圖像; (6)重復(fù)(1)~(5)步直到輸入圖像的右下角。 特殊情況怎么樣? 如果輸入圖像和模板圖像一樣大,那么反向投影相當(dāng)于直方圖對比。如果輸入圖像比模板圖像還小,直接罷工。

cvCalcBackProject()函數(shù) 作用:計(jì)算反向投影 格式: void cvCalcBackProject( iplImage** image, CvArr* back_project, const CvHistogram* hist ); 參數(shù): image 單通道輸入圖像 (也可以傳遞 CvMat** ). back_project 單通道反向投影圖像,與輸入圖像具有同樣類型. hist

直方圖——I think應(yīng)當(dāng)是模板圖像的直方圖

函數(shù) cvCalcBackProject 計(jì)算直方圖的反向投影。 對于所有輸入的單通道圖像同一位置的像素?cái)?shù)組,該函數(shù)根據(jù)相應(yīng)的像素?cái)?shù)組,放置其對應(yīng)的直方塊的值到輸出圖像中。用統(tǒng)計(jì)學(xué)術(shù)語,輸出圖像像素點(diǎn)的值是觀測數(shù)組在某個分布(直方圖)下的概率。 例如,為了發(fā)現(xiàn)圖像中的紅色目標(biāo),可以這么做: 1 對紅色物體計(jì)算色調(diào)直方圖(I think就是H通道,hsv的h就是色調(diào)),假設(shè)圖像僅僅包含該物體。則直方圖有可能有極值,對應(yīng)著紅顏色。 2 對將要搜索目標(biāo)的輸入圖像,使用直方圖計(jì)算其色調(diào)平面的反向投影,然后對圖像做閾值操作。 3 在產(chǎn)生的圖像中發(fā)現(xiàn)連通部分,然后使用某種附加準(zhǔn)則選擇正確的部分,比如最大的連通部分。

反向投影程序

#include <cv.h>#include <highgui.h>int main(){ IplImage* src = cvLoadImage("h1.jpg"); if (src != NULL) { IplImage* hsv = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3); //將bgr圖像轉(zhuǎn)化為hsv圖像 cvCvtColor(src, hsv, CV_BGR2HSV); //創(chuàng)建3個單通道的圖像,用于將hsv圖像分離為3個通道 IplImage* h = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); IplImage* s = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); IplImage* v = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); IplImage* planes[] = {h, s}; //將hsv圖像分離 cvCvtPixToPlane(hsv, h, s, v, 0);//相當(dāng)于cvSplit//在h通道上設(shè)定30個劃分度,在s通道上設(shè)定32個劃分度 int h_bins(30), s_bins(32); CvHistogram* hist; { int hist_size[] = {h_bins, s_bins}; float h_ranges[] = {0, 180}; float s_ranges[] = {0, 255};//將h通道上的范圍,即[0,180],以及s通道上的范圍,即[0,255]組織成函數(shù)cvCreateHist所需的形式 float* ranges[] = {h_ranges, s_ranges}; //創(chuàng)建一個2維的、h維上劃分度為30、s維上劃分度為32的均分直方圖 hist = cvCreateHist(2, hist_size, CV_HIST_ARRAY, ranges, 1); } //通過源圖像上的h與s通道上圖像數(shù)據(jù)統(tǒng)計(jì)出直方圖 cvCalcHist(planes, hist, 0, 0); //獲取得到的直方圖的所有數(shù)據(jù)的和 CvScalar sc = cvSum(hist->bins);float sum = sc.val[0] + sc.val[1] + sc.val[2] + sc.val[3]; //歸一化直方圖 cvNormalizeHist(hist, 1.0);//scale:每一個劃分在用于顯示的圖像上所占的像素點(diǎn)數(shù) int scale = 10; IplImage* img = cvCreateImage(cvSize(h_bins * scale, s_bins * scale), IPL_DEPTH_8U, 3); cvZero(img);//為什么要求最大值呢?由于歸一化之后的圖像中的像素點(diǎn)的值都不會大于1,那么在人眼看來都是黑色的一片,沒法通過圖像來直觀的感受直方圖了,所以在下邊會通過將直方圖的值和直方圖中的最大值做除法,再乘以255,使人眼能看出直方圖中數(shù)值的變化 float max_value = 0; cvGetMinMaxHistValue(hist, NULL, &max_value, 0, 0); for (int h = 0; h < h_bins; ++h) { for (int s = 0; s < s_bins; ++s) { //訪問直方圖在關(guān)于h與s所確定的顏色的數(shù)值 float bin_val = cvQueryHistValue_2D(hist, h, s); int intensity = cvRound(bin_val * 255 / max_value); cvRectangle(img, cvPoint(h * scale, s * scale), cvPoint((h + 1) * scale - 1, (s + 1) * scale - 1), CV_RGB(intensity, intensity, intensity),CV_FILLED); } } cvNamedWindow("src"); cvShowImage("src", src); cvNamedWindow("img"); cvShowImage("img", img);IplImage* img2 = cvLoadImage("hand2.jpg");IplImage* hsv2 = cvCreateImage(cvGetSize(img2), IPL_DEPTH_8U, 3);cvCvtColor(img2, hsv2, CV_BGR2HSV);IplImage* h2 = cvCreateImage(cvGetSize(img2), IPL_DEPTH_8U, 1);IplImage* s2 = cvCreateImage(cvGetSize(img2), IPL_DEPTH_8U, 1);IplImage* v2 = cvCreateImage(cvGetSize(img2), IPL_DEPTH_8U, 1);IplImage* planes2[] = {h2, s2};cvCvtPixToPlane(hsv2, h2, s2, v2, 0);IplImage* backProject = cvCreateImage(cvGetSize(img2), IPL_DEPTH_8U, 1); cvSetZero(backProject); cvNormalizeHist(hist, sum); cvCalcBackProject(planes2, backProject, hist); cvNamedWindow("img2"); cvShowImage("img2", img2); cvNamedWindow("back project"); cvShowImage("back project", backProject); //釋放資源 cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&img); cvReleaseImage(&backProject); cvReleaseImage(&img2); cvReleaseHist(&hist); } return 0;}

程序理解: 用的是 http://www.cnblogs.com/slysky/archive/2011/10/13/2210745.html 里面的代碼——刪掉了一些,個人感覺其中有一部分是建立一個我沒看懂的直方圖,刪掉了。 這個程序的思路是先建立一個H-S二維直方圖,過程和實(shí)例2:建立一個二維直方圖(書上的例子)是一毛一樣的。接著,將待測圖片的h和s通道分離出來,然后反向投影,就可以了。 代碼很有用,標(biāo)準(zhǔn)圖片和待測圖片之間沒有大小關(guān)系。

特別注意: 使用這個代碼,有一點(diǎn)要注意。其中有幾句很關(guān)鍵: //獲取得到的直方圖的所有數(shù)據(jù)的和 CvScalar sc = cvSum(hist->bins); float sum = sc.val[0] + sc.val[1] + sc.val[2] + sc.val[3]; 然后,在 cvCalcBackProject(planes2, backProject, hist); 之前,先要有: cvNormalizeHist(hist, sum); ——很關(guān)鍵,如果刪掉,最終結(jié)果就是一片漆黑。 為什么會這樣呢? 我想了想是這樣的,如果歸一化了,直方圖所有數(shù)據(jù)之和為1,這個直方圖相當(dāng)于所有數(shù)據(jù)被壓縮了。那么按照這個直方圖反向投影,所有的像素都不會超過1——不是真實(shí)的情況。 但是如果獲取得到的直方圖的所有數(shù)據(jù)的和,然后cvNormalizeHist(hist, sum);就可以反映真實(shí)情況了,所以圖像可以準(zhǔn)確地顯示出來。 那么又有一個問題,為什么前面還有一個: //歸一化直方圖 cvNormalizeHist(hist, 1.0); 因?yàn)檫@個語句是為了畫出H-S二維直方圖,所以會有這個。

所用的圖片 h1 這里寫圖片描述 hand2 這里寫圖片描述


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阜康市| 资中县| 蒲城县| 定兴县| 通城县| 绍兴市| 灌南县| 雷州市| 二手房| 调兵山市| 徐州市| 栖霞市| 绥江县| 磐石市| 濮阳市| 武功县| 吐鲁番市| 上犹县| 乐昌市| 周口市| 潼南县| 岐山县| 金沙县| 临沂市| 黑山县| 定日县| 嵊州市| 民县| 通化市| 汝城县| 东海县| 鄂伦春自治旗| 炉霍县| 游戏| 都安| 彭阳县| 南靖县| 贺兰县| 南华县| 宜阳县| 南昌市|