IDfy-Avatarify / gradio_demo /preprocess.py
yashvii's picture
Upload folder using huggingface_hub
b2cbfed verified
raw
history blame contribute delete
No virus
10.7 kB
import os
import random
import csv
import gc
import glob
from datetime import datetime
import time
from pathlib import Path
from style_template import style_list
from PIL import Image, ImageOps
# Default Configuration variables
INPUT_FOLDER_NAME = 'examples'
OUTPUT_FOLDER_NAME = 'generated_images'
LOG_FILENAME = 'generation_log.csv'
logfile_path = os.path.join(os.getcwd(), LOG_FILENAME)
PROMPT = "human, sharp focus"
NEGATIVE_PROMPT = "(blurry, blur, text, abstract, glitch, lowres, low quality, worst quality:1.2), (text:1.2), watermark, painting, drawing, illustration, glitch, deformed, mutated, cross-eyed, ugly, disfigured"
IDENTITYNET_STRENGTH_RATIO_RANGE = (1.0, 1.5)
ADAPTER_STRENGTH_RATIO_RANGE = (0.7, 1.0)
NUM_INFERENCE_STEPS_RANGE = (40, 60)
GUIDANCE_SCALE_RANGE = (7.0, 12.0)
MAX_SIDE = 1280
MIN_SIDE = 1024
NUMBER_OF_LOOPS = 1
# Dynamically create the STYLES list from imported style_list
STYLES = [style["name"] for style in style_list]
USE_RANDOM_STYLE = False
def choose_random_style():
return random.choice(STYLES)
def get_random_image_file(input_folder):
valid_extensions = [".jpg", ".jpeg", ".png"]
files = [file for file in Path(input_folder).glob("*") if file.suffix.lower() in valid_extensions]
if not files:
raise FileNotFoundError(f"No images found in directory {input_folder}")
return str(random.choice(files))
def resize_and_pad_image(image_path, max_side, min_side, pad_color=(255, 255, 255)):
# Open an image using PIL
image = Image.open(image_path)
# Calculate the scale and new size
ratio = min(min_side / min(image.size), max_side / max(image.size))
new_size = (int(image.size[0] * ratio), int(image.size[1] * ratio))
# Resize the image
image = image.resize(new_size, Image.BILINEAR)
# Calculate padding
delta_w = max_side - new_size[0]
delta_h = max_side - new_size[1]
# Pad the resized image to make it square
padding = (delta_w // 2, delta_h // 2, delta_w - (delta_w // 2), delta_h - (delta_h // 2))
image = ImageOps.expand(image, padding, pad_color)
return image
def log_to_csv(logfile_path, image_name, new_file_name='Unknown', identitynet_strength_ratio=0.0, adapter_strength_ratio=0.0, num_inference_steps=0, guidance_scale=0.0, seed=0, success=True, error_message='', style_name="", prompt="", negative_prompt="", time_taken=0.0, current_timestamp=""):
os.makedirs(os.path.dirname(logfile_path), exist_ok=True)
file_exists = os.path.isfile(logfile_path)
with open(logfile_path, 'a', newline='', encoding='utf-8') as csvfile:
fieldnames = ['image_name', 'new_file_name', 'identitynet_strength_ratio', 'adapter_strength_ratio', 'num_inference_steps', 'guidance_scale', 'seed', 'success', 'error_message', 'style_name', 'prompt', 'negative_prompt', 'time_taken', 'current_timestamp']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
if not file_exists:
writer.writeheader()
writer.writerow({
'image_name': image_name,
'new_file_name': new_file_name,
'identitynet_strength_ratio': identitynet_strength_ratio,
'adapter_strength_ratio': adapter_strength_ratio,
'num_inference_steps': num_inference_steps,
'guidance_scale': guidance_scale,
'seed': seed,
'success': success,
'error_message': error_message,
'style_name': style_name,
'prompt': prompt,
'negative_prompt': negative_prompt,
'time_taken': time_taken,
'current_timestamp': current_timestamp
})
def initial_image(generate_image_func):
overall_start_time = time.time()
total_time_taken = 0.0
# Initialize a counter for processed images at the beginning of the function
processed_images_count = 0
# List all image files in the `INPUT_FOLDER_NAME`
image_files = glob.glob(f'{INPUT_FOLDER_NAME}/*.png') + \
glob.glob(f'{INPUT_FOLDER_NAME}/*.jpg') + \
glob.glob(f'{INPUT_FOLDER_NAME}/*.jpeg')
# Check if we found any images
if not image_files:
raise FileNotFoundError(f"No images found in directory {INPUT_FOLDER_NAME}")
# Print the count of detected image files
print(f"Processing a total of {len(image_files)} image(s) in '{INPUT_FOLDER_NAME}'")
# Shuffle the image files randomly
random.shuffle(image_files)
total_images = len(image_files) # Get the total number of images to process
for loop in range(NUMBER_OF_LOOPS):
print(f"Starting loop {loop+1} of {NUMBER_OF_LOOPS}")
for image_number, face_image_path in enumerate(image_files, start=1):
loop_start_time = datetime.now()
face_image = [face_image_path]
basename = os.path.basename(face_image_path)
processed_images_count += 1
# Resize and pad the image before processing
processed_image = resize_and_pad_image(
image_path=face_image_path,
max_side=MAX_SIDE,
min_side=MIN_SIDE
)
if USE_RANDOM_STYLE:
style_name = choose_random_style()
else:
style_name = "(No style)"
identitynet_strength_ratio = random.uniform(*IDENTITYNET_STRENGTH_RATIO_RANGE)
adapter_strength_ratio = random.uniform(*ADAPTER_STRENGTH_RATIO_RANGE)
num_inference_steps = random.randint(*NUM_INFERENCE_STEPS_RANGE)
guidance_scale = random.uniform(*GUIDANCE_SCALE_RANGE)
seed = random.randint(0, 2**32 - 1)
# Print settings for the current image BEFORE processing it
print_generation_settings(basename, style_name, identitynet_strength_ratio,
adapter_strength_ratio, num_inference_steps, guidance_scale, seed,
image_number, total_images)
# Here, the generate_image_func is supposedly called and image processing happens
_, _, generated_file_paths = generate_image_func(
face_image=face_image,
pose_image=None,
prompt=PROMPT,
negative_prompt=NEGATIVE_PROMPT,
style_name=style_name,
enhance_face_region=True,
num_steps=num_inference_steps,
identitynet_strength_ratio=identitynet_strength_ratio,
adapter_strength_ratio=adapter_strength_ratio,
guidance_scale=guidance_scale,
seed=seed
)
loop_end_time = datetime.now()
loop_time_taken = (loop_end_time - loop_start_time).total_seconds()
# Immediately print the time taken and current time.
print(f"Time taken to process image: {loop_time_taken:.2f} seconds")
# Update the total time taken with this image's processing time
total_time_taken += loop_time_taken
# Calculate the average time taken per image
average_time_per_image = total_time_taken / image_number
current_timestamp = loop_end_time.strftime("%Y-%m-%d %H:%M:%S") # Current time after processing
print(f"Current timestamp: {current_timestamp}")
# Calculate estimated remaining time considering the images left in this loop and the additional loops
remaining_images_this_loop = total_images - image_number
remaining_images_in_additional_loops = (NUMBER_OF_LOOPS - (loop + 1)) * total_images
total_remaining_images = remaining_images_this_loop + remaining_images_in_additional_loops
estimated_time_remaining = average_time_per_image * total_remaining_images
# Display the estimated time remaining including remaining loops
print(f"Estimated time remaining (including loops): {estimated_time_remaining // 60:.0f} minutes, {estimated_time_remaining % 60:.0f} seconds")
# Display the overall average time per image in seconds
print(f"Overall average time per image: {average_time_per_image:.2f} seconds")
# Display the total number of remaining images to process including looping
print(f"Total remaining images to process (including loops): {total_remaining_images}")
success = True # Assuming generation was successful.
error_message = "" # Assuming no error.
# Log to CSV after the image generation.
for generated_file_path in generated_file_paths:
new_file_name = os.path.basename(generated_file_path)
log_to_csv(logfile_path, basename, new_file_name, identitynet_strength_ratio,
adapter_strength_ratio, num_inference_steps, guidance_scale, seed, success,
error_message, style_name, PROMPT, NEGATIVE_PROMPT, loop_time_taken, current_timestamp)
del generated_file_paths # Explicitly delete large variables
gc.collect() # Call garbage collection
# At the end of the initial_image() function, add:
total_elapsed_time = time.time() - overall_start_time
print("\n===FINAL SUMMARY===")
print(f"Total loops completed: {NUMBER_OF_LOOPS}")
print(f"Total images processed per loop: {len(image_files)}")
print(f"Overall total images processed: {NUMBER_OF_LOOPS * len(image_files)}") # Multiplied by the number of loops
print(f"Overall total time: {total_elapsed_time / 60:.2f} minutes")
def print_generation_settings(basename, style_name, identitynet_strength_ratio, adapter_strength_ratio, num_inference_steps, guidance_scale, seed, image_number, total_images):
print("===IMAGE GENERATION DATA SUMMARY===")
# Print settings for the current image
print(f"- Image {image_number} of {total_images}\n"
f"- Filename: {basename}\n"
f"- Style: {style_name}\n"
f"- IdentityNet strength ratio: {identitynet_strength_ratio:0.2f}\n"
f"- Adapter strength ratio: {adapter_strength_ratio:0.2f}\n"
f"- Number of inference steps: {num_inference_steps}\n"
f"- Guidance scale: {guidance_scale:0.2f}\n"
f"- Seed: {seed}\n"
f"- Input folder name: {INPUT_FOLDER_NAME}\n"
f"- Output folder name: {OUTPUT_FOLDER_NAME}\n"
f"- Prompt: {PROMPT}\n"
f"- Negative prompt: {NEGATIVE_PROMPT}\n"
f"- Number of loops: {NUMBER_OF_LOOPS}\n"
f"- Use random style: {USE_RANDOM_STYLE}\n")
print("===DEFINING COMPLETE, GENERATING IMAGE...===")