鱼C论坛

 找回密码
 立即注册
查看: 2358|回复: 1

人脸融合项目求怎么纠错

[复制链接]
发表于 2021-5-1 20:34:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import numpy as np
  2. import cv2
  3. import dlib
  4. from scipy.spatial import Delaunay


  5. predictor_model = 'shape_predictor_68_face_landmarks.dat'


  6. def get_points(image):  # 用 dlib 来得到人脸的特征点

  7.     face_detector = dlib.get_frontal_face_detector()  # 正向人脸检测器,进行人脸检测,提取人脸外部矩形框
  8.     face_pose_predictor = dlib.shape_predictor(predictor_model)
  9.     try:
  10.         detected_face = face_detector(image, 1)[0]
  11.     except:
  12.         print('No face detected in image {}'.format(image))
  13.     pose_landmarks = face_pose_predictor(image, detected_face)  # 获取landmark
  14.     points = []
  15.     for p in pose_landmarks.parts():
  16.         points.append([p.x, p.y])

  17.     # 加入四个顶点和四条边的中点
  18.     x = image.shape[1] - 1
  19.     y = image.shape[0] - 1
  20.     points.append([0, 0])
  21.     points.append([x // 2, 0])
  22.     points.append([x, 0])
  23.     points.append([x, y // 2])
  24.     points.append([x, y])
  25.     points.append([x // 2, y])
  26.     points.append([0, y])
  27.     points.append([0, y // 2])

  28.     return np.array(points)


  29. def get_triangles(points):  #  在特征点上使用 Delaunay 三角剖分,将点集连接成一定大小的三角形,且分配要相对合理,才能呈现出漂亮的三角化
  30.     return Delaunay(points).simplices


  31. def affine_transform(input_image, input_triangle, output_triangle, size):  # 对人脸进行仿射变换,确定位置
  32.     warp_matrix = cv2.getAffineTransform(
  33.         np.float32(input_triangle), np.float32(output_triangle))
  34.     output_image = cv2.warpAffine(input_image, warp_matrix, (size[0], size[1]), None,
  35.                                   flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)
  36.     return output_image


  37. def morph_triangle(img1, img2, img, tri1, tri2, tri, alpha):  # 三角形变形,Alpha 混合
  38.     # 计算三角形的边界框
  39.     rect1 = cv2.boundingRect(np.float32([tri1]))  # 寻找tri1的左上角坐标,和tri1的长和宽
  40.     rect2 = cv2.boundingRect(np.float32([tri2]))
  41.     rect = cv2.boundingRect(np.float32([tri]))

  42.     tri_rect1 = []
  43.     tri_rect2 = []
  44.     tri_rect_warped = []

  45.     for i in range(0, 3):
  46.         tri_rect_warped.append(
  47.             ((tri[i][0] - rect[0]), (tri[i][1] - rect[1])))
  48.         tri_rect1.append(
  49.             ((tri1[i][0] - rect1[0]), (tri1[i][1] - rect1[1])))
  50.         tri_rect2.append(
  51.             ((tri2[i][0] - rect2[0]), (tri2[i][1] - rect2[1])))

  52.     # 在边界框内进行仿射变换
  53.     img1_rect = img1[rect1[1]:rect1[1] +
  54.                      rect1[3], rect1[0]:rect1[0] + rect1[2]]
  55.     img2_rect = img2[rect2[1]:rect2[1] +
  56.                      rect2[3], rect2[0]:rect2[0] + rect2[2]]

  57.     size = (rect[2], rect[3])
  58.     warped_img1 = affine_transform(
  59.         img1_rect, tri_rect1, tri_rect_warped, size)
  60.     warped_img2 = affine_transform(
  61.         img2_rect, tri_rect2, tri_rect_warped, size)

  62.     # 加权求和
  63.     img_rect = (1.0 - alpha) * warped_img1 + alpha * warped_img2

  64.     # 生成模板
  65.     mask = np.zeros((rect[3], rect[2], 3), dtype=np.float32)
  66.     cv2.fillConvexPoly(mask, np.int32(tri_rect_warped), (1.0, 1.0, 1.0), 16, 0)

  67.     # 应用模板
  68.     img[rect[1]:rect[1] + rect[3], rect[0]:rect[0] + rect[2]] = \
  69.         img[rect[1]:rect[1] + rect[3], rect[0]:rect[0] +
  70.             rect[2]] * (1 - mask) + img_rect * mask


  71. def morph_faces(filename1, filename2, alpha=0.5):  # 融合图片
  72.     img1 = cv2.imread(filename1)
  73.     img2 = cv2.imread(filename2)
  74.     img2 = cv2.resize(img2,(img1.shape[1],img1.shape[0]),interpolation=cv2.INTER_CUBIC)
  75.     print('img1.shape',img1.shape)
  76.     print('img2.shape',img2.shape)

  77.     points1 = get_points(img1)
  78.     print('pionts1:',len(points1),points1)
  79.     points2 = get_points(img2)
  80.     points = (1 - alpha) * np.array(points1) + alpha * np.array(points2)
  81.     import pandas as pd
  82.     p = pd.DataFrame(points)
  83.     p.to_csv('./1.csv')

  84.     img1 = np.float32(img1)
  85.     img2 = np.float32(img2)
  86.     img_morphed = np.zeros(img1.shape, dtype=img1.dtype)

  87.     triangles = get_triangles(points)
  88.     for i in triangles:
  89.         x = i[0]
  90.         y = i[1]
  91.         z = i[2]

  92.         tri1 = [points1[x], points1[y], points1[z]]
  93.         tri2 = [points2[x], points2[y], points2[z]]
  94.         tri = [points[x], points[y], points[z]]
  95.         morph_triangle(img1, img2, img_morphed, tri1, tri2, tri, alpha)

  96.     return np.uint8(img_morphed)


  97. def main(file1,file2,alpha):
  98.     try:
  99.      alpha = float(alpha)
  100.     except:
  101.         alpha = 0.5
  102.     img_morphed = morph_faces(file1, file2, alpha)
  103.     output_file = '{}_{}_{}.jpg'.format(
  104.         file1.split('.')[0][-2:], file2.split('.')[0][-1:], alpha)
  105.     cv2.imwrite(output_file, img_morphed)
  106.     return output_file


复制代码


  1. from PIL import Image, ImageTk
  2. from tkinter.filedialog import askopenfilename
  3. from tkinter import *
  4. import PIL
  5. from face_morhper import main

  6. root = Tk()
  7. root.title('人脸融合软件')
  8. root.geometry('1200x500')

  9. decoration = PIL.Image.open('zyf.jpg').resize((1200, 500))
  10. render = ImageTk.PhotoImage(decoration)
  11. img = Label(image=render)
  12. img.image = render
  13. img.place(x=0, y=0)

  14. global path1_, path2_, rate, seg_img_path


  15. # 原图1展示
  16. def show_original1_pic():
  17.     global path1_
  18.     path1_ = askopenfilename(title='选择文件')
  19.     print(path1_)
  20.     Img = PIL.Image.open(r'{}'.format(path1_))
  21.     Img = Img.resize((270,270),PIL.Image.ANTIALIAS)   # 调整图片大小至256x256
  22.     img_png_original = ImageTk.PhotoImage(Img)
  23.     label_Img_original1.config(image=img_png_original)
  24.     label_Img_original1.image = img_png_original  # keep a reference
  25.     cv_orinial1.create_image(5, 5,anchor='nw', image=img_png_original)


  26. # 原图2展示
  27. def show_original2_pic():
  28.     global path2_
  29.     path2_ = askopenfilename(title='选择文件')
  30.     print(path2_)
  31.     Img = PIL.Image.open(r'{}'.format(path2_))
  32.     Img = Img.resize((270,270),PIL.Image.ANTIALIAS)   # 调整图片大小至256x256
  33.     img_png_original = ImageTk.PhotoImage(Img)
  34.     label_Img_original2.config(image=img_png_original)
  35.     label_Img_original2.image = img_png_original  # keep a reference
  36.     cv_orinial2.create_image(5, 5,anchor='nw', image=img_png_original)


  37. # 人脸融合效果展示
  38. def show_morpher_pic():
  39.     global path1_,seg_img_path,path2_
  40.     print(entry.get())
  41.     mor_img_path = main(path1_,path2_,entry.get())
  42.     Img = PIL.Image.open(r'{}'.format(mor_img_path))
  43.     Img = Img.resize((270, 270), PIL.Image.ANTIALIAS)  # 调整图片大小至256x256
  44.     img_png_seg = ImageTk.PhotoImage(Img)
  45.     label_Img_seg.config(image=img_png_seg)
  46.     label_Img_seg.image = img_png_seg  # keep a reference


  47. def quit():
  48.     root.destroy()


  49. # 原图1的展示
  50. Button(root, text = "打开图片1", command = show_original1_pic).place(x=50,y=120)
  51. # 原图2的展示
  52. Button(root, text = "打开图片2", command = show_original2_pic).place(x=50,y=200)
  53. # 进行提取结果的展示
  54. Button(root, text = "人脸融合", command = show_morpher_pic).place(x=50,y=280)

  55. Button(root, text = "退出软件", command = quit).place(x=900,y=40)

  56. Label(root,text = "融合系数",font=10).place(x=50,y=10)
  57. entry = Entry(root)
  58. entry.place(x=130,y=10)


  59. Label(root,text = "图片1",font=10).place(x=280,y=120)
  60. cv_orinial1 = Canvas(root,bg = 'white',width=270,height=270)
  61. cv_orinial1.create_rectangle(8,8,260,260,width=1,outline='red')
  62. cv_orinial1.place(x=180,y=150)
  63. label_Img_original1 = Label(root)
  64. label_Img_original1.place(x=180,y=150)


  65. Label(root,text="图片2",font=10).place(x=600,y=120)
  66. cv_orinial2 = Canvas(root,bg = 'white',width=270,height=270)
  67. cv_orinial2.create_rectangle(8,8,260,260,width=1,outline='red')
  68. cv_orinial2.place(x=500,y=150)
  69. label_Img_original2 = Label(root)
  70. label_Img_original2.place(x=500,y=150)

  71. Label(root, text="融合效果", font=10).place(x=920,y=120)
  72. cv_seg = Canvas(root, bg='white', width=270,height=270)
  73. cv_seg.create_rectangle(8,8,260,260,width=1,outline='red')
  74. cv_seg.place(x=820,y=150)
  75. label_Img_seg = Label(root)
  76. label_Img_seg.place(x=820,y=150)


  77. root.mainloop()
复制代码


报错:
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\12160\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "E:\人脸合成\interface.py", line 50, in show_morpher_pic
    mor_img_path = main(path1_,path2_,entry.get())
  File "E:\人脸合成\face_morhper.py", line 131, in main
    img_morphed = morph_faces(file1, file2, alpha)
  File "E:\人脸合成\face_morhper.py", line 96, in morph_faces
    img2 = cv2.resize(img2,(img1.shape[1],img1.shape[0]),interpolation=cv2.INTER_CUBIC)
AttributeError: 'NoneType' object has no attribute 'shape'

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-5-2 14:37:13 | 显示全部楼层
wocao
吊!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-24 09:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表