圖像人臉檢測(框出人臉、笑臉、眼睛)


  1 # 通過圖片識別人臉
  2 
  3 #1.概述: 人臉識別,是基於人的臉部特征信息進行身份識別的一種生物識別技術。用攝像機或攝像頭采集含有人臉的圖像或視頻流,並自動在圖像中檢測和跟蹤人臉,進而對檢測到的人臉進行臉部的一系列相關技術,通常也叫做人像識別、面部識別。
  4 
  5 # 2、人臉識別步驟
  6 # 1    人臉圖像采集及檢測
  7 # 2    人臉圖像預處理
  8 # 3    人臉圖像特征提取以及匹配與識別
  9 
 10 # 3、 人臉識別的方法
 11 # 在OpenCV中主要使用了兩種特征(即兩種方法)進行人臉檢測,Haar特征和LBP特征。使用已經訓練好的XML格式的分類器進行人臉檢測。在OpenCV的安裝目錄下的data文件夾里可以看到下圖所示的內容(D:\PROFESSION_\PYTHON_\Lib\site-packages\cv2\data):
 12 
 13 import os
 14 import cv2
 15 from PIL import Image, ImageDraw
 16 from datetime import datetime
 17 import time
 18 
 19 
 20 # detectFaces()返回圖像中所有人臉的矩形坐標(矩形左上、右下頂點)
 21 # 使用haar特征的級聯分類器haarcascade_frontalface_default.xml,在haarcascades目錄下還有其他的訓練好的xml文件可供選擇。
 22 # 注:haarcascades目錄下訓練好的分類器必須以灰度圖作為輸入。
 23 def detectFaces(image_name):
 24     img = cv2.imread(image_name)
 25     face_cascade = cv2.CascadeClassifier("D:\PROFESSION_\PYTHON_\Lib\site-packages\cv2\data/haarcascade_frontalface_default.xml")
 26     if img.ndim == 3:
 27         gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 28         print('轉換灰度圖成功','gray.ndim',gray.ndim)
 29     else:
 30         gray = img  # if語句:如果img維度為3,說明不是灰度圖,先轉化為灰度圖gray,如果不為3,也就是2,原圖就是灰度圖
 31         print('我本來就是灰度圖')
 32     faces = face_cascade.detectMultiScale(gray, 1.3, 5)  # 1.3和5是特征的最小、最大檢測窗口,它改變檢測結果也會改變
 33     result = []
 34     for (x, y, width, height) in faces:
 35         result.append((x, y, x + width, y + height))
 36     # print(result)   [(148, 33, 210, 95), (51, 46, 110, 105), (306, 49, 369, 112)]
 37     return result
 38 
 39 
 40 # 保存人臉圖
 41 def saveFaces(image_name):
 42     faces = detectFaces(image_name)
 43     print('faces',faces)
 44     if faces:
 45         # 將人臉保存在save_dir目錄下。
 46         # Image模塊:Image.open獲取圖像句柄,crop剪切圖像(剪切的區域就是detectFaces返回的坐標),save保存。
 47         save_dir = image_name.split('.')[0] + "_faces"
 48         print('save_dir',save_dir)
 49         os.mkdir(save_dir)
 50         count = 0
 51         for (x1, y1, x2, y2) in faces:
 52             file_name = os.path.join(save_dir, str(count) + ".jpg")
 53             Image.open(image_name).crop((x1, y1, x2, y2)).save(file_name)
 54             count += 1
 55 
 56 
 57 # 在原圖像上畫矩形,框出所有人臉。
 58 # 調用Image模塊的draw方法,Image.open獲取圖像句柄,ImageDraw.Draw獲取該圖像的draw實例,然后調用該draw實例的rectangle方法畫矩形(矩形的坐標即 detectFaces返回的坐標),outline是矩形線條顏色(B,G,R)。
 59 # 注:原始圖像如果是灰度圖,則去掉outline,因為灰度圖沒有RGB可言。drawEyes、detectSmiles也一樣。
 60 
 61 def drawFaces(image_name):
 62     faces = detectFaces(image_name)
 63     if faces:
 64         img = Image.open(image_name)
 65         draw_instance = ImageDraw.Draw(img)
 66         for (x1, y1, x2, y2) in faces:
 67             draw_instance.rectangle((x1, y1, x2, y2), outline=(255, 0, 0))
 68         img.save('drawfaces_' + image_name)
 69 
 70 
 71 # 檢測眼睛,返回坐標
 72 # 由於眼睛在人臉上,我們往往是先檢測出人臉,再細入地檢測眼睛。故detectEyes可在detectFaces基礎上來進行,代碼中需要注意“相對坐標”。# 當然也可以在整張圖片上直接使用分類器,這種方法代碼跟detectFaces一樣,這里不多說。
 73 def detectEyes(image_name):
 74     eye_cascade = cv2.CascadeClassifier('D:\PROFESSION_\PYTHON_\Lib\site-packages\cv2\data/haarcascade_eye.xml')
 75     faces = detectFaces(image_name)
 76 
 77     img = cv2.imread(image_name)
 78     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 79     result = []
 80     for (x1, y1, x2, y2) in faces:
 81         roi_gray = gray[y1:y2, x1:x2]
 82         eyes = eye_cascade.detectMultiScale(roi_gray, 1.3, 2)
 83         for (ex, ey, ew, eh) in eyes:
 84             result.append((x1 + ex, y1 + ey, x1 + ex + ew, y1 + ey + eh))
 85     return result
 86 
 87 
 88 # 在原圖像上框出眼睛.
 89 def drawEyes(image_name):
 90     eyes = detectEyes(image_name)
 91     if eyes:
 92         img = Image.open(image_name)
 93         draw_instance = ImageDraw.Draw(img)
 94         for (x1, y1, x2, y2) in eyes:
 95             draw_instance.rectangle((x1, y1, x2, y2), outline=(0, 0, 255))
 96         img.save('draweyes_' + image_name)
 97 
 98 
 99 # 檢測笑臉
