Files
SimSwapPlus/face_crop.py
T
2022-02-08 16:37:30 +08:00

275 lines
10 KiB
Python

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#############################################################
# File: face_crop.py
# Created Date: Tuesday February 1st 2022
# Author: Chen Xuanhong
# Email: chenxuanhongzju@outlook.com
# Last Modified: Wednesday, 2nd February 2022 4:13:28 pm
# Modified By: Chen Xuanhong
# Copyright (c) 2022 Shanghai Jiao Tong University
#############################################################
import os
import cv2
import sys
import glob
import json
import tkinter
from tkinter.filedialog import askdirectory
import threading
import tkinter as tk
import tkinter.ttk as ttk
import subprocess
from pathlib import Path
from insightface_func.face_detect_crop_multi import Face_detect_crop
class TextRedirector(object):
def __init__(self, widget, tag="stdout"):
self.widget = widget
self.tag = tag
def write(self, str):
self.widget.configure(state="normal")
self.widget.insert("end", str, (self.tag,))
self.widget.configure(state="disabled")
self.widget.see(tk.END)
def flush(self):
pass
#############################################################
# Main Class
#############################################################
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master,bg='black')
# self.font_size = 16
self.font_list = ("Times New Roman",14)
self.padx = 5
self.pady = 5
self.window_init()
def __label_text__(self, usr, root):
return "User Name: %s\nWorkspace: %s"%(usr, root)
def window_init(self):
cwd = os.getcwd()
self.master.title('Face Crop - %s'%cwd)
# self.master.iconbitmap('./utilities/_logo.ico')
self.master.geometry("{}x{}".format(640, 600))
font_list = self.font_list
#################################################################################################
list_frame = tk.Frame(self.master)
list_frame.pack(fill="both", padx=5,pady=5)
list_frame.columnconfigure(0, weight=1)
list_frame.columnconfigure(1, weight=1)
list_frame.columnconfigure(2, weight=1)
self.img_path = tkinter.StringVar()
tk.Label(list_frame, text="Image/Video Path:",font=font_list,justify="left")\
.grid(row=0,column=0,sticky=tk.EW)
tk.Entry(list_frame, textvariable= self.img_path, font=font_list)\
.grid(row=0,column=1,sticky=tk.EW)
tk.Button(list_frame, text = "Select Path", font=font_list,
command = self.Select, bg='#F4A460', fg='#F5F5F5')\
.grid(row=0,column=2,sticky=tk.EW)
#################################################################################################
list_frame1 = tk.Frame(self.master)
list_frame1.pack(fill="both", padx=5,pady=5)
list_frame1.columnconfigure(0, weight=1)
list_frame1.columnconfigure(1, weight=1)
list_frame1.columnconfigure(2, weight=1)
self.save_path = tkinter.StringVar()
tk.Label(list_frame1, text="Target Path:",font=font_list,justify="left")\
.grid(row=0,column=0,sticky=tk.EW)
tk.Entry(list_frame1, textvariable= self.save_path, font=font_list)\
.grid(row=0,column=1,sticky=tk.EW)
tk.Button(list_frame1, text = "Select Path", font=font_list,
command = self.Select_Target, bg='#F4A460', fg='#F5F5F5')\
.grid(row=0,column=2,sticky=tk.EW)
#################################################################################################
label_frame = tk.Frame(self.master)
label_frame.pack(fill="both", padx=5,pady=5)
label_frame.columnconfigure(0, weight=1)
label_frame.columnconfigure(1, weight=1)
label_frame.columnconfigure(2, weight=1)
tk.Label(label_frame, text="Crop Size:",font=font_list,justify="left")\
.grid(row=0,column=0,sticky=tk.EW)
tk.Label(label_frame, text="Align Mode:",font=font_list,justify="left")\
.grid(row=0,column=1,sticky=tk.EW)
tk.Label(label_frame, text="Target Format:",font=font_list,justify="left")\
.grid(row=0,column=2,sticky=tk.EW)
#################################################################################################
test_frame = tk.Frame(self.master)
test_frame.pack(fill="both", padx=5,pady=5)
test_frame.columnconfigure(0, weight=1)
test_frame.columnconfigure(1, weight=1)
test_frame.columnconfigure(2, weight=1)
self.test_var = tkinter.StringVar()
self.test_com = ttk.Combobox(test_frame, textvariable=self.test_var)
self.test_com.grid(row=0,column=0,sticky=tk.EW)
self.test_com["value"] = [256,512,768,1024]
self.test_com.current(1)
self.align_var = tkinter.StringVar()
self.align_com = ttk.Combobox(test_frame, textvariable=self.align_var)
self.align_com.grid(row=0,column=1,sticky=tk.EW)
self.align_com["value"] = ["VGGFace","ffhq"]
self.align_com.current(0)
self.format_var = tkinter.StringVar()
self.format_com = ttk.Combobox(test_frame, textvariable=self.format_var)
self.format_com.grid(row=0,column=2,sticky=tk.EW)
self.format_com["value"] = ["png","jpg"]
self.format_com.current(0)
#################################################################################################
scale_frame = tk.Frame(self.master)
scale_frame.pack(fill="both", padx=5,pady=5)
scale_frame.columnconfigure(0, weight=2)
label_frame.columnconfigure(1, weight=1)
# label_frame.columnconfigure(2, weight=1)
tk.Label(scale_frame, text="Min Size:",font=font_list,justify="left")\
.grid(row=0,column=0,sticky=tk.EW)
self.min_scale = tkinter.StringVar()
tk.Scale(scale_frame, from_=0.5, to=2.0, length=500, orient=tk.HORIZONTAL, variable= self.min_scale,\
font=font_list, resolution=0.1).grid(row=0,column=1,sticky=tk.EW)
#################################################################################################
test_frame1 = tk.Frame(self.master)
test_frame1.pack(fill="both", padx=5,pady=5)
test_frame1.columnconfigure(0, weight=1)
# test_frame1.columnconfigure(1, weight=1)
test_update_button = tk.Button(test_frame1, text = "Crop",
font=font_list, command = self.Crop, bg='#F4A460', fg='#F5F5F5')
test_update_button.grid(row=0,column=0,sticky=tk.EW)
#################################################################################################
text = tk.Text(self.master, wrap="word")
text.pack(fill="both",expand="yes", padx=5,pady=5)
sys.stdout = TextRedirector(text, "stdout")
self.init_algorithm()
self.master.protocol("WM_DELETE_WINDOW", self.on_closing)
def init_algorithm(self):
self.detect = Face_detect_crop(name='antelope', root='./insightface_func/models')
# def __scaning_logs__(self):
def Select(self):
thread_update = threading.Thread(target=self.select_task)
thread_update.start()
def select_task(self):
path = askdirectory()
print("Selected source directory: %s"%path)
self.img_path.set(path)
def Select_Target(self):
thread_update = threading.Thread(target=self.select_target_task)
thread_update.start()
def select_target_task(self):
path = askdirectory()
print("Selected target directory: %s"%path)
self.save_path.set(path)
def Crop(self):
thread_update = threading.Thread(target=self.crop_task)
thread_update.start()
def crop_task(self):
mode = self.align_com.get()
crop_size = int(self.test_com.get())
path = self.img_path.get()
tg_path = self.save_path.get()
tg_format = self.format_com.get()
min_scale = float(self.min_scale.get())
blur_t = 100.0
font = cv2.FONT_HERSHEY_SIMPLEX
self.detect.prepare(ctx_id = 0, det_thresh=0.6,\
det_size=(640,640),mode = mode,crop_size=crop_size,ratio=min_scale)
if path and tg_path:
imgs_list = []
if os.path.isdir(path):
print("Input a dir....")
imgs = glob.glob(os.path.join(path,"*"))
for item in imgs:
imgs_list.append(item)
# print(imgs_list)
index = 0
for img in imgs_list:
print(img)
attr_img_ori= cv2.imread(img)
try:
attr_img_align_crop, _ = self.detect.get(attr_img_ori)
sub_index = 0
for face_i in attr_img_align_crop:
imageVar = cv2.Laplacian(face_i, cv2.CV_64F).var()
f_path =os.path.join(tg_path, str(index).zfill(6)+"_%d.%s"%(sub_index,tg_format))
if imageVar < blur_t:
print("Over blurry image!")
continue
# face_i = cv2.putText(face_i, '%.1f'%imageVar,(50, 50), font, 0.8, (15, 9, 255), 2)
cv2.imwrite(f_path,face_i)
sub_index += 1
index += 1
except:
print("Detect no face!")
continue
else:
print("Input an image....")
imgs_list.append(path)
print("Process finished!")
else:
print("Pathes are invalid!")
def on_closing(self):
# self.__save_config__()
self.master.destroy()
if __name__ == "__main__":
app = Application()
app.mainloop()