AI计算机视觉进阶项目(一)——带口罩识别检测(2)

官方合作微信:gldz_super

本专栏《AI计算机视觉进阶项目》主要以计算机视觉实战项目为主,第一个项目为口罩检测:该项目将分为几个模块进行展示

1.项目概述

        要求如下:检测出视频中的人是否带口罩,如果带了进行检测,该项目主要分为正常佩戴、未佩戴口罩以及不规范(漏鼻子)三个类别。训练的数据集有正常佩戴1915张、未佩戴口罩1918张以及不规范(漏鼻子)1919张数据。

2.本节任务

  1. 对所有的图像首先将人脸裁剪出来,然后进行Blob转换(上节是对单个图像进行处理)
  2. 将数据存储为numpy格式

3.项目实现

3.1导入需要的库

import cv2
import numpy as np
import matplotlib.pyplot as plt
import os, glob
import tqdm

3.2加载路径中的所有类别图像并加载模型

 # 处理所有图像
    path = 'images/'
    # 剪切人脸,为了图像的计算效率对人的图像进行剪切
    # 加载SSD模型:将人脸剪切出来
    face_detector = cv2.dnn.readNetFromCaffe('./weights/deploy.prototxt.txt',
                                             'weights/res10_300x300_ssd_iter_140000.caffemodel')

3.3 将所有图像人脸剪切出来

def face_detect(img):
    # 转为blob:进行均值相减,加快运算
    img_blob = cv2.dnn.blobFromImage(img, 1, (300, 300), (104, 177, 123), swapRB=True)
    # 输入
    face_detector.setInput(img_blob)
    # 推理
    detections = face_detector.forward()
    # print(detections.shape)

    # 遍历结果
    # 获取原图大小
    img_h, img_w = img.shape[:2]

    # 人数
    person_count = detections.shape[2]

    for face_index in range(person_count):
        # 置信度
        confidence = detections[0, 0, face_index, 2]
        # print(confidence) # 发现大部分置信度都是比较小,我们这挑选比较大的置信度
        if confidence >0.5: # 表示检测到人脸
            locations = detections[0, 0, face_index, 3:7]*np.array([img_w, img_h, img_w, img_h]) # 由于之前归一化了,所以拿到位置要乘以宽高返回到原图大小
            # 用矩形框画出人脸:由于画矩形框不能有小数,所以需要取整
            l, t, r, b = locations.astype('int')
            # cv2.rectangle(img, (l, t), (r, b), (0, 255, 0), 5)
            # plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
            # plt.show()
            return img[t:b, l:r]
    return None

3.4将所有剪切后的图像转为Blob图像

# 转为Blob图像
def imgBlob(img):
    img_blob = cv2.dnn.blobFromImage(img, 1, (100, 100), (104, 177, 123), swapRB=True)
    # 转变后图像由三维会变为四维,所以需要进行维度压缩:变为:(1, 3, 300, 300)
    img_squeeze = np.squeeze(img_blob)  # 变为(3, 300, 300)所以需要转置将3放在后面
    img_squeeze = img_squeeze.T # 输出人倒立横着的,所以需要旋转90度
    # 旋转
    img_rotate = cv2.rotate(img_squeeze, cv2.ROTATE_90_CLOCKWISE)
    # 再进行镜像翻转图像就和原图位置一样
    img_flip = cv2.flip(img_rotate, 1)
    # 去除负数:将小于0设置为0,大于0不变
    img_flip = np.maximum(img_flip, 0)
    # 归一化
    img_blob = img_flip / img_flip.max()
    return img_blob

3.5处理所有图像函数

def proAllImage(path):
    # 处理所有的图片
    labels = os.listdir(path)
    # print(labels)
    # 遍历所有类别,并用两个列表保存结果
    # 建立两个列表保存结果
    img_list = []
    label_list = []
    for label in labels:
        # 获取每类文件列表
        file_list = glob.glob('images/%s/*.jpg' % (label))
        # print(file_list)
        for img_file in tqdm.tqdm(file_list, desc="处理中%s" % (label)):  # 加上tqdm好处就是可以看到进度条
            img = cv2.imread(img_file)
            # 裁剪人脸
            img_crop = face_detect(img)
            # 判断空的情况
            if img_crop is not None:
                # 转为blob
                img_blob = imgBlob(img_crop)
                img_list.append(img_blob)
                label_list.append(label)
                # print(label_list)
    # 保存numpy格式文件。转为numpy数组
    x = np.asarray(img_list)
    y = np.asarray(label_list)
    print(x.shape)
    print(y.shape)
    # 存储为numpy文件
    np_data = np.savez('./imageData.npz', x, y)
    return np_data

4.完整代码

import cv2
import numpy as np
import matplotlib.pyplot as plt
import os, glob
import tqdm

def face_detect(img):
    # 转为blob:进行均值相减,加快运算
    img_blob = cv2.dnn.blobFromImage(img, 1, (300, 300), (104, 177, 123), swapRB=True)
    # 输入
    face_detector.setInput(img_blob)
    # 推理
    detections = face_detector.forward()
    # print(detections.shape)

    # 遍历结果
    # 获取原图大小
    img_h, img_w = img.shape[:2]

    # 人数
    person_count = detections.shape[2]

    for face_index in range(person_count):
        # 置信度
        confidence = detections[0, 0, face_index, 2]
        # print(confidence) # 发现大部分置信度都是比较小,我们这挑选比较大的置信度
        if confidence >0.5: # 表示检测到人脸
            locations = detections[0, 0, face_index, 3:7]*np.array([img_w, img_h, img_w, img_h]) # 由于之前归一化了,所以拿到位置要乘以宽高返回到原图大小
            # 用矩形框画出人脸:由于画矩形框不能有小数,所以需要取整
            l, t, r, b = locations.astype('int')
            # cv2.rectangle(img, (l, t), (r, b), (0, 255, 0), 5)
            # plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
            # plt.show()
            return img[t:b, l:r]
    return None

# 转为Blob图像
def imgBlob(img):
    img_blob = cv2.dnn.blobFromImage(img, 1, (100, 100), (104, 177, 123), swapRB=True)
    # 转变后图像由三维会变为四维,所以需要进行维度压缩:变为:(1, 3, 300, 300)
    img_squeeze = np.squeeze(img_blob)  # 变为(3, 300, 300)所以需要转置将3放在后面
    img_squeeze = img_squeeze.T # 输出人倒立横着的,所以需要旋转90度
    # 旋转
    img_rotate = cv2.rotate(img_squeeze, cv2.ROTATE_90_CLOCKWISE)
    # 再进行镜像翻转图像就和原图位置一样
    img_flip = cv2.flip(img_rotate, 1)
    # 去除负数:将小于0设置为0,大于0不变
    img_flip = np.maximum(img_flip, 0)
    # 归一化
    img_blob = img_flip / img_flip.max()
    return img_blob

def proAllImage(path):
    # 处理所有的图片
    labels = os.listdir(path)
    # print(labels)
    # 遍历所有类别,并用两个列表保存结果
    # 建立两个列表保存结果
    img_list = []
    label_list = []
    for label in labels:
        # 获取每类文件列表
        file_list = glob.glob('images/%s/*.jpg' % (label))
        # print(file_list)
        for img_file in tqdm.tqdm(file_list, desc="处理中%s" % (label)):  # 加上tqdm好处就是可以看到进度条
            img = cv2.imread(img_file)
            # 裁剪人脸
            img_crop = face_detect(img)
            # 判断空的情况
            if img_crop is not None:
                # 转为blob
                img_blob = imgBlob(img_crop)
                img_list.append(img_blob)
                label_list.append(label)
                # print(label_list)
    # 保存numpy格式文件。转为numpy数组
    x = np.asarray(img_list)
    y = np.asarray(label_list)
    print(x.shape)
    print(y.shape)
    # 存储为numpy文件
    np_data = np.savez('./imageData.npz', x, y)
    return np_data

if __name__ =="__main__":
    # 处理所有图像
    path = 'images/'
    # 剪切人脸,为了图像的计算效率对人的图像进行剪切
    # 加载SSD模型:将人脸剪切出来
    face_detector = cv2.dnn.readNetFromCaffe('./weights/deploy.prototxt.txt',
                                             'weights/res10_300x300_ssd_iter_140000.caffemodel')
    np_data = proAllImage(path)


    cv2.waitKey(0)

5.结果展示

正在处理的进程 :

生成一个numpy存储格式的数据

 数据处理结束

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI炮灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值