Python傳統(tǒng)圖像處理之皮膚區(qū)域檢測(cè)詳解
1.RGB空間
膚色在RGB模型下的范圍基本滿(mǎn)足以下約束:
在均勻光照下應(yīng)滿(mǎn)足以下判別式:
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
在側(cè)光拍攝環(huán)境下:
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
效果:


2.Ycrcb空間
在RGB空間里人臉的膚色受亮度影響相當(dāng)大,所以膚色點(diǎn)很難從非膚色點(diǎn)中分離出來(lái),也就是說(shuō)在此空間經(jīng)過(guò)處理后,膚色點(diǎn)是離散的點(diǎn),中間嵌有很多非膚色。如果把RGB轉(zhuǎn)為YCrCb空間的話,可以忽略Y(亮度)的影響,因?yàn)樵摽臻g受亮度影響很小,膚色會(huì)產(chǎn)生很好的類(lèi)聚。這樣就把三維的空間降為二維的CrCb,膚色點(diǎn)會(huì)形成一定得形狀。
133≤Cr≤173
77≤Cb≤127
代碼:
def skinMask_YCrCb(image):
YCrCb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) #轉(zhuǎn)換至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
效果:


3.Ycrcb空間+otsu
Y表示明亮度(Luminance或Luma),也就是灰階值。Cr反映了RGB輸入信號(hào)紅色部分與RGB信號(hào)亮度值之間的差異。而Cb反映的是RGB輸入信號(hào)藍(lán)色部分與RGB信號(hào)亮度值之間的差異。
將RGB圖像轉(zhuǎn)換到Y(jié)CrCb顏色空間,提取Cr分量圖像。對(duì)Cr做自二值化閾值分割處理(Otsu法)。
代碼:
def skinMask_YCrCb_otsu(image):
YCrCb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) #轉(zhuǎn)換至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
效果:


4.HSV空間
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
效果:


5.opencv自帶膚色檢測(cè)類(lèi)AdaptiveSkinDetector
已經(jīng)從opencv 3以上版本中移除,opencv 2中函數(shù)。
6.基于橢圓模型
將皮膚信息映射到Y(jié)CrCb空間,則在CrCb二維空間中這些皮膚像素點(diǎn)近似成一個(gè)橢圓分布。因此如果我們得到了一個(gè)CrCb的橢圓,下次來(lái)一個(gè)坐標(biāo)(Cr, Cb)我們只需判斷它是否在橢圓內(nèi)(包括邊界),如果是,則可以判斷其為皮膚,否則就是非皮膚像素點(diǎn)。
代碼:
def skinMask_ellipse(image):
YCrCb = cv2.cvtColor(image, cv2.COLOR_BGR2YCR_CB) #轉(zhuǎn)換至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
效果:
橢圓模型

效果


7.直方圖反向投影
反向投影可以用來(lái)做圖像分割,尋找感興趣區(qū)間。可以尋找任何的roi,這里將其用作尋找人體膚色。它會(huì)輸出與輸入圖像大小相同的圖像,每一個(gè)像素值代表了輸入圖像上對(duì)應(yīng)點(diǎn)屬于目標(biāo)對(duì)象的概率,簡(jiǎn)言之,輸出圖像中像素值越高的點(diǎn)越可能代表想要查找的目標(biāo)。直方圖投影經(jīng)常與camshift(追蹤算法)算法一起使用。
操作步驟:
(1)截取若干張不同膚色的圖片,最好覆蓋常見(jiàn)的所有膚色(如下圖)

(2)對(duì)所有膚色的圖片一起做色彩直方圖(利用OpenCV中的calcHist函數(shù))
(3)新建一個(gè)與待檢測(cè)圖片同尺寸的灰度圖片,找到待檢測(cè)圖片中每顆像素點(diǎn)的顏色在色彩直方圖中對(duì)應(yīng)柵格的數(shù)值(即統(tǒng)計(jì)中出現(xiàn)的次數(shù)),并將該數(shù)值賦值予新建灰度圖片中與該檢測(cè)像素同位置的像素(利用OpenCV中的calcBackProject函數(shù))。圖像中像素亮度越高,待檢測(cè)圖像該位置處是膚色的概率越大。
代碼:
def skinMask_hist_backproject(target, roi_image):
#roi圖片,就想要找的的圖片
hsv = cv2.cvtColor(roi_image,cv2.COLOR_BGR2HSV)
#目標(biāo)搜索圖片
hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)
#計(jì)算目標(biāo)直方圖
roihist = cv2.calcHist([hsv],[0,1],None,[180,256],[0,180,0,256])
#歸一化,參數(shù)為原圖像和輸出圖像,歸一化后值全部在2到255范圍
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)
#卷積連接分散的點(diǎn)
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傳統(tǒng)圖像處理之皮膚區(qū)域檢測(cè)詳解的詳細(xì)內(nèi)容,更多關(guān)于Python 皮膚區(qū)域檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中搜索和替換文件中的文本的實(shí)現(xiàn)(四種)
本文主要介紹了Python中搜索和替換文件中的文本的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
PyQt5實(shí)現(xiàn)從主窗口打開(kāi)子窗口的方法
今天小編就為大家分享一篇PyQt5實(shí)現(xiàn)從主窗口打開(kāi)子窗口的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
python elasticsearch環(huán)境搭建詳解
在本篇文章里小編給大家整理的是關(guān)于python elasticsearch環(huán)境搭建的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以參考下。2019-09-09
1行Python代碼實(shí)現(xiàn)去除圖片水印詳解
這篇文章主要為大家介紹了1行Python代碼實(shí)現(xiàn)去除圖片水印詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Python實(shí)現(xiàn)修改Excel文件的元數(shù)據(jù)
這篇文章將通過(guò)使用Python、Openpyxl模塊以及wxPython庫(kù),實(shí)現(xiàn)創(chuàng)建一個(gè)GUI界面來(lái)輸入元數(shù)據(jù),然后將這些元數(shù)據(jù)與Excel文件一起保存,感興趣的可以了解一下2023-04-04
pyinstaller將python程序打包為可執(zhí)行文件
這篇文章主要介紹了pyinstaller將python程序打包為可執(zhí)行文件,pyinstaller是一個(gè)python打包工具,它將python程序及所需依賴(lài)都打包成一個(gè)可執(zhí)行文件2022-08-08

