您对华为云开发者网站的整体评价?

非常不满意 非常满意

0

1

2

3

4

5

6

7

8

9

10

*您遇到了哪些问题?(最多选三项)
*您感到满意的原因是?(最多选三项)
*请针对您所遇到的问题给出具体的反馈
200/200

Notebook
ssdlite_dlib自动标注
用于生成人脸关键点检测数据集
HouYanSong
11个月以前
11MB 174 9
  • 许可证类型 ? Unknown
  • 标签
    视频目标检测关键点检测CPU推理
  • 资产ID db1cdbdb-8eef-41da-b988-33594388f5c3

描述

OpenCV抽帧自动标注

import cv2
import dlib
import glob
import time
import numpy as np
import onnxruntime
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
%matplotlib inline
video_path = glob.glob('videos/*.mp4')
video_path[:5]
['videos\\day_man_001_00_1.mp4',
 'videos\\day_man_001_00_2.mp4',
 'videos\\day_man_001_10_1.mp4',
 'videos\\day_man_001_10_2.mp4',
 'videos\\day_man_001_11_1.mp4']
video_names = [name.split('\\')[-1].split('.')[0] for name in video_path]
video_names[:5], len(video_names)
(['day_man_001_00_1',
  'day_man_001_00_2',
  'day_man_001_10_1',
  'day_man_001_10_2',
  'day_man_001_11_1'],
 142)
image_path = 'day_man_001_40_4_12.png'
image = cv2.imread(image_path)
image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
plt.imshow(image)
<matplotlib.image.AxesImage at 0x1e27c372148>
# 人脸检测模型
hog_face_detector = dlib.get_frontal_face_detector()
# 关键点 检测模型
shape_detector = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')
# 检测人脸
detections = hog_face_detector(image,1)
print(detections)
rectangles[[(1311, 491) (1632, 812)]]
head_bboxes = []
for face in detections:
    # 人脸框坐标
    l,t,r,b = face.left(),face.top(),face.right(),face.bottom()
    bbox = [l, t, r, b]
    head_bboxes.append(bbox)
head_bboxes
[[1311, 491, 1632, 812]]
def get_max_roi(bboxes, img_data, scale=1):
        """找出roi最大的手部检测框"""
        max_bbox = max(bboxes, key = lambda x: (x[2] - x[0]) * (x[3] - x[1]))

        # 原始检测框数据归一化到[0,1],此处需还原到原图中的坐标
        img_h, img_w, _ = img_data.shape
        x1, y1, x2, y2 = max_bbox
        # x1 = int(x1 * img_w)
        # y1 = int(y1 * img_h)
        # x2 = int(x2 * img_w)
        # y2 = int(y2 * img_h)
        
        # 检测框进行一定的外扩
        w_ = max(abs(x2 - x1), abs(y2 - y1))
        w_ = w_ * scale
        x_mid = (x1 + x2) / 2
        y_mid = (y1 + y2) / 2
        new_x1 = max(0, int(x_mid - w_ / 2))
        new_y1 = max(0, int(y_mid - w_ / 2))
        new_x2 = min(int(x_mid + w_ / 2), img_w)
        new_y2 = min(int(y_mid + w_ / 2), img_h)
        new_bbox = [new_x1, new_y1, new_x2, new_y2]
        return new_bbox
def get_max_roi_ssd(bboxes, img_data, scale=1):
        """找出roi最大的手部检测框"""
        max_bbox = max(bboxes, key = lambda x: (x[2] - x[0]) * (x[3] - x[1]))

        # 原始检测框数据归一化到[0,1],此处需还原到原图中的坐标
        img_h, img_w, _ = img_data.shape
        x1, y1, x2, y2 = max_bbox
        x1 = int(x1 * img_w)
        y1 = int(y1 * img_h)
        x2 = int(x2 * img_w)
        y2 = int(y2 * img_h)
        
        # 检测框进行一定的外扩
        w_ = max(abs(x2 - x1), abs(y2 - y1))
        w_ = w_ * scale
        x_mid = (x1 + x2) / 2
        y_mid = (y1 + y2) / 2
        new_x1 = max(0, int(x_mid - w_ / 2))
        new_y1 = max(0, int(y_mid - w_ / 2))
        new_x2 = min(int(x_mid + w_ / 2), img_w)
        new_y2 = min(int(y_mid + w_ / 2), img_h)
        new_bbox = [new_x1, new_y1, new_x2, new_y2]
        return new_bbox
if head_bboxes:
    max_roi = get_max_roi(head_bboxes, image)
