官方合作微信:gldz_super
本专栏《AI计算机视觉进阶项目》主要以计算机视觉实战项目为主,第一个项目为口罩检测:该项目将分为几个模块进行展示
要求如下:检测出视频中的人是否带口罩,如果带了进行检测,该项目主要分为正常佩戴、未佩戴口罩以及不规范(漏鼻子)三个类别。训练的数据集有正常佩戴1915张、未佩戴口罩1918张以及不规范(漏鼻子)1919张数据。
- import cv2
- import numpy as np
- import matplotlib.pyplot as plt
- import os, glob
- import tqdm
- # 处理所有图像
- path = 'images/'
- # 剪切人脸,为了图像的计算效率对人的图像进行剪切
- # 加载SSD模型:将人脸剪切出来
- face_detector = cv2.dnn.readNetFromCaffe('./weights/deploy.prototxt.txt',
- 'weights/res10_300x300_ssd_iter_140000.caffemodel')
- 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
- 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)
-
正在处理的进程 :

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

数据处理结束