首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >三色手机过人脸教程,人脸识别图片眨眼生成器,python模型算法分享

三色手机过人脸教程,人脸识别图片眨眼生成器,python模型算法分享

原创
作者头像
用户11749621
发布2025-07-17 12:46:47
发布2025-07-17 12:46:47
1.3K0
举报

下载地址:https://www.pan38.com/dow/share.php?code=JCnzE 提取密码:1133

这些代码实现了一个完整的人脸识别系统,包含眨眼检测、人脸替换和活体验证功能。您需要下载dlib的预训练模型shape_predictor_68_face_landmarks.dat才能运行。

代码语言:txt
复制

import cv2
import dlib
import numpy as np
from scipy.spatial import distance as dist

class BlinkDetector:
    def __init__(self):
        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
        self.EYE_AR_THRESH = 0.25
        self.EYE_AR_CONSEC_FRAMES = 3
        self.COUNTER = 0
        self.TOTAL = 0
        
    def eye_aspect_ratio(self, eye):
        # 计算两组垂直方向上的欧氏距离
        A = dist.euclidean(eye[1], eye[5])
        B = dist.euclidean(eye[2], eye[4])
        
        # 计算水平方向上的欧氏距离
        C = dist.euclidean(eye[0], eye[3])
        
        # 计算眼睛纵横比
        ear = (A + B) / (2.0 * C)
        return ear
    
    def detect_blinks(self, frame):
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        rects = self.detector(gray, 0)
        
        for rect in rects:
            shape = self.predictor(gray, rect)
            shape = np.array([(shape.part(i).x, shape.part(i).y) for i in range(68)])
            
            left_eye = shape[42:48]
            right_eye = shape[36:42]
            
            left_ear = self.eye_aspect_ratio(left_eye)
            right_ear = self.eye_aspect_ratio(right_eye)
            
            ear = (left_ear + right_ear) / 2.0
            
            left_eye_hull = cv2.convexHull(left_eye)
            right_eye_hull = cv2.convexHull(right_eye)
            cv2.drawContours(frame, [left_eye_hull], -1, (0, 255, 0), 1)
            cv2.drawContours(frame, [right_eye_hull], -1, (0, 255, 0), 1)
            
            if ear < self.EYE_AR_THRESH:
                self.COUNTER += 1
            else:
                if self.COUNTER >= self.EYE_AR_CONSEC_FRAMES:
                    self.TOTAL += 1
                self.COUNTER = 0
            
            cv2.putText(frame, "Blinks: {}".format(self.TOTAL), (10, 30),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
            cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        
        return frame

def main():
    detector = BlinkDetector()
    cap = cv2.VideoCapture(0)
    
    while True:
        ret, frame = cap.read()
        if not ret:
            break
            
        frame = detector.detect_blinks(frame)
        cv2.imshow("Blink Detection", frame)
        
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            
    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()
import cv2
import dlib
import numpy as np
from PIL import Image

class FaceSwapper:
    def __init__(self):
        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
        
    def get_landmarks(self, image):
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        rects = self.detector(gray, 1)
        
        if len(rects) == 0:
            return None
            
        shape = self.predictor(gray, rects[0])
        landmarks = np.array([[p.x, p.y] for p in shape.parts()])
        return landmarks
        
    def create_blinking_effect(self, image, landmarks, blink_ratio=0.5):
        # 获取眼睛区域
        left_eye = landmarks[36:42]
        right_eye = landmarks[42:48]
        
        # 计算眼睛中心
        left_eye_center = np.mean(left_eye, axis=0).astype(int)
        right_eye_center = np.mean(right_eye, axis=0).astype(int)
        
        # 创建眨眼效果
        mask = np.ones_like(image) * 255
        for y in range(left_eye_center[1]-5, left_eye_center[1]+5):
            for x in range(left_eye[0][0], left_eye[3][0]):
                if (y - left_eye_center[1])**2 / (5**2) + (x - left_eye_center[0])**2 / (10**2) <= 1:
                    mask[y,x] = image[y,x]
                    
        for y in range(right_eye_center[1]-5, right_eye_center[1]+5):
            for x in range(right_eye[0][0], right_eye[3][0]):
                if (y - right_eye_center[1])**2 / (5**2) + (x - right_eye_center[0])**2 / (10**2) <= 1:
                    mask[y,x] = image[y,x]
                    
        # 混合原始图像和眨眼效果
        result = cv2.addWeighted(image, 1-blink_ratio, mask, blink_ratio, 0)
        return result
        
    def swap_faces(self, src_image, dst_image):
        src_landmarks = self.get_landmarks(src_image)
        dst_landmarks = self.get_landmarks(dst_image)
        
        if src_landmarks is None or dst_landmarks is None:
            return dst_image
            
        # 创建凸包
        hull_index = list(range(17)) + list(range(17, 27))[::-1]
        hull = cv2.convexHull(src_landmarks[hull_index], False)
        
        # 计算Delaunay三角剖分
        rect = (0, 0, dst_image.shape[1], dst_image.shape[0])
        subdiv = cv2.Subdiv2D(rect)
        for p in dst_landmarks[hull_index]:
            subdiv.insert((int(p[0]), int(p[1])))
            
        triangles = subdiv.getTriangleList()
        triangles = np.array(triangles, dtype=np.int32)
        
        # 实现人脸交换
        warped_image = np.copy(dst_image)
        for t in triangles:
            src_tri = []
            dst_tri = []
            
            for i in range(3):
                src_tri.append(src_landmarks[hull_index][np.where(
                    (dst_landmarks[hull_index][:,0] == t[i*2]) & 
                    (dst_landmarks[hull_index][:,1] == t[i*2+1]))[0][0]])
                dst_tri.append([t[i*2], t[i*2+1]])
                
            self.warp_triangle(src_image, warped_image, np.float32(src_tri), np.float32(dst_tri))
            
        # 创建无缝克隆
        mask = np.zeros(dst_image.shape, dtype=dst_image.dtype)
        cv2.fillConvexPoly(mask, np.int32(hull), (255, 255, 255))
        r = cv2.boundingRect(np.float32([hull]))
        center = ((r[0]+r[2]//2, r[1]+r[3]//2))
        output = cv2.seamlessClone(warped_image, dst_image, mask, center, cv2.NORMAL_CLONE)
        
        return output
        
    def warp_triangle(self, src_img, dst_img, src_tri, dst_tri):
        # 计算仿射变换
        warp_mat = cv2.getAffineTransform(src_tri, dst_tri)
        
        # 应用变换
        warped = cv2.warpAffine(src_img, warp_mat, (dst_img.shape[1], dst_img.shape[0]), None, 
                               flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
        
        # 创建mask
        mask = np.zeros((dst_img.shape[0], dst_img.shape[1], 3), dtype=np.float32)
        cv2.fillConvexPoly(mask, np.int32(dst_tri), (1.0, 1.0, 1.0), 16, 0)
        
        # 混合图像
        dst_img = dst_img * (1 - mask) + warped * mask
        
def main():
    swapper = FaceSwapper()
    
    # 加载图像
    src_img = cv2.imread("source.jpg")
    dst_img = cv2.imread("target.jpg")
    
    # 人脸交换
    swapped = swapper.swap_faces(src_img, dst_img)
    
    # 添加眨眼效果
    landmarks = swapper.get_landmarks(swapped)
    if landmarks is not None:
        blinked = swapper.create_blinking_effect(swapped, landmarks, 0.7)
        cv2.imwrite("result.jpg", blinked)
    else:
        cv2.imwrite("result.jpg", swapped)

if __name__ == "__main__":
    main()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档