max_roi
[1311, 491, 1632, 812]
xmin, ymin, xmax, ymax = max_roi[0], max_roi[1], max_roi[2], max_roi[3]
# 创建rectangle对象,四个参数分别为左上角点位置,与右下角点的位置
rectangle = dlib.rectangle(xmin, ymin, xmax, ymax)
# 创建一个rectangles空对象
faces = dlib.rectangles()
faces.append(rectangle)
face = faces[0]
print(face)
[(1311, 491) (1632, 812)]
eyes = np.arange(36, 48)
mous = np.arange(60, 68)
keys = np.append(eyes, mous)
# 获取68个关键点
points = shape_detector(image,face)
# 绘制关键点
for key in keys:
    point = points.parts()[key]
    cv2.circle(image,(point.x,point.y),3,(0,255,0),-1)
    
# 绘制矩形框
cv2.rectangle(image,(l,t),(r,b),(0,255,0),2)

plt.imshow(image)
<matplotlib.image.AxesImage at 0x1e27c0666c8>
def cover_ratio(box1, box2):
    '''计算两个矩形框的IOU与box2区域的比值'''
    def _overlap(x1, x2, x3, x4):
        left = max(x1, x3)
        right = min(x2, x4)
        return right - left

    w = _overlap(box1[0], box1[2], box2[0], box2[2])
    h = _overlap(box1[1], box1[3], box2[1], box2[3])
    if w <= 0 or h <= 0:
        return 0
    inter_area = w * h
    small_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
    return inter_area * 1.0 / small_area
video_name = video_names[0]
"""
OpenCV 读取摄像头视频视频流,使用原生的onnxruntime推理
"""
for video_name in video_names[:]:
    # cap = cv2.VideoCapture(0)
    cap = cv2.VideoCapture('videos/' + video_name + '.mp4')

    if not cap.isOpened():
        print('文件不存在或编码错误')

    else:
        e = 0
        fps = 30
        font = cv2.FONT_HERSHEY_PLAIN
        index_to_clss = {1: 'head', 2: 'phone'}
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        hog_face_detector = dlib.get_frontal_face_detector()
        onnx_model = onnxruntime.InferenceSession('ssdlite_mbv2.onnx')
        shape_detector = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')
        writer = cv2.VideoWriter('dataset/mp4/' +video_name + '_result.mp4',cv2.VideoWriter_fourcc(*'X264'),fps,(width,height))


    while cap.isOpened():

        ret,frame = cap.read()

        if ret:
            e += 1
            if e%2==0:
                continue
            image = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
            detections = hog_face_detector(image,1)
            head_bboxes = []
            for face in detections:
                # 人脸框坐标
                l,t,r,b = face.left(),face.top(),face.right(),face.bottom()
                bbox = [l, t, r, b]
                head_bboxes.append(bbox)
            if head_bboxes:
                face_points = []
                max_roi = get_max_roi(head_bboxes, image)
                l, t, r, b = max_roi[0], max_roi[1], max_roi[2], max_roi[3]
                # 创建rectangle对象,四个参数分别为左上角点位置,与右下角点的位置
                rectangle = dlib.rectangle(l, t, r, b)
                # 创建一个rectangles空对象
                faces = dlib.rectangles()
                faces.append(rectangle)
                face = faces[0]
                # 获取68个关键点
                points = shape_detector(image,face)
                # 绘制关键点
                for key in keys:
                    point = points.parts()[key]
                    face_points.append(point.x)
                    face_points.append(point.y)
                    cv2.circle(frame,(point.x,point.y),3,(0,255,0),-1)
                # 绘制矩形框
                face_points.append(l)
                face_points.append(t)
                face_points.append(r)
                face_points.append(b)
                cv2.rectangle(frame,(l,t),(r,b),(0,255,0),2)

            head_bboxes_ssd = []
            img = cv2.resize(frame, (300, 300))
            img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
            img = img.astype(np.uint8)
            data = np.expand_dims(img, axis=0)
            onnx_input ={onnx_model.get_inputs()[0].name: data}
            detection_boxes, detection_classes, detection_multiclass_scores, detection_scores, num_detections, raw_detection_boxes, raw_detection_scores = onnx_model.run(None, onnx_input)

            for i in range(100):
                if detection_scores[0][i]>0.5:
                    ymin, xmin, ymax, xmax = detection_boxes[0][i][0], detection_boxes[0][i][1], detection_boxes[0][i][2], detection_boxes[0][i][3]
                    if detection_classes[0][i]==1:
                        bbox_ssd = [xmin, ymin, xmax, ymax]
                        head_bboxes_ssd.append(bbox_ssd) 
                    else:
                        y1, x1, y2, x2 = int(detection_boxes[0][i][0]*height), int(detection_boxes[0][i][1]*width), int(detection_boxes[0][i][2]*height), int(detection_boxes[0][i][3]*width)
                        cv2.rectangle(img=frame,pt1=(x1,y1),pt2=(x2,y2),color=(0,0,255),thickness=10)

            if head_bboxes_ssd and not head_bboxes:
                max_roi_ssd = get_max_roi_ssd(head_bboxes_ssd, frame)
                xmin, ymin, xmax, ymax = max_roi_ssd[0], max_roi_ssd[1], max_roi_ssd[2], max_roi_ssd[3]
                cv2.rectangle(img=frame,pt1=(xmin,ymin),pt2=(xmax,ymax),color=(0,255,0),thickness=10)
                print(video_name + "_others_" + str(e+1) + '.jpg')
                cv2.putText(img=frame,text="bad",org=(xmin,ymin),fontFace=font,fontScale=5,color=(0, 0, 255),thickness=5,lineType=cv2.LINE_AA)

            if head_bboxes_ssd and head_bboxes:
                image_face_points = []
                max_roi_ssd = get_max_roi_ssd(head_bboxes_ssd, frame)
                xmin, ymin, xmax, ymax = max_roi_ssd[0], max_roi_ssd[1], max_roi_ssd[2], max_roi_ssd[3]
                cv2.rectangle(img=frame,pt1=(xmin,ymin),pt2=(xmax,ymax),color=(0,255,0),thickness=10)
                iou = cover_ratio(max_roi_ssd, max_roi)
                if iou>0.9:
                    image_crop = image[ymin:ymax,xmin:xmax]
                    face_points = np.array(face_points).reshape(-1, 2)
                    for x, y in face_points:
                        image_face_points.append(x-xmin)
                        image_face_points.append(y-ymin)
                        cv2.circle(frame,(x,y),5,(255,0,0),-1)
                    # 保存原始图片   
                    img_name = 'dataset/img/' + video_name + "_normal_" + str(e+1) + '.jpg'
                    image_crop = cv2.cvtColor(image_crop,cv2.COLOR_BGR2RGB)
                    cv2.imwrite(img_name, image_crop)
                    # 保存渲染图
                    pic_name = 'dataset/pic/' + video_name + "_normal_" + str(e+1) + '.jpg'
                    cv2.rectangle(img=image_crop,pt1=(image_face_points[-4],image_face_points[-3]),pt2=(image_face_points[-2],image_face_points[-1]),color=(0,255,0),thickness=10)
                    for x, y in np.array(image_face_points).reshape(-1, 2):
                        cv2.circle(image_crop,(x,y),5,(255,0,255),-1)
                    cv2.imwrite(pic_name, image_crop)
                    # 保存关键点
                    txt_name = 'dataset/txt/' + video_name + "_normal_" + str(e+1) + '.txt'
                    with open(txt_name,'w') as f:
                        for p in image_face_points:
                            f.write('%s\n' % p)
                    
                    print(video_name + "_normal_" + str(e+1) + '.jpg')
                    cv2.putText(img=frame,text="well iou:" + str(np.round(iou, 2)),org=(xmin,ymin),fontFace=font,fontScale=5,color=(0, 255, 0),thickness=5,lineType=cv2.LINE_AA)
                    cv2.putText(img=frame,text=video_name + "_normal_" + str(e+1) + '.jpg',org=(50,200),fontFace=font,fontScale=5,color=(0, 255, 0),thickness=5,lineType=cv2.LINE_AA)
                else:
                    print(video_name + "_others_" + str(e+1) + '.jpg')
                    cv2.putText(img=frame,text="bad iou:" + str(np.round(iou, 2)),org=(xmin,ymin),fontFace=font,fontScale=5,color=(255, 0, 0),thickness=5,lineType=cv2.LINE_AA)

            print('face_landmarks post ' + str(e))
            cv2.putText(img=frame,text="auto_marking:"+str(e),org=(50,100),fontFace=font,fontScale=5,color=(255, 0, 0),thickness=5,lineType=cv2.LINE_AA)
            # 显示画面
            # cv2.imshow('Demo',frame)
            writer.write(frame)
            # 退出条件
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

        else:
            break


    cap.release()
    cv2.destroyAllWindows()