100 def detectSmiles(image_name):
101     img = cv2.imread(image_name)
102     smiles_cascade = cv2.CascadeClassifier("D:\PROFESSION_\PYTHON_\Lib\site-packages\cv2\data/haarcascade_smile.xml")
103     if img.ndim == 3:
104         gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
105     else:
106         gray = img  # if語句:如果img維度為3,說明不是灰度圖,先轉化為灰度圖gray,如果不為3,也就是2,原圖就是灰度圖
107 
108     smiles = smiles_cascade.detectMultiScale(gray, 4, 5)
109     result = []
110     for (x, y, width, height) in smiles:
111         result.append((x, y, x + width, y + height))
112     return result
113 
114 
115 # 在原圖像上框出笑臉
116 def drawSmiles(image_name):
117     smiles = detectSmiles(image_name)
118     if smiles:
119         img = Image.open(image_name)
120         draw_instance = ImageDraw.Draw(img)
121         for (x1, y1, x2, y2) in smiles:
122             draw_instance.rectangle((x1, y1, x2, y2), outline=(100, 100, 0))
123         img.save('drawsmiles_' + image_name)
124 
125 
126 
127 
128 
129 
130 
131 if __name__ == '__main__':
132     time1 = datetime.now()
133     result = detectFaces('d.jpg')
134     time2 = datetime.now()
135     print("耗時:" + str(time2 - time1))
136     if len(result) > 0:
137         print("有人存在!!---》人數為:" + str(len(result)))
138     else:
139         print('視頻圖像中無人!!')
140 
141     # drawFaces('d.jpg')#框出臉
142     # drawSmiles('d.jpg')#框出笑臉
143     # drawEyes('d.jpg') #框出眼睛
144 
145 
146 """
147 上面的代碼將眼睛、人臉、笑臉在不同的圖像上框出,如果需要在同一張圖像上框出,改一下代碼就可以了。
148 總之,利用opencv里訓練好的haar特征的xml文件,在圖片上檢測出人臉的坐標,利用這個坐標,我們可以將人臉區域剪切保存,也可以在原圖上將人臉框出。剪切保存人臉以及用矩形工具框出人臉,本程序使用的是PIL里的Image、ImageDraw模塊。
149 此外,opencv里面也有畫矩形的模塊,同樣可以用來框出人臉。
150 """
151 # ---------------------
152 # 作者:wsywb111
153 # 來源:CSDN
154 # 原文:https://blog.csdn.net/wsywb111/article/details/79152425
155 # 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM