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


    官方合作微信:gldz_super

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

    1.项目概述

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

    2.本节任务

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

    3.项目实现

    3.1导入需要的库

    1. import cv2
    2. import numpy as np
    3. import matplotlib.pyplot as plt
    4. import os, glob
    5. import tqdm

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

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

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

    1. def face_detect(img):
    2. # 转为blob:进行均值相减,加快运算
    3. img_blob = cv2.dnn.blobFromImage(img, 1, (300, 300), (104, 177, 123), swapRB=True)
    4. # 输入
    5. face_detector.setInput(img_blob)
    6. # 推理
    7. detections = face_detector.forward()
    8. # print(detections.shape)
    9. # 遍历结果
    10. # 获取原图大小
    11. img_h, img_w = img.shape[:2]
    12. # 人数
    13. person_count = detections.shape[2]
    14. for face_index in range(person_count):
    15. # 置信度
    16. confidence = detections[0, 0, face_index, 2]
    17. # print(confidence) # 发现大部分置信度都是比较小,我们这挑选比较大的置信度
    18. if confidence >0.5: # 表示检测到人脸
    19. locations = detections[0, 0, face_index, 3:7]*np.array([img_w, img_h, img_w, img_h]) # 由于之前归一化了,所以拿到位置要乘以宽高返回到原图大小
    20. # 用矩形框画出人脸:由于画矩形框不能有小数,所以需要取整
    21. l, t, r, b = locations.astype('int')
    22. # cv2.rectangle(img, (l, t), (r, b), (0, 255, 0), 5)
    23. # plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
    24. # plt.show()
    25. return img[t:b, l:r]
    26. return None

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

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

    3.5处理所有图像函数

    1. def proAllImage(path):
    2. # 处理所有的图片
    3. labels = os.listdir(path)
    4. # print(labels)
    5. # 遍历所有类别,并用两个列表保存结果
    6. # 建立两个列表保存结果
    7. img_list = []
    8. label_list = []
    9. for label in labels:
    10. # 获取每类文件列表
    11. file_list = glob.glob('images/%s/*.jpg' % (label))
    12. # print(file_list)
    13. for img_file in tqdm.tqdm(file_list, desc="处理中%s" % (label)): # 加上tqdm好处就是可以看到进度条
    14. img = cv2.imread(img_file)
    15. # 裁剪人脸
    16. img_crop = face_detect(img)
    17. # 判断空的情况
    18. if img_crop is not None:
    19. # 转为blob
    20. img_blob = imgBlob(img_crop)
    21. img_list.append(img_blob)
    22. label_list.append(label)
    23. # print(label_list)
    24. # 保存numpy格式文件。转为numpy数组
    25. x = np.asarray(img_list)
    26. y = np.asarray(label_list)
    27. print(x.shape)
    28. print(y.shape)
    29. # 存储为numpy文件
    30. np_data = np.savez('./imageData.npz', x, y)
    31. return np_data

    4.完整代码

    1. import cv2
    2. import numpy as np
    3. import matplotlib.pyplot as plt
    4. import os, glob
    5. import tqdm
    6. def face_detect(img):
    7. # 转为blob:进行均值相减,加快运算
    8. img_blob = cv2.dnn.blobFromImage(img, 1, (300, 300), (104, 177, 123), swapRB=True)
    9. # 输入
    10. face_detector.setInput(img_blob)
    11. # 推理
    12. detections = face_detector.forward()
    13. # print(detections.shape)
    14. # 遍历结果
    15. # 获取原图大小
    16. img_h, img_w = img.shape[:2]
    17. # 人数
    18. person_count = detections.shape[2]
    19. for face_index in range(person_count):
    20. # 置信度
    21. confidence = detections[0, 0, face_index, 2]
    22. # print(confidence) # 发现大部分置信度都是比较小,我们这挑选比较大的置信度
    23. if confidence >0.5: # 表示检测到人脸
    24. locations = detections[0, 0, face_index, 3:7]*np.array([img_w, img_h, img_w, img_h]) # 由于之前归一化了,所以拿到位置要乘以宽高返回到原图大小
    25. # 用矩形框画出人脸:由于画矩形框不能有小数,所以需要取整
    26. l, t, r, b = locations.astype('int')
    27. # cv2.rectangle(img, (l, t), (r, b), (0, 255, 0), 5)
    28. # plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
    29. # plt.show()
    30. return img[t:b, l:r]
    31. return None
    32. # 转为Blob图像
    33. def imgBlob(img):
    34. img_blob = cv2.dnn.blobFromImage(img, 1, (100, 100), (104, 177, 123), swapRB=True)
    35. # 转变后图像由三维会变为四维,所以需要进行维度压缩:变为:(1, 3, 300, 300)
    36. img_squeeze = np.squeeze(img_blob) # 变为(3, 300, 300)所以需要转置将3放在后面
    37. img_squeeze = img_squeeze.T # 输出人倒立横着的,所以需要旋转90
    38. # 旋转
    39. img_rotate = cv2.rotate(img_squeeze, cv2.ROTATE_90_CLOCKWISE)
    40. # 再进行镜像翻转图像就和原图位置一样
    41. img_flip = cv2.flip(img_rotate, 1)
    42. # 去除负数:将小于0设置为0,大于0不变
    43. img_flip = np.maximum(img_flip, 0)
    44. # 归一化
    45. img_blob = img_flip / img_flip.max()
    46. return img_blob
    47. def proAllImage(path):
    48. # 处理所有的图片
    49. labels = os.listdir(path)
    50. # print(labels)
    51. # 遍历所有类别,并用两个列表保存结果
    52. # 建立两个列表保存结果
    53. img_list = []
    54. label_list = []
    55. for label in labels:
    56. # 获取每类文件列表
    57. file_list = glob.glob('images/%s/*.jpg' % (label))
    58. # print(file_list)
    59. for img_file in tqdm.tqdm(file_list, desc="处理中%s" % (label)): # 加上tqdm好处就是可以看到进度条
    60. img = cv2.imread(img_file)
    61. # 裁剪人脸
    62. img_crop = face_detect(img)
    63. # 判断空的情况
    64. if img_crop is not None:
    65. # 转为blob
    66. img_blob = imgBlob(img_crop)
    67. img_list.append(img_blob)
    68. label_list.append(label)
    69. # print(label_list)
    70. # 保存numpy格式文件。转为numpy数组
    71. x = np.asarray(img_list)
    72. y = np.asarray(label_list)
    73. print(x.shape)
    74. print(y.shape)
    75. # 存储为numpy文件
    76. np_data = np.savez('./imageData.npz', x, y)
    77. return np_data
    78. if __name__ =="__main__":
    79. # 处理所有图像
    80. path = 'images/'
    81. # 剪切人脸,为了图像的计算效率对人的图像进行剪切
    82. # 加载SSD模型:将人脸剪切出来
    83. face_detector = cv2.dnn.readNetFromCaffe('./weights/deploy.prototxt.txt',
    84. 'weights/res10_300x300_ssd_iter_140000.caffemodel')
    85. np_data = proAllImage(path)
    86. cv2.waitKey(0)

    5.结果展示

    正在处理的进程 :

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

     数据处理结束

  • 相关阅读:
    springboot中自定义拦截器用Component注解不用Configuration注解的坏处是什么
    如何在@GenericGenerator中显式指定schema
    羽毛球馆的绿色之选——气膜体育馆
    LeetCode:1929.数组串联
    LQ0141 纸张尺寸【水题】
    Async/Await 来简化Promise(以Element-ui 询问框为例)
    成都某公司笔试题sql
    闲话Python编程-循环
    [ 云计算 | AWS ] IAM 详解以及如何在 AWS 中直接创建 IAM 账号
    5、ByteBuffer(基础使用)
  • 原文地址:https://blog.csdn.net/bigData1994pb/article/details/126412416