Python人體膚色檢測

代碼地址以下:
http://www.demodashi.com/demo/12967.htmlhtml

Python人體膚色檢測

概述

本文中的人體膚色檢測功能採用 OpenCV 庫實現, OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,能夠運行在Linux、Windows、Android和Mac OS操做系統上. 它輕量級並且高效——由一系列 C 函數和少許 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的不少通用算法.python

本文主要使用了OpenCV的圖像色域轉換, 顏色通道分割, 高斯濾波, OSTU自動閾值等功能.web

參考資料

OpenCV探索之路:皮膚檢測技術算法

學習OpenCV—膚色檢測bash

準備工做

安裝 Python-OpenCV

pip install opencv-python -i https://mirrors.ustc.edu.cn/pypi/web/simple

利用 -i 爲pip指令鏡像源, 這裏使用電子科技大學的源, 速度比官方源更快.函數

安裝 Numpy 科學計算庫

pip install numpy -i https://mirrors.ustc.edu.cn/pypi/web/simple

圖像的基本操做

import numpy as np
import cv2

imname =  "6358772.jpg"

# 讀入圖像
'''
使用函數 cv2.imread() 讀入圖像。這幅圖像應該在此程序的工做路徑,或者給函數提供完整路徑.
警告:就算圖像的路徑是錯的,OpenCV 也不會提醒你的,可是當你使用命令print(img)時獲得的結果是None。
'''
img = cv2.imread(imname, cv2.IMREAD_COLOR)
'''
imread函數的第一個參數是要打開的圖像的名稱(帶路徑)
第二個參數是告訴函數應該如何讀取這幅圖片. 其中
    cv2.IMREAD_COLOR 表示讀入一副彩色圖像, alpha 通道被忽略, 默認值
    cv2.IMREAD_ANYCOLOR 表示讀入一副彩色圖像
    cv2.IMREAD_GRAYSCALE 表示讀入一副灰度圖像
    cv2.IMREAD_UNCHANGED 表示讀入一幅圖像,而且包括圖像的 alpha 通道
'''

# 顯示圖像
'''
使用函數 cv2.imshow() 顯示圖像。窗口會自動調整爲圖像大小。第一個參數是窗口的名字,
其次纔是咱們的圖像。你能夠建立多個窗口,只要你喜歡,可是必須給他們不一樣的名字.
'''
cv2.imshow("image", img) # "image" 參數爲圖像顯示窗口的標題, img是待顯示的圖像數據
cv2.waitKey(0) #等待鍵盤輸入,參數表示等待時間,單位毫秒.0表示無限期等待
cv2.destroyAllWindows() # 銷燬全部cv建立的窗口
# 也能夠銷燬指定窗口:
#cv2.destroyWindow("image") # 刪除窗口標題爲"image"的窗口

# 保存圖像
'''
使用函數 cv2.imwrite() 來保存一個圖像。首先須要一個文件名,以後纔是你要保存的圖像。
保存的圖片的格式由後綴名決定.
'''
#cv2.imwrite(imname + "01.png", img) 
cv2.imwrite(imname + "01.jpg", img)

運行截圖

運行截圖

皮膚檢測算法

基於YCrCb顏色空間的Cr份量+Otsu法閾值分割算法

YCrCbYUV ,其中 Y 表示明亮度 LuminanceLuma , 也就是灰階值. 而 UV 表示的則是色度 ChrominanceChroma ,做用是描述影像色彩及飽和度, 用於指定像素的顏色. 亮度 是透過RGB輸入信號來創建的, 方法是將RGB信號的特定部分疊加到一塊兒. 色度 則定義了顏色的兩個方面─色調與飽和度,分別用 CrCb 來表示. 其中, Cr 反映了RGB輸入信號紅色部分與RGB信號亮度值之間的差別. 而 Cb 反映的是RGB輸入信號藍色部分與RGB信號亮度值之間的差別.學習

該方法的原理也很簡單:ui

  • 將RGB圖像轉換到 YCrCb 顏色空間,提取 Cr 份量圖像
  • Cr 份量進行高斯濾波
  • 對Cr作自二值化閾值分割處理 OSTU

關於高斯濾波
使用低通濾波器能夠達到圖像模糊的目的。這對與去除噪音頗有幫助。其實就是去除圖像中的高頻成分(好比:噪音,邊界)。因此邊界也會被模糊一點。(固然,也有一些模糊技術不會模糊掉邊界)。OpenCV 提供了四種模糊技術。高斯濾波就是其中一種。實現的函數是 cv2.GaussianBlur()。咱們須要指定高斯濾波器的寬和高(必須是奇數)。以及高斯函數沿 X,Y 方向的標準差。若是咱們只指定了 X 方向的的標準差,Y 方向也會取相同值。若是兩個標準差都是 0,那麼函數會根據核函數的大小本身計算。高斯濾波能夠有效的從圖像中去除高斯噪音。若是你願意的話,你也可使用函數 cv2.getGaussianKernel() 本身構建一個高斯濾波器。操作系統

