您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python傳統圖像處理皮膚區域檢測的方法有哪些”,在日常操作中,相信很多人在Python傳統圖像處理皮膚區域檢測的方法有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python傳統圖像處理皮膚區域檢測的方法有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
膚色在RGB模型下的范圍基本滿足以下約束:
在均勻光照下應滿足以下判別式:
R>95 AND G>40 B>20 AND MAX(R,G,B)-MIN(R,G,B)>15 AND ABS(R-G)>15 AND R>G AND R>B
在側光拍攝環境下:
R>220 AND G>210 AND B>170 AND ABS(R-G)<=15 AND R>B AND G>B
代碼:
def skinMask_rgb(image): b, g, r = cv2.split(image) mask_uniformity = (r>95)*(g>40)*(b>20)* (np.max(image, axis=2) -np.min(image,axis=2)>15)* (abs(r-g)>15)*(r>g)*(r>b) mask_side = (r>220)*(g>210)*(b>170)*(abs(r-g)<=15)*(r>b)*(g>b) mask = mask_uniformity|mask_side skin = np.array(mask, np.uint8)*255 ratio = np.sum(skin/255)/(image.shape[0]*image.shape[1]) return skin, ratio
效果:
在RGB空間里人臉的膚色受亮度影響相當大,所以膚色點很難從非膚色點中分離出來,也就是說在此空間經過處理后,膚色點是離散的點,中間嵌有很多非膚色。如果把RGB轉為YCrCb空間的話,可以忽略Y(亮度)的影響,因為該空間受亮度影響很小,膚色會產生很好的類聚。這樣就把三維的空間降為二維的CrCb,膚色點會形成一定得形狀。
133≤Cr≤173
77≤Cb≤127
代碼:
def skinMask_YCrCb(image): YCrCb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) #轉換至YCrCb空間 (y,cr,cb) = cv2.split(YCrCb) #拆分出Y,Cr,Cb值 skin = np.zeros(cr.shape, dtype = np.uint8) (x,y) = cr.shape cr_mask1 = cr >= 133 cr_mask2 = cr <= 173 cr_mask = cr_mask1 * cr_mask2 cb_mask1 = cb >= 77 cb_mask2 = cb <= 127 cb_mask = cb_mask1 * cb_mask2 mask = cr_mask * cb_mask skin[mask] = 255 ratio = np.sum(skin/255)/(x*y) return skin, ratio
效果:
Y表示明亮度(Luminance或Luma),也就是灰階值。Cr反映了RGB輸入信號紅色部分與RGB信號亮度值之間的差異。而Cb反映的是RGB輸入信號藍色部分與RGB信號亮度值之間的差異。
將RGB圖像轉換到YCrCb顏色空間,提取Cr分量圖像。對Cr做自二值化閾值分割處理(Otsu法)。
代碼:
def skinMask_YCrCb_otsu(image): YCrCb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) #轉換至YCrCb空間 (y,cr,cb) = cv2.split(YCrCb) #拆分出Y,Cr,Cb值 ret, skin = cv2.threshold(cr, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) ratio = np.sum(skin/255)/(image.shape[0]*image.shape[1]) return skin, ratio
效果:
7<H<20
28<S<256
50<V<256
代碼:
def skinMask_hsv(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) mask = (h>7)*(h<20)*(s>28)*(v>50) skin = np.array(mask, np.uint8)*255 ratio = np.sum(skin/255)/(image.shape[0]*image.shape[1]) return skin, ratio
效果:
已經從opencv 3以上版本中移除,opencv 2中函數。
將皮膚信息映射到YCrCb空間,則在CrCb二維空間中這些皮膚像素點近似成一個橢圓分布。因此如果我們得到了一個CrCb的橢圓,下次來一個坐標(Cr, Cb)我們只需判斷它是否在橢圓內(包括邊界),如果是,則可以判斷其為皮膚,否則就是非皮膚像素點。
代碼:
def skinMask_ellipse(image): YCrCb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) #轉換至YCrCb空間 (y,cr,cb) = cv2.split(YCrCb) #拆分出Y,Cr,Cb值 skinCrCbHist = np.zeros((256,256),np.uint8) skinCrCbHist = cv2.ellipse(skinCrCbHist, (113, 155), (23, 15), 43.0, 0.0, 360.0, (255, 255, 255), -1) cv2.imwrite("ww.jpg", skinCrCbHist) skin = cv2.remap(skinCrCbHist, cb.astype(np.float32), cr.astype(np.float32), interpolation=cv2.INTER_LINEAR) ratio = np.sum(skin/255)/(image.shape[0]*image.shape[1]) return skin, ratio
效果:
橢圓模型
效果
反向投影可以用來做圖像分割,尋找感興趣區間。可以尋找任何的roi,這里將其用作尋找人體膚色。它會輸出與輸入圖像大小相同的圖像,每一個像素值代表了輸入圖像上對應點屬于目標對象的概率,簡言之,輸出圖像中像素值越高的點越可能代表想要查找的目標。直方圖投影經常與camshift(追蹤算法)算法一起使用。
操作步驟:
(1)截取若干張不同膚色的圖片,最好覆蓋常見的所有膚色(如下圖)
(2)對所有膚色的圖片一起做色彩直方圖(利用OpenCV中的calcHist函數)
(3)新建一個與待檢測圖片同尺寸的灰度圖片,找到待檢測圖片中每顆像素點的顏色在色彩直方圖中對應柵格的數值(即統計中出現的次數),并將該數值賦值予新建灰度圖片中與該檢測像素同位置的像素(利用OpenCV中的calcBackProject函數)。圖像中像素亮度越高,待檢測圖像該位置處是膚色的概率越大。
代碼:
def skinMask_hist_backproject(target, roi_image): #roi圖片,就想要找的的圖片 hsv = cv2.cvtColor(roi_image,cv2.COLOR_BGR2HSV) #目標搜索圖片 hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV) #計算目標直方圖 roihist = cv2.calcHist([hsv],[0,1],None,[180,256],[0,180,0,256]) #歸一化,參數為原圖像和輸出圖像,歸一化后值全部在2到255范圍 cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX) dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1) #卷積連接分散的點 disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) dst = cv2.filter2D(dst,-1,disc) ret,skin = cv2.threshold(dst,50,255,0) ratio = np.sum(skin/255)/(target.shape[0]*target.shape[1]) return skin, ratio
效果:
到此,關于“Python傳統圖像處理皮膚區域檢測的方法有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。