许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  瘦脸实现【Python】(基于人脸关键点/图像变形)

瘦脸实现【Python】(基于人脸关键点/图像变形)

阅读数 6
点赞 0
article_banner

对实现人脸瘦脸简单功能的一个记录,大概流程如下:

1.使用dlib 检测 出人脸关键点

2.使用Interactive Image Warping 局部平移 算法  实现瘦脸

瘦脸的 原理 可以参照这篇博客https://blog.csdn.net/grafx/article/details/70232797?locationNum=11&fps=1

下载地址:https://download.csdn.net/download/u011941438/10646628,可耻求2分。但以下代码再下个shape_predictor_68_face_landmarks.dat就可以直接执行了

ps:利用c语言扩展加速

给出代码:

#-*- coding:gb18030 -*- import dlibimport cv2import numpy as npimport mathpredictor_path='shape_predictor_68_face_landmarks.dat' #使用dlib自带的frontal_face_detector作为我们的特征提取器detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(predictor_path)   def landmark_dec_dlib_fun(img_src):    img_gray = cv2.cvtColor(img_src,cv2.COLOR_BGR2GRAY)     land_marks = []     rects = detector(img_gray,0)     for i in range(len(rects)):        land_marks_node = np.matrix([[p.x,p.y] for p in predictor(img_gray,rects[i]).parts()])        # for idx,point in enumerate(land_marks_node):        # # 68点坐标        # pos = (point[0,0],point[0,1])        # print(idx,pos)        # # 利用cv2.circle给每个特征点画一个圈,共68个        # cv2.circle(img_src, pos, 5, color=(0, 255, 0))        # # 利用cv2.putText输出1-68        # font = cv2.FONT_HERSHEY_SIMPLEX        # cv2.putText(img_src, str(idx + 1), pos, font, 0.8, (0, 0, 255), 1, cv2.LINE_AA)        land_marks.append(land_marks_node)     return land_marks     '''方法: Interactive Image Warping 局部平移算法'''  def localTranslationWarp(srcImg,startX,startY,endX,endY,radius):     ddradius = float(radius * radius)    copyImg = np.zeros(srcImg.shape, np.uint8)    copyImg = srcImg.copy()     # 计算公式中的|m-c|^2    ddmc = (endX - startX) * (endX - startX) + (endY - startY) * (endY - startY)    H, W, C = srcImg.shape    for i in range(W):        for j in range(H):            #计算该点是否在形变圆的范围之内            #优化,第一步,直接判断是会在(startX,startY)的矩阵框中            if math.fabs(i-startX)>radius and math.fabs(j-startY)>radius:                continue             distance = ( i - startX ) * ( i - startX) + ( j - startY ) * ( j - startY )             if(distance < ddradius):                #计算出(i,j)坐标的原坐标                #计算公式中右边平方号里的部分                ratio=(  ddradius-distance ) / ( ddradius - distance + ddmc)                ratio = ratio * ratio                 #映射原位置                UX = i - ratio  * ( endX - startX )                UY = j - ratio  * ( endY - startY )                 #根据双线性插值法得到UX,UY的值                value = BilinearInsert(srcImg,UX,UY)                #改变当前 i ,j的值                copyImg[j,i] =value     return copyImg  #双线性插值法def BilinearInsert(src,ux,uy):    w,h,c = src.shape    if c == 3:        x1=int(ux)        x2=x1+1        y1=int(uy)        y2=y1+1         part1=src[y1,x1].astype(np.float)*(float(x2)-ux)*(float(y2)-uy)        part2=src[y1,x2].astype(np.float)*(ux-float(x1))*(float(y2)-uy)        part3=src[y2,x1].astype(np.float) * (float(x2) - ux)*(uy-float(y1))        part4 = src[y2,x2].astype(np.float) * (ux-float(x1)) * (uy - float(y1))         insertValue=part1+part2+part3+part4         return insertValue.astype(np.int8) def face_thin_auto(src):     landmarks = landmark_dec_dlib_fun(src)     #如果未检测到人脸关键点,就不进行瘦脸    if len(landmarks) == 0:        return     for landmarks_node in landmarks:        left_landmark= landmarks_node[3]        left_landmark_down=landmarks_node[5]         right_landmark = landmarks_node[13]        right_landmark_down = landmarks_node[15]         endPt = landmarks_node[30]          #计算第4个点到第6个点的距离作为瘦脸距离        r_left=math.sqrt((left_landmark[0,0]-left_landmark_down[0,0])*(left_landmark[0,0]-left_landmark_down[0,0])+                         (left_landmark[0,1] - left_landmark_down[0,1]) * (left_landmark[0,1] - left_landmark_down[0, 1]))         # 计算第14个点到第16个点的距离作为瘦脸距离        r_right=math.sqrt((right_landmark[0,0]-right_landmark_down[0,0])*(right_landmark[0,0]-right_landmark_down[0,0])+                         (right_landmark[0,1] -right_landmark_down[0,1]) * (right_landmark[0,1] -right_landmark_down[0, 1]))         #瘦左边脸        thin_image = localTranslationWarp(src,left_landmark[0,0],left_landmark[0,1],endPt[0,0],endPt[0,1],r_left)        #瘦右边脸        thin_image = localTranslationWarp(thin_image, right_landmark[0,0], right_landmark[0,1], endPt[0,0],endPt[0,1], r_right)     #显示    cv2.imshow('thin',thin_image)    cv2.imwrite('thin.jpg',thin_image) def main():    src = cv2.imread('timg4.jpg')    cv2.imshow('src', src)    face_thin_auto(src)    cv2.waitKey(0) if __name__ == '__main__':    main()

效果如下:

原图:                                                                                                  

瘦脸后的图:

ps:照片来自网络,若有侵权请告知!


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删



相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空