imgs = glob.glob('dataset/img/*.jpg')
txts = glob.glob('dataset/txt/*.txt')
for i in range(10):
    img = cv2.imread(imgs[i])
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    with open(txts[i],'r') as f:
        points_list = [ t.strip() for t in f.readlines() ] 
        xmin = int(points_list[-4])
        ymin = int(points_list[-3])
        xmax = int(points_list[-2])
        ymax = int(points_list[-1])
        cv2.rectangle(img,pt1=(xmin,ymin),pt2=(xmax,ymax),color=(0,255,0),thickness=5)
        keypoint_features = np.array(points_list).reshape(-1,2)
        for x,y in keypoint_features:
            cv2.circle(img,(int(x),int(y)),5,(255,0,255),-1)
    plt.imshow(img)
    plt.show()

交付

华为云ModelArts

华北-北京四

限制

公开

版本

版本号
版本ID
发布时间
发布状态
版本说明
1.0.0
1.0.0
2023-07-01 09:08
已完成
Initial release.

关联资产

  • 人脸关键点检测数据集

    可以用于人脸检测和人脸关键点定位,由疲劳/分神驾驶样例数据集生成

    数据集
    0 0 169 10 1

    19个月以前

若您怀疑合法知识产权遭受侵犯,可以通过此链接进行投诉与建议。