• 图像人脸检测(框出人脸、笑脸、眼睛)


      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_Libsite-packagescv2data):
     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_Libsite-packagescv2data/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_Libsite-packagescv2data/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_Libsite-packagescv2data/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 # 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    带符号数的移位
    day03-Java语言基础之运算符
    day02Java语言基础数量部分
    day01Java概述
    交换机光口识别与连接问题
    wireshark怎么抓包
    Java中的语句
    构建主键批注的方法
    通过反射,获得数据库增删改查的sql语句的方法
    sql语句
  • 原文地址:https://www.cnblogs.com/zpdbkshangshanluoshuo/p/10423816.html
Copyright © 2020-2023  润新知