# 膚色檢測之一: YCrCb之Cr份量 + OTSU二值化
img = cv2.imread(imname, cv2.IMREAD_COLOR)
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb) # 把圖像轉換到YUV色域
(y, cr, cb) = cv2.split(ycrcb) # 圖像分割, 分別獲取y, cr, br通道圖像


# 高斯濾波, cr 是待濾波的源圖像數據, (5,5)是值窗口大小, 0 是指根據窗口大小來計算高斯函數標準差
cr1 = cv2.GaussianBlur(cr, (5, 5), 0) # 對cr通道份量進行高斯濾波
# 根據OTSU算法求圖像閾值, 對圖像進行二值化
_, skin1 = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) 

cv2.imshow("image CR", cr1)
cv2.imshow("Skin Cr+OSTU", skin1 )

檢測效果

運行截圖

基於YCrCb顏色空間Cr, Cb範圍篩選法

這個方法跟法一其實大同小異,只是顏色空間不一樣而已。據資料顯示,正常黃種人的Cr份量大約在140至175之間,Cb份量大約在100至120之間。你們能夠根據本身項目需求放大或縮小這兩個份量的範圍,會有不一樣的效果。.net

# 膚色檢測之二: YCrCb中 140<=Cr<=175 100<=Cb<=120
img = cv2.imread(imname, cv2.IMREAD_COLOR)
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb) # 把圖像轉換到YUV色域
(y, cr, cb) = cv2.split(ycrcb) # 圖像分割, 分別獲取y, cr, br通道份量圖像

skin2 = np.zeros(cr.shape, dtype=np.uint8) # 根據源圖像的大小建立一個全0的矩陣,用於保存圖像數據
(x, y) = cr.shape # 獲取源圖像數據的長和寬

# 遍歷圖像, 判斷Cr和Br通道的數值, 若是在指定範圍中, 則置把新圖像的點設爲255,不然設爲0
for i in  range(0, x): 
    for j in  range(0, y):
        if (cr[i][j] >  140) and (cr[i][j] <  175) and (cb[i][j] >  100) and (cb[i][j] <  120):
            skin2[i][j] =  255
        else:
            skin2[i][j] =  0

cv2.imshow(imname, img)
cv2.imshow(imname +  " Skin2 Cr+Cb", skin2)

檢測效果

運行截圖

基於HSV顏色空間H,S,V範圍篩選法

這個方法跟上一方法相似,只是顏色空間不一樣而已。據資料顯示,正常黃種人的H份量大約在7至20之間,S份量大約在28至256之間,V份量大約在50至256之間。你們能夠根據本身項目需求放大或縮小這兩個份量的範圍,會有不一樣的效果。

# 膚色檢測之三: HSV中 7<H<20 28<S<256 50<V<256
img = cv2.imread(imname, cv2.IMREAD_COLOR) 
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 把圖像轉換到HSV色域
(_h, _s, _v) = cv2.split(hsv) # 圖像分割, 分別獲取h, s, v 通道份量圖像
skin3 = np.zeros(_h.shape, dtype=np.uint8)  # 根據源圖像的大小建立一個全0的矩陣,用於保存圖像數據
(x, y) = _h.shape # 獲取源圖像數據的長和寬

# 遍歷圖像, 判斷HSV通道的數值, 若是在指定範圍中, 則置把新圖像的點設爲255,不然設爲0
for i in  range(0, x):
    for j in  range(0, y):
        if (_h[i][j] >  7) and (_h[i][j] <  20) and (_s[i][j] >  28) and (_s[i][j] <  255) and (_v[i][j] >  50) and (_v[i][j] <  255):
            skin3[i][j] =  255
        else:
            skin3[i][j] =  0

cv2.imshow(imname, img)
cv2.imshow(imname +  " Skin3 HSV", skin3)

檢測效果

運行截圖

三種檢測算法效果對比

運行截圖

項目內文件截圖

項目內文件截圖

Python人體膚色檢測

代碼地址以下:
http://www.demodashi.com/demo/12967.html

注:本文著做權歸做者,由demo大師代發,拒絕轉載,轉載須要做者受權

相關文章
相關標籤/搜索