I am trying to create a script that goes through all the image faces in my folder, detects the faces and converts it to greyscale (for CNN purposes)
import cv2 import os
input_directory = r'C:UsersMeDesktopProjectPython FilesTrainingPicturesUncropped_Me' cascades_directory = r'C:UsersMeDesktopProjectPython Fileshaarcascade_frontalface_default.xml' output_directory = r'C:UsersMeDesktopProjectPython FilesTrainingPicturesCropped_Me_Grey'
if not os.path.exists(output_directory): os.makedirs(output_directory)
for filename in os.listdir(input_directory): input_path = os.path.join(input_directory, filename)
img = cv2.imread(input_path)
img_grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#identify and store x,y,w,h in array
haar_cascades = cv2.CascadeClassifier(cascades_directory)
faces = haar_cascades.detectMultiScale(img_grey, scaleFactor = 1.3, minNeighbors = 4)
print(f'Detected {len(faces)} in {filename}')
#Rectangle around around face, then crop, then save
for i,(x,y,w,h) in enumerate(faces):
cv2.rectangle(img_grey, pt1 = (x,y), pt2 = ((x+w),(y+h)), color = (0,255,0), thickness = 2)
faces_cropped = img_grey[y: y+h , x: x+w]
output_filename = f'Cropped_Me_Grey_{i+1}.jpg'
output_path = os.path.join(output_directory,output_filename)
cv2.imwrite(output_path,faces_cropped)
print(faces_cropped.shape)
print(faces)
cv2.destroyAllWindows()
When I run the script. It creats a singular file only. When I open the file it seems to loop through all the images in my input directory but then saves over the previous file if that makes sense.
That suggests to me that it is correctly looping through all of the files, but is overwriting the last file it made.
Does this mean I have an issue with ‘output_filename’, this is where I believe the problem may lie, but I don’t know how to fix it.
In the first for loop, you are iterating over all the files in the folder, but in each iteration, you’re overwriting the input_path
variable. As a result, by the end of the loop, input_path
only contains the path of the last image. To fix this, you should use a list to store all the file paths. This way, you’ll be able to retain the paths for all images in the folder.
The error was not in storing paths, but in how my script was saving the pictures.
output_filename = f'Cropped_Me_Grey_{i+1}.jpg'
The above line is incorrect. If someone more advanced than I could let us know it would be great.
Corrected:
output_filename = f'processed_photo_{int(cv2.getTickCount())}.jpg'
The {int(cv2.getTickCount())}
line I retrieved from a previous code. Seems to have worked.