live2d 抠人脸

Peppa_Pig_Face_Landmark

python 复制代码
import glob

import cv2
import time
import numpy as np
import os
import argparse


from Skps import FaceAna
def video(video_path_or_cam):
    facer = FaceAna()
    vide_capture=cv2.VideoCapture(video_path_or_cam)

    while 1:
        ret, image = vide_capture.read()
        if ret:
            pattern = np.zeros_like(image)
            img_show = image.copy()
            star=time.time()
            result = facer.run(image)
            duration=time.time()-star
            #print('one iamge cost %f s'%(duration))
            fps=1/duration
            cv2.putText(img_show, "X: " + "{:7.2f}".format(fps), (20, 20), cv2.FONT_HERSHEY_SIMPLEX,
                        0.75, (0, 0, 0), thickness=2)
            for face_index in range(len(result)):
                cur_face_kps=result[face_index]['kps']
                cur_face_kps_score=result[face_index]['scores']
                for landmarks_index in range(cur_face_kps.shape[0]):
                    x_y = cur_face_kps[landmarks_index]
                    score=cur_face_kps_score[landmarks_index]
                    # color = (255, 255, 255)
                    if score>0.8:
                        color=(255,255,255)
                    else:
                        color = (0, 0, 255)
                    cv2.circle(img_show, (int(x_y[0]), int(x_y[1])),
                                   color=color, radius=1, thickness=2)
            cv2.namedWindow("capture", 0)
            cv2.imshow("capture", img_show)
            if args.mask:
                cv2.namedWindow("masked", 0)
                cv2.imshow("masked", image*pattern)

            key=cv2.waitKey(1)
            if key==ord('q'):
                return

def save_roi_as_png(mask, landmarks, indices,expand_ratio=1.0):

    pts = landmarks[indices].astype(np.int32)
    x_min = np.min(pts[:, 0])
    x_max = np.max(pts[:, 0])
    y_min = np.min(pts[:, 1])
    y_max = np.max(pts[:, 1])
    
    H, W = mask.shape[:2]
    # 矩形中心
    cx = (x_min + x_max) // 2
    cy = (y_min + y_max) // 2

    # 边长取矩形最大边,扩展 expand_ratio
    side = int(max(x_max - x_min, y_max - y_min) * expand_ratio / 2)

    # 正方形边界
    x1 = max(cx - side, 0)
    x2 = min(cx + side, W - 1)
    y1 = max(cy - side, 0)
    y2 = min(cy + side, H - 1)

    # 填充 mask
    cv2.rectangle(mask, (x1, y1), (x2, y2), 255, -1)
    
    return mask
def images(image_dir):
    facer = FaceAna()
    
    # image_list=glob.glob(image_dir+'/*.jpg')
    image_list=glob.glob(r"B:\360MoveData\Users\Administrator\Desktop\tmp\a123.jpeg")

    for image_name in image_list:

        image=cv2.imread(os.path.join(image_dir,image_name))
        pattern = np.zeros_like(image)
        img_show = image.copy()

        star=time.time()
        result = facer.run(image)
        ###no track
        facer.reset()
        duration=time.time()-star
        print('one iamge cost %f s'%(duration))
        for face_index in range(len(result)):

            cur_face_kps = result[face_index]['kps']
            cur_face_kps_score = result[face_index]['scores']
            
            left_eye_idx = np.arange(60, 68)
            right_eye_idx = np.arange(68, 76)
            mouth_idx = np.arange(76, 96)
            jaw_low_idx = np.arange(8, 11)
            
            
            H, W = img_show.shape[:2]
            
            # 创建黑色 mask
            mask = np.zeros((H, W), dtype=np.uint8)
            # ----- 保存区域 -----
            mask = save_roi_as_png(mask, cur_face_kps, left_eye_idx)
            mask = save_roi_as_png(mask, cur_face_kps, right_eye_idx)
            
        
            pts = np.concatenate([cur_face_kps[mouth_idx], cur_face_kps[jaw_low_idx]]).astype(np.int32)
            x_min, y_min = np.min(pts, axis=0)
            x_max, y_max = np.max(pts, axis=0)
            cv2.rectangle(mask, (x_min, y_min), (x_max, y_max), 255, -1)
            
            cv2.imwrite('mask1.png',mask)
            
            for landmarks_index in range(cur_face_kps.shape[0]):

                x_y = cur_face_kps[landmarks_index]
                score = cur_face_kps_score[landmarks_index]
                # color = (255, 255, 255)
                if score > 0.8:
                    color = (255, 0, 0)
                else:
                    color = (0, 0, 255)
                cv2.circle(img_show, (int(x_y[0]), int(x_y[1])),
                           color=color, radius=1, thickness=1)

        # cv2.namedWindow("capture", 0)
        cv2.imshow("capture", img_show)

        key=cv2.waitKey(0)
        if key==ord('q'):
            return

def build_argparse():
    parser = argparse.ArgumentParser(description='Start train.')
    parser.add_argument('--video', dest='video', type=str, default=None,  help='the camera id (default: 0)')
    parser.add_argument('--cam_id', dest='cam_id', type=int, default=0,help='the camera to use')
    parser.add_argument('--img_dir', dest='img_dir', type=str, default='aa',  help='the images dir to use')

    parser.add_argument('--mask', dest='mask', type=bool, default=False, help='mask the face or not')

    args = parser.parse_args()
    return  args

if __name__=='__main__':

    args=build_argparse()

    if args.img_dir is not None:
        images(args.img_dir)

    elif args.video is not None:
        video(args.video)
    else:
        video(args.cam_id)
相关推荐
测试员周周6 小时前
【Appium 系列】第16节-WebView-H5上下文切换 — 混合应用的自动化难点
运维·开发语言·人工智能·功能测试·appium·自动化·测试用例
K姐研究社8 小时前
怎么用AI制作电商口播视频,开拍APP一键生成
人工智能·音视频
LaughingZhu9 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
传说故事9 小时前
【论文阅读】MotuBrain: An Advanced World Action Model for Robot Control
论文阅读·人工智能·具身智能·wam
北京耐用通信10 小时前
全域适配工业场景耐达讯自动化Modbus TCP 转 PROFIBUS 网关轻松实现以太网与现场总线互通
网络·人工智能·网络协议·自动化·信息与通信
火山引擎开发者社区10 小时前
TRAE × 火山引擎 Supabase:为你的 AI 应用装上“数据引擎”
人工智能
小a彤10 小时前
GE 在 CANN 五层架构中的位置
人工智能·深度学习·transformer
前端若水10 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Upsy-Daisy10 小时前
AI Agent 项目学习笔记(八):Tool Calling 工具调用机制总览
人工智能·笔记·学习
企学宝10 小时前
企学宝5月专题课程丨《OpenClaw AI 智能体实战营:从零基础部署到全场景自动化落地》
人工智能·ai·企业培训