在室內條件下,用一些手和臉來建立h-s直方圖(膚色的直方圖)
利用函式calcbackproject()來找到膚色區域,分別代表了不同手勢
對所找到的手勢進行直方圖建立模型,從而可作為後續輸入手勢的手勢識別器。
首先是膚色直方圖的建,我使用的是如左下圖所示的**影象,可以計算出其二維直方圖,作為膚色的描述子,如右圖所示。
下一步是通過calcbackproject()尋找不同手勢,這一步比較簡單,如下圖所示為反投影出的一些手勢
手勢1
手勢2
手勢3形態學去噪
首先將投影出的影象轉換為二值化影象,更易於處理,使用開操作+閉操作的方法去噪
輪廓提取
輪廓提取有兩個目的,一是通過檢測輪廓長度可以去除較小的輪廓(同樣是雜訊),二是可以提取出手型輪廓的座標資訊。
漫水填充
計算輪廓座標的質心,可以認為在手型的內部。可以將該點作為種子點,做漫水填充,這一步是為了解決輪廓內很多黑洞的問題。
下圖為形態學去噪的結果,除了黑洞外,還是有一些小雜訊。
形態學去噪
再對形態學去噪影象的輪廓提取影象,由於要求輪廓長度大於影象周長的四分之一,右上角的小塊雜訊已經不見了,如下圖。
輪廓影象
通過計算輪廓的零階矩和一階矩就可以計算出輪廓的質心座標,該座標作為下一步漫水填充的種子點。
為漫水填充的演算法的使用建立乙個新的模板,填充過後為1的點,我們就可以認為是手勢的區域,該mask可以傳入直方圖計算函式,僅僅計算手勢的直方圖分布。
在試驗過程中可以發現opencv中漫水填充演算法中的lodiff和updiff並不好選,需要多次嘗試才可以找到比較滿意的結果,由於手的邊緣有一些陰影,因此如果lodiff取的較大的話常常會得到更多的填充區域。
如下圖,為填充過後的模板區域。
漫水填充結果
可以跟最初反投影計算結果比較,此時的模板更加符合乙個剪刀手勢了,也就是我們真正感興趣的區域。通過下一步函式,就可以建立該手勢的直方圖。
hist = cvcalchist(img,hist_size,range,1,flood_fill_mask);
因此,通過不同的手勢影象學習,我們就可以獲得不同手勢的直方圖了,即完成手勢模型的建立。
後續實驗:
既然已經建立了手勢的模型,我便希望可以完成手勢識別,採用了基於塊的反向投影函式calcbackprojectpatch(),實驗影象如左下所示,實驗結果右下所示:
可以看出在複雜的背景條件下,同時檢測出了手勢以及臉型。因此可以說明前面所建立的剪刀手直方圖是不完善的,即可以檢測出**,但對**形狀不能進行分類,因此,如果將更多的資訊考慮在內,可能會收穫更好地效果(例如輪廓hu矩)。
直方圖是一種基於統計學的操作,不受平移或旋轉的影響,因此它用於目標資訊的學習和檢測效果還是不錯的。但該方法會受到光線變化、陰影等影響,一種解決辦法是學習不同光照下的直方圖,進行多次匹配,但從實驗過程中可知,直方圖匹配的過程是比較慢的,因此實時性較差。
#include
#include
using
namespace cv;
int main()
; // hue varies from 0 to 179, see cvtcolor
float hranges = ;
// saturation varies from 0 (black-gray-white) to
// 255 (pure spectrum color)
float sranges = ;
const
float* ranges = ;
ma*** hist;
// we compute the histogram from the 0-th and 1-st channels
int channels = ;
calchist( &hsv_skin, 1, channels, mat(), // do not use mask
hist, 2, histsize, ranges,
true, // the histogram is uniform
false );
//反投影
ma*** back_pro;
calcbackproject(&hsv_gesture,1,channels,hist,back_pro,ranges,1.0);
//二值化
threshold(back_pro,back_pro,30,255,cv_thresh_binary);
//去噪
mat k = getstructuringelement(morph_rect,size(3,3), point(-1,-1));
morphologyex(back_pro,back_pro,morph_open,k);
morphologyex(back_pro,back_pro,morph_close,k);
尋找輪廓(目標為尋找質心),此處不直接使用掩模影象,也是為了多目標分離
//flood fill尋找區域
//利用mask建立手勢直方圖
ma*** gesture_hist;
calchist( &hsv_gesture, 1, channels,back_pro , // use mask
gesture_hist, 2, histsize, ranges,
true, // the histogram is uniform
false );
//讀入影象測試
OpenCV 基於YCrCb顏色空間的膚色檢測
膚色ycbcr顏色空間是一種常用的膚色檢測的色彩模型,其中y代表亮度,cr代表光源中的紅色分量,cb代表光源中的藍色分量。人的膚色在外觀上的差異是由色度引起的,不同人的膚色分布集中在較小的區域內。膚色的ycbcr顏色空間cbcr平面分布在近似的橢圓區域內,通過判斷當前畫素點的cbcr是否落在膚色分布...
一 反向投影的原理說明(1)
目標 一 概念 反向投影是一種記錄給定影象中的畫素點如何適應直方圖模型畫素分布的方式。簡單的講,就是首先計算某一特徵的直方圖模型,然後使用模型去尋找影象中存在的該特徵。例如,你有乙個膚色直方圖 hue saturation直方圖 你可以用它來尋找影象中的膚色區域 1 直方圖反向投影矩陣的計算方法 什...
基於OpenCV的任意方向投影
目前在opencv中,有reduce函式可以進行水平或者垂直方向的投影。c voidreduce inputarraymtx,outputarrayvec,intdim,intreduceop,intdtype 1 parameters reduction operation that could ...