Upload 7 files
Browse files- extract_faces.py +75 -0
- install.bat +33 -0
- resizer_v4.py +154 -0
- run_extract_faces_CPU.bat +10 -0
- run_extract_faces_GPU.bat +10 -0
- run_resizer_CPU.bat +10 -0
- run_resizer_GPU.bat +10 -0
extract_faces.py
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from PIL import Image
|
3 |
+
from retinaface import RetinaFace
|
4 |
+
from concurrent.futures import ProcessPoolExecutor
|
5 |
+
|
6 |
+
Image.MAX_IMAGE_PIXELS = 200000000 # Allow images up to 200 million pixels
|
7 |
+
|
8 |
+
DATA = [
|
9 |
+
((512, 512), r"G:\man dataset\man_4502_imgs_raw"),
|
10 |
+
((1024, 1024), r"G:\man dataset\man_4502_imgs_raw")
|
11 |
+
]
|
12 |
+
|
13 |
+
NUM_THREADS = 1 # Modify this for the desired number of threads
|
14 |
+
OUTPUT_ROOT = r"H:\man dataset\resize_faces" # Root folder to save resized face images
|
15 |
+
|
16 |
+
## change resize enabled to resize
|
17 |
+
def resize_face(args, resize_enabled=False):
|
18 |
+
try:
|
19 |
+
input_path, resolution, output_root = args
|
20 |
+
except ValueError as e:
|
21 |
+
print(f"Error unpacking arguments: {e}")
|
22 |
+
return
|
23 |
+
|
24 |
+
try:
|
25 |
+
image = Image.open(input_path)
|
26 |
+
except Exception as e:
|
27 |
+
print(f"Error loading image: {e}")
|
28 |
+
return
|
29 |
+
|
30 |
+
try:
|
31 |
+
# Detect faces
|
32 |
+
faces = RetinaFace.detect_faces(input_path)
|
33 |
+
|
34 |
+
if not faces:
|
35 |
+
print(f"No face detected in {input_path}")
|
36 |
+
return
|
37 |
+
|
38 |
+
# Assuming we take the first detected face
|
39 |
+
face = next(iter(faces.values()))
|
40 |
+
x, y, x2, y2 = face['facial_area']
|
41 |
+
face_image = image.crop((x, y, x2, y2))
|
42 |
+
|
43 |
+
if resize_enabled:
|
44 |
+
# Resize the cropped face only if resizing is enabled
|
45 |
+
face_image = face_image.resize(resolution, Image.LANCZOS)
|
46 |
+
except Exception as e:
|
47 |
+
print(f"Error in face detection or resizing: {e}")
|
48 |
+
return
|
49 |
+
|
50 |
+
try:
|
51 |
+
output_folder = os.path.join(output_root, f"{resolution[0]}x{resolution[1]}" if resize_enabled else "no_resize")
|
52 |
+
if not os.path.exists(output_folder):
|
53 |
+
os.makedirs(output_folder)
|
54 |
+
|
55 |
+
output_path = os.path.join(output_folder, os.path.basename(input_path))
|
56 |
+
face_image.save(output_path, quality=100)
|
57 |
+
except Exception as e:
|
58 |
+
print(f"Error saving image: {e}")
|
59 |
+
|
60 |
+
def process_folder(input_folder, resolution, resize_enabled=False):
|
61 |
+
image_paths = [os.path.join(input_folder, fname) for fname in os.listdir(input_folder) if fname.lower().endswith(('png', 'jpg', 'jpeg'))]
|
62 |
+
|
63 |
+
total_images = len(image_paths)
|
64 |
+
processed_count = 0
|
65 |
+
|
66 |
+
with ProcessPoolExecutor(max_workers=NUM_THREADS) as executor:
|
67 |
+
for _ in executor.map(resize_face, [(path, resolution, OUTPUT_ROOT) for path in image_paths], [resize_enabled] * len(image_paths)):
|
68 |
+
processed_count += 1
|
69 |
+
print(f"Processed {processed_count}/{total_images} images for resolution {resolution[0]}x{resolution[1]} (Resize: {'Enabled' if resize_enabled else 'Disabled'})...")
|
70 |
+
|
71 |
+
if __name__ == "__main__":
|
72 |
+
resize_enabled = False # Change this to True if resizing is needed
|
73 |
+
for resolution, folder in DATA:
|
74 |
+
process_folder(folder, resolution, resize_enabled)
|
75 |
+
print("Processing complete!")
|
install.bat
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
python.exe -m pip install --upgrade pip
|
4 |
+
|
5 |
+
REM Create virtual environment folder
|
6 |
+
echo composing venv
|
7 |
+
IF NOT EXIST venv (
|
8 |
+
python -m venv venv
|
9 |
+
) ELSE (
|
10 |
+
echo venv folder already exists, skipping making new venv...
|
11 |
+
)
|
12 |
+
call .\venv\Scripts\activate.bat
|
13 |
+
|
14 |
+
|
15 |
+
|
16 |
+
pip3 install torch==2.0.1 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
|
17 |
+
|
18 |
+
pip install tensorflow==2.10
|
19 |
+
|
20 |
+
pip install transformers
|
21 |
+
|
22 |
+
pip install Pillow
|
23 |
+
|
24 |
+
pip install retina-face
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
REM Show completion message
|
30 |
+
echo Virtual environment made and installed properly
|
31 |
+
|
32 |
+
REM Pause to keep the command prompt open
|
33 |
+
pause
|
resizer_v4.py
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import time
|
3 |
+
from PIL import Image
|
4 |
+
from retinaface import RetinaFace
|
5 |
+
from concurrent.futures import ProcessPoolExecutor
|
6 |
+
|
7 |
+
Image.MAX_IMAGE_PIXELS = 200000000 # Allow images up to 200 million pixels
|
8 |
+
|
9 |
+
DATA = [
|
10 |
+
((768,1368), r"F:\woman dataset\768x1368"),
|
11 |
+
((1216, 832), r"F:\woman dataset\1216x832")
|
12 |
+
]
|
13 |
+
|
14 |
+
DATA = [
|
15 |
+
((512, 512), r"H:\woman dataset\1536x1536"),
|
16 |
+
((768, 768), r"H:\woman dataset\1536x1536"),
|
17 |
+
((1024, 1024), r"H:\woman dataset\1536x1536"),
|
18 |
+
((1536, 1536), r"H:\woman dataset\1536x1536"),
|
19 |
+
((1280, 1536), r"H:\woman dataset\1280x1536"),
|
20 |
+
((1536, 1280), r"H:\woman dataset\1536x1280"),
|
21 |
+
((1024, 1536), r"H:\woman dataset\1024x1536"),
|
22 |
+
((1536, 1024), r"H:\woman dataset\1536x1024"),
|
23 |
+
((512, 768), r"H:\woman dataset\1024x1536"),
|
24 |
+
((768, 512), r"H:\woman dataset\1536x1024"),
|
25 |
+
((768, 1024), r"H:\woman dataset\768x1024"),
|
26 |
+
((1024, 768), r"H:\woman dataset\1024x768"),
|
27 |
+
((1024, 1280), r"H:\woman dataset\1024x1280"),
|
28 |
+
((1280, 1024), r"H:\woman dataset\1280x1024"),
|
29 |
+
((640,1536), r"H:\woman dataset\640x1536"),
|
30 |
+
((1536, 640), r"H:\woman dataset\1536x640"),
|
31 |
+
((768,1344), r"H:\woman dataset\768x1344"),
|
32 |
+
((1344, 768), r"H:\woman dataset\1344x768"),
|
33 |
+
((768,1368), r"H:\woman dataset\768x1368"),
|
34 |
+
((1368, 768), r"H:\woman dataset\1368x768"),
|
35 |
+
((832,1216), r"H:\woman dataset\832x1216"),
|
36 |
+
((1216, 832), r"H:\woman dataset\1216x832"),
|
37 |
+
((896,1152), r"H:\woman dataset\896x1152"),
|
38 |
+
((1152, 896), r"H:\woman dataset\1152x896")
|
39 |
+
]
|
40 |
+
|
41 |
+
|
42 |
+
|
43 |
+
NUM_THREADS = 1 # Modify this for the desired number of threads
|
44 |
+
OUTPUT_ROOT = r"G:\woman dataset\fixed_faces_png" # Root folder to save resized images
|
45 |
+
Save_PNG = False # Options are True and False
|
46 |
+
LOG_FILE = "face_detection_failures.txt" # File to log images where faces can't be detected
|
47 |
+
|
48 |
+
def resize_image(args):
|
49 |
+
start_time = time.time() # Start timing
|
50 |
+
|
51 |
+
try:
|
52 |
+
input_path, resolution, output_root, save_as_png = args
|
53 |
+
except ValueError as e:
|
54 |
+
print(f"Error unpacking arguments: {e}")
|
55 |
+
return None
|
56 |
+
|
57 |
+
try:
|
58 |
+
# Load the image
|
59 |
+
image = Image.open(input_path)
|
60 |
+
except Exception as e:
|
61 |
+
print(f"Error loading image: {e}")
|
62 |
+
return None
|
63 |
+
|
64 |
+
face_detected = True
|
65 |
+
face_locations = None
|
66 |
+
|
67 |
+
try:
|
68 |
+
# Get face locations using RetinaFace
|
69 |
+
faces = RetinaFace.detect_faces(input_path)
|
70 |
+
|
71 |
+
if not faces or 'face_1' not in faces:
|
72 |
+
face_detected = False
|
73 |
+
with open(LOG_FILE, 'a') as log:
|
74 |
+
log.write(f"Face not detected: {input_path}\n")
|
75 |
+
else:
|
76 |
+
face = faces['face_1']
|
77 |
+
x, y, x2, y2 = face['facial_area']
|
78 |
+
face_locations = [(y, x2, y2, x)] # Adjust format to match face_recognition
|
79 |
+
except Exception as e:
|
80 |
+
print(f"Error detecting faces: {e}")
|
81 |
+
face_detected = False
|
82 |
+
|
83 |
+
# Proceed with cropping and resizing
|
84 |
+
try:
|
85 |
+
desired_aspect_ratio = resolution[0] / resolution[1]
|
86 |
+
image_aspect_ratio = image.width / image.height
|
87 |
+
|
88 |
+
# Calculate crop dimensions
|
89 |
+
if image_aspect_ratio > desired_aspect_ratio:
|
90 |
+
new_width = int(image.height * desired_aspect_ratio)
|
91 |
+
new_height = image.height
|
92 |
+
else:
|
93 |
+
new_width = image.width
|
94 |
+
new_height = int(image.width / desired_aspect_ratio)
|
95 |
+
|
96 |
+
# Default centering
|
97 |
+
left = (image.width - new_width) / 2
|
98 |
+
top = (image.height - new_height) / 2
|
99 |
+
right = (image.width + new_width) / 2
|
100 |
+
bottom = (image.height + new_height) / 2
|
101 |
+
|
102 |
+
# Adjust for face center if a face is detected
|
103 |
+
if face_detected and face_locations:
|
104 |
+
face_top, face_right, face_bottom, face_left = face_locations[0]
|
105 |
+
face_center_x = (face_left + face_right) // 2
|
106 |
+
face_center_y = (face_top + face_bottom) // 2
|
107 |
+
|
108 |
+
left = min(max(0, face_center_x - new_width // 2), image.width - new_width)
|
109 |
+
top = min(max(0, face_center_y - new_height // 2), image.height - new_height)
|
110 |
+
right = left + new_width
|
111 |
+
bottom = top + new_height
|
112 |
+
|
113 |
+
image = image.crop((left, top, right, bottom))
|
114 |
+
|
115 |
+
# Resize image with best resampling filter (LANCZOS)
|
116 |
+
image = image.resize(resolution, Image.LANCZOS)
|
117 |
+
|
118 |
+
output_folder = os.path.join(output_root, f"{resolution[0]}x{resolution[1]}")
|
119 |
+
if not os.path.exists(output_folder):
|
120 |
+
os.makedirs(output_folder)
|
121 |
+
|
122 |
+
output_path = os.path.join(output_folder, os.path.basename(input_path))
|
123 |
+
if save_as_png:
|
124 |
+
output_path = os.path.splitext(output_path)[0] + '.png'
|
125 |
+
image.save(output_path, format='PNG')
|
126 |
+
else:
|
127 |
+
image.save(output_path, quality=100)
|
128 |
+
|
129 |
+
except Exception as e:
|
130 |
+
print(f"Error processing or saving image: {e}")
|
131 |
+
return None
|
132 |
+
|
133 |
+
end_time = time.time() # End timing
|
134 |
+
return end_time - start_time # Return processing time
|
135 |
+
|
136 |
+
def process_folder(input_folder, resolution, save_as_png):
|
137 |
+
image_paths = [os.path.join(input_folder, fname) for fname in os.listdir(input_folder) if fname.lower().endswith(('png', 'jpg', 'jpeg'))]
|
138 |
+
|
139 |
+
total_images = len(image_paths)
|
140 |
+
processed_count = 0
|
141 |
+
total_time = 0 # Total time for processing images
|
142 |
+
|
143 |
+
with ProcessPoolExecutor(max_workers=NUM_THREADS) as executor:
|
144 |
+
for processing_time in executor.map(resize_image, [(path, resolution, OUTPUT_ROOT, save_as_png) for path in image_paths]):
|
145 |
+
processed_count += 1
|
146 |
+
if processing_time is not None:
|
147 |
+
total_time += processing_time
|
148 |
+
average_time = total_time / processed_count * 1000 # Convert to milliseconds
|
149 |
+
print(f"Processed {processed_count}/{total_images} images for resolution {resolution[0]}x{resolution[1]}... Average processing time per image: {average_time:.2f} ms")
|
150 |
+
|
151 |
+
if __name__ == "__main__":
|
152 |
+
for resolution, folder in DATA:
|
153 |
+
process_folder(folder, resolution, Save_PNG)
|
154 |
+
print("Processing complete!")
|
run_extract_faces_CPU.bat
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
echo don't forget to run install bat and make sure that you have changed the paths in resize_faces.py file
|
4 |
+
echo moreover set your thread count according to your CPU
|
5 |
+
call .\venv\Scripts\activate.bat
|
6 |
+
|
7 |
+
set CUDA_VISIBLE_DEVICES=124121
|
8 |
+
python extract_faces.py
|
9 |
+
|
10 |
+
pause
|
run_extract_faces_GPU.bat
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
echo don't forget to run install bat and make sure that you have changed the paths in resize_faces.py file
|
4 |
+
echo moreover set your thread count according to your CPU
|
5 |
+
call .\venv\Scripts\activate.bat
|
6 |
+
|
7 |
+
set CUDA_VISIBLE_DEVICES=0
|
8 |
+
python extract_faces.py
|
9 |
+
|
10 |
+
pause
|
run_resizer_CPU.bat
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
echo don't forget to run install bat and make sure that you have changed the paths in resizer_v4.py file
|
4 |
+
echo moreover set your thread count according to your CPU
|
5 |
+
call .\venv\Scripts\activate.bat
|
6 |
+
|
7 |
+
set CUDA_VISIBLE_DEVICES=1231412
|
8 |
+
python resizer_v4.py
|
9 |
+
|
10 |
+
pause
|
run_resizer_GPU.bat
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
|
3 |
+
echo don't forget to run install bat and make sure that you have changed the paths in resizer_v4.py file
|
4 |
+
echo moreover set your thread count according to your CPU
|
5 |
+
call .\venv\Scripts\activate.bat
|
6 |
+
|
7 |
+
set CUDA_VISIBLE_DEVICES=0
|
8 |
+
python resizer_v4.py
|
9 |
+
|
10 |
+
pause
|