I have a face recognition code(Entire code given at the end) that works perfectly fine with the existing dataset.
But I wanted it to also add new faces into the dataset(Enrollments), after asking for a user input for the name of the new person in the frame [like this: new_name = print(Who is this?)]. So then I could create a new folder by the entered name, and store the face inside the frame. This is what I did:
new_name = input("Who is this?")
path_2 = os.path.join('Images',new_name)
os.mkdir(path_2)
print("Directory '% s' created" % new_name)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0,0,255),
thickness = 2)
cv2.putText(frame, new_name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
0.75, (0, 255, 0), 2)
sub_face = frame[y:y+h, x:x+w]
FaceFileName = new_name + str(y+x) + ".jpg"
cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
cv2.imshow("Frame",frame)
#if cv2.waitKey(1) & 0xFF == ord('q'):
# break
This worked fine with new people. But now I had to do something for unrecognized faces of known people.
In this case, we would already have a folder by the entered name. We must append the image into the existing folder by the entered name.
So for this I tried the below code: (Did not work)
else: # To store the unknown new face with name
new_name = input("Who is this?")
# If the new_name entered already exists as a folder
if os.path.isfile(new_name):
print(new_name,"folder already exists")
frame = imutils.resize(frame, width = 400)
rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30))
FaceFileName = new_name + str(y+x) + ".jpg"
for (x, y, w, h) in rects:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Frame",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("k"):
p = os.path.join([new_name,FaceFileName.format(str(total).zfill(5))])
# cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
cv2.imwrite(p, orig)
total += 1
print("Image saved")
elif key == ord("q"):
break
# If the new_name does not exist as a folder new folder has to be created
else:
path_2 = os.path.join('Images',new_name)
os.mkdir(path_2)
print("Directory '% s' created" % new_name)
frame = imutils.resize(frame, width = 400)
rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30))
FaceFileName = new_name + str(y+x) + ".jpg"
for (x, y, w, h) in rects:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Frame",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("k"):
p = os.path.join([path_2,FaceFileName.format(str(total).zfill(5))])
# cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
cv2.imwrite(p, orig)
total += 1
print("Image saved")
I am getting the error:
Who is this?Vishwesh
Traceback (most recent call last):
File "C:\Users\Vishw\databs.py", line 117, in <module>
os.mkdir(path_2)
FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'Images\\Vishwesh'
[ WARN:0] global C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-sgoydvi3\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
Complete code is given below. Let me know what is wrong with the code. Kindly help!
Note: I included the above codes under the # Face recognition on LIVE WEBCAM FEED section and as else statement for the "if True in matches:"
Here is my entire code:
# Extracting features from face
from imutils import paths
import face_recognition
import pickle
import cv2
import os
#Get paths of each file in folder named Images
#Images here contains my data(folders of various persons)
imagePaths = list(paths.list_images('Images'))
knownEncodings = []
knownNames = []
# loop over the image paths
for (i, imagePath) in enumerate(imagePaths):
# extract the person name from the image path
name = imagePath.split(os.path.sep)[-2]
# load the input image and convert it from BGR (OpenCV ordering)
# to dlib ordering (RGB)
image = cv2.imread(imagePath)
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
#Use Face_recognition to locate faces
boxes = face_recognition.face_locations(rgb,model='hog')
# compute the facial embedding for the face
encodings = face_recognition.face_encodings(rgb, boxes)
# loop over the encodings
for encoding in encodings:
knownEncodings.append(encoding)
knownNames.append(name)
#save emcodings along with their names in dictionary data
data = {"encodings": knownEncodings, "names": knownNames}
#use pickle to save data into a file for later use
f = open("face_enc", "wb")
f.write(pickle.dumps(data))
f.close()
# Face recognition on LIVE WEBCAM FEED
import face_recognition
import pickle
import cv2
import os
#find path of xml file containing haarcascade file
cascPathface = os.path.dirname(
cv2.__file__) + "/data/haarcascade_frontalface_default.xml"
# load the harcaascade in the cascade classifier
faceCascade = cv2.CascadeClassifier(cascPathface)
# load the known faces and embeddings saved in last file
data = pickle.loads(open('face_enc', "rb").read())
print("Streaming started")
video_capture = cv2.VideoCapture(0)
# loop over frames from the video file stream
while True:
# grab the frame from the threaded video stream
ret, frame = video_capture.read()
orig = frame.copy()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray,
scaleFactor=1.05,
minNeighbors=3,
minSize=(60, 60),
flags=cv2.CASCADE_SCALE_IMAGE)
# convert the input frame from BGR to RGB
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# the facial embeddings for face in input
encodings = face_recognition.face_encodings(rgb)
names = []
# loop over the facial embeddings incase
# we have multiple embeddings for multiple fcaes
for encoding in encodings:
#Compare encodings with encodings in data["encodings"]
#Matches contain array with boolean values and True for the embeddings it matches closely
#and False for rest
matches = face_recognition.compare_faces(data["encodings"],encoding)
#set name =unknown if no encoding matches
name = "Unknown"
# check to see if we have found a match
if True in matches:
# Find positions at which we get True and store them
matchedIdxs = [i for (i, b) in enumerate(matches) if b]
counts = {}
# loop over the matched indexes and maintain a count for
# each recognized face face
for i in matchedIdxs:
#Check the names at respective indexes we stored in matchedIdxs
name = data["names"][i]
#increase count for the name we got
counts[name] = counts.get(name, 0) + 1
#set name which has highest count
name = max(counts, key=counts.get)
else: # To store the unknown new face with name
new_name = input("Who is this?")
# If the new_name entered already exists as a folder
if os.path.isfile(new_name):
print(new_name,"folder already exists")
frame = imutils.resize(frame, width = 400)
rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30))
FaceFileName = new_name + str(y+x) + ".jpg"
for (x, y, w, h) in rects:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Frame",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("k"):
p = os.path.join([new_name,FaceFileName.format(str(total).zfill(5))])
# cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
cv2.imwrite(p, orig)
total += 1
print("Image saved")
elif key == ord("q"):
break
# If the new_name does not exist as a folder new folder has to be created
else:
path_2 = os.path.join('Images',new_name)
os.mkdir(path_2)
print("Directory '% s' created" % new_name)
frame = imutils.resize(frame, width = 400)
rects = detector.detectMultiScale(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY),
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30))
FaceFileName = new_name + str(y+x) + ".jpg"
for (x, y, w, h) in rects:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Frame",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("k"):
p = os.path.join([path_2,FaceFileName.format(str(total).zfill(5))])
# cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
cv2.imwrite(p, orig)
total += 1
print("Image saved")
# update the list of names
names.append(name)
# loop over the recognized faces
for ((x, y, w, h), name) in zip(faces, names):
# rescale the face coordinates
# draw the predicted face name on the image
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
0.75, (0, 255, 0), 2)
cv2.imshow("Frame", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
So, your issue is rather related to file operations then to face recognition...
Try to check if folder alreday exists before trying to create it:
path_2 = os.path.join('Images',new_name)
if not os.path.exists(path_2):
os.mkdir(path_2)
Using the idea given by #Bohdan:
else: # To store the unknown new face with name
new_name = input("Who is this?")
path_2 = os.path.join('Images',new_name)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0,0,255),
thickness = 2)
cv2.putText(frame, new_name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,
0.75, (0, 255, 0), 2)
sub_face = frame[y:y+h, x:x+w]
FaceFileName = new_name + str(y+x) + ".jpg"
if not os.path.exists(path_2):
os.mkdir(path_2)
print("Directory '% s' created" % new_name)
cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
# To store unrecognised faces of known people
else:
cv2.imwrite(os.path.join(path_2,FaceFileName),sub_face)
Code works perfectly fine!
Related
I am currently building a Real time face recognition system which I intend on testing for my security system at home. I am using the Haar Cascade approach and would like the system to either identify the individuals who have been spotted by the cameras (the peoples name are in the array) or to give us an unknown label.
Code
# iniciate id counter
userID = 0
# names related to Userids:
names = ['Mike', 'Yakub', 'Brother C', 'Brother A', 'Robert', 'William']
# Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video widht
cam.set(4, 480) # set video height
# Define min window size to be recognized bv face
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
while True:
ret,img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(int(minW), int(minH)),
)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
userID, confidence = recognizer.predict(gray[y:y + h, x:x + w])
# Check if confidence is less them 80 ==> "0" is perfect match
if confidence < 80:
userID = names[userID]
confidence = " {0}%".format(round(80 - confidence))
else:
userID = "unknown"
confidence = " {0}%".format(round(80 - confidence))
cv2.putText(img, str(userID), (x + 5, y - 5), font, 1, (255, 255, 255), 2)
cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (255, 255, 0), 1)
cv2.imshow('camera', img)
k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
if k == 27:
break
Error message:
userID = names[userID]
IndexError: list index out of range
Process finished with exit code 1
I am getting the error message "userID = names[userID] IndexError: list index out of range" even though it should not. My objective is for the box to appear with the name of the person which should be dependent on the UserID array.
I have a simple python code using OpenCV and Keras that performs some detections on frames (follow-up from my previous question here). But when I want to record and save the frames as a video using video_writer, the generated video is empty.
What is wrong in the video_writer?
#........some code
# start the webcam feed
cap = cv2.VideoCapture(1)
canvasImageOriginal = cv2.imread("fg2.png")
canvasImage = cv2.imread("fg2.png")
canvasHappy = cv2.imread("fg2happy.png")
canvasSad = cv2.imread("fg2sad.png")
x0, x1 = 330, 1290
y0, y1 = 155, 700
#=========
w=960#int(cap.get(cv2.CV_CAP_PROP_FRAME_WIDTH ))
h=540#int(cap.get(cv2.CV_CAP_PROP_FRAME_HEIGHT ))
# video recorder
fourcc = cv2.VideoWriter_fourcc(*'XVID')
video_writer = cv2.VideoWriter('output.avi', fourcc, 25.0, (w, h))
#=========
prediction_history = []
LOOKBACK = 5 # how far you want to look back
counter = 0
while True:
# Find haar cascade to draw bounding box around face
ret, frame = cap.read()
frame=cv2.flip(frame,3)
if not ret:
break
facecasc = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = facecasc.detectMultiScale(gray,scaleFactor=1.3, minNeighbors=5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y-50), (x+w, y+h+10), (255, 0, 0), 2)
roi_gray = gray[y:y + h, x:x + w]
cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray, (48, 48)), -1), 0)
prediction = model.predict(cropped_img)
maxindex = int(np.argmax(prediction))
text = emotion_dict[maxindex]
print(prediction[0][3])
prediction_history.append(maxindex)
most_common_index = max(set(prediction_history[-LOOKBACK:][::-1]), key = prediction_history.count)
text = emotion_dict[most_common_index]
#if ("Sad" in text) or ("Angry" in text) or ("Disgusted" in text):
# text = "Sad"
if ("Happy" in text) or ("Sad" in text) :
cv2.putText(frame, text, (x+20, y-60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
if ("Happy" in text):
counter= counter+1
if counter == 10:
#print("Happy!")
canvasImage = canvasHappy
else:
counter = 0
canvasImage = canvasImageOriginal
dim = (800,480)
frame_shrunk = cv2.resize(frame, (x1 - x0, y1 - y0))
canvasImage[y0:y1, x0:x1] = frame_shrunk
#cv2.imshow('Video', cv2.resize(frame,dim,interpolation = cv2.INTER_CUBIC))
cv2.imshow('Demo', canvasImage)
video_writer.write(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
video_writer.release()
cv2.destroyAllWindows()
As it is mentioned above, please check print(frame.shape).
When I did it, I saw (300,450,3), and I changed the resolution of videowriter as (450,300) and it worked for me. As a result, I can say that frame.shape=(y, x, maybe color) but the resolution of videowriter=(x,y).
I want to write my detected images with caffe pre-trained model in openCV and it works with jpg or other similar formats but it's showing an error
SystemError: <built-in function imwrite> returned NULL without setting an error
and here is my code
import os
import cv2
import numpy
from imutils import paths
# DIR_PATH = os.path.dirname(os.path.realpath('dataset/'))
DIR_PATH = (list(paths.list_images('dataset')))
print(DIR_PATH)
if not os.path.exists('Output'):
os.makedirs('Output')
MODEL = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'weights.caffemodel')
# print(DIR_PATH)
for file in DIR_PATH:
filename, file_extension = os.path.splitext(file)
if (file_extension in ['.png', '.jpg', '.pgm', '.jpeg']):
image = cv2.imread(file)
(h, w) = image.shape[:2]
print("Proccess one started ")
blob = cv2.dnn.blobFromImage(cv2.resize(
image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123, 0))
MODEL.setInput(blob)
detections = MODEL.forward()
print("Proccess Two started ")
COUNT = 0
for i in range(0, detections.shape[2]):
box = detections[0, 0, i, 3:7] * numpy.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
confidence = detections[0, 0, i, 2]
if confidence > 0.165:
cv2.rectangle(image, (startX, startY),
(endX, endY), (0, 255, 0), 2)
COUNT = COUNT + 1
export_name = filename.split("\\")
print(export_name)
if file_extension == '.pgm' :
cv2.imwrite('Output/'+export_name[1]+export_name[2], image, 0)
else:
cv2.imwrite('Output/'+export_name[1]+file_extension, image)
print("Face detection complete for image " +
file + " (" + str(COUNT) + ") faces found!")
and also I've checked my values.
images with PGM format has been loading but and detecting faces but the number of faces is too much and it's not writing at all with cv2.imwrite
here is the exact problem
if file_extension == '.pgm' :
cv2.imwrite('Output/'+export_name[1]+export_name[2], image, 0)
else:
cv2.imwrite('Output/'+export_name[1]+file_extension, image)
OpenCV does not read paths in OS paths or PathLib formats, it reads a string so change your code to:
if file_extension == '.pgm':
fname = 'Output/{}{}'.format(export_name[1],export_name[2])
cv2.imwrite(fname, image, 0)
else:
fname = 'Output/{}{}'.format(export_name[1],file_extension)
cv2.imwrite(fname, image)
I am working with a face recognition using OpenCV in python. I want to close this window then open another window when the cam recognized a user. (Nevermind the opening of the window, i already did that) If I just open the another window, it loops and shows plenty of windows. I did search in the internet but no luck. Can someone help me? Here is my code:
import cv2, sys, numpy, os
size = 1
fn_haar = 'data/haarcascade_frontalface_alt.xml'
fn_dir = 'userface'
print('Loading..')
(images, lables, names, img_id) = ([], [], {}, 0)
for (subdirs, dirs, files) in os.walk(fn_dir):
for subdir in dirs:
names[img_id] = subdir
subjectpath = os.path.join(fn_dir, subdir)
for filename in os.listdir(subjectpath):
f_name, f_extension = os.path.splitext(filename)
if (f_extension.lower() not in ['.png','.jpg','.jpeg','.gif','.pgm']):
print("Skipping "+filename+", wrong file type")
continue
path = subjectpath + "/" + filename
lable = img_id
images.append(cv2.imread(path, 0))
lables.append(int(lable))
img_id += 1
(im_width, im_height) = (112, 92)
(images, lables) = [numpy.array(lis) for lis in [images, lables]]
model = cv2.face.FisherFaceRecognizer_create()
model.train(images, lables)
webcam = cv2.VideoCapture(0)
classifier = cv2.CascadeClassifier(fn_haar)
while(True):
rval = False
while(not rval):
(rval, frame) = webcam.read()
if (not rval):
print("Failed to open webcam, Trying again...")
frame = cv2.flip(frame, 1, 0)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
mini = cv2.resize(frame, (int(frame.shape[1] / size), int(frame.shape[0] /
size)))
faces = classifier.detectMultiScale(mini)
for i in range(len(faces)):
face_i = faces[i]
(x, y, w, h) = [v * size for v in face_i]
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (im_width, im_height))
prediction = model.predict(face_resize)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
if prediction[1]<2300:
cv2.putText(frame, '%s - %.0f' % (names[prediction[0]], prediction[1]),
(x-10, y-10), cv2.FONT_HERSHEY_PLAIN,1,(0, 255, 0))
else:
cv2.putText(frame, 'Unknown', (x-10, y-10), cv2.FONT_HERSHEY_PLAIN,1,(0,
255, 0))
cv2.imshow("Login using Face Recognition", frame)
key = cv2.waitKey(10)
if (key == 27):
break
Im pretty sure you need to create a named window so then you can specifically close that window itself.
You can then destroy the windows when you don't need them anymore:
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Depends on how you use cv2.namedWindow and cv2.imshow.
It could slow down your application if you are using a different winname every time as you would be creating new windows.
I would suggest to just use cv.imshow and modify your code to have a variable that creates a unique title for the current window.
win_name = 'Login using Face Recognition: '
success_count = 0
while(True):
# ... your recognition logic that would set `recognized`
recognized = True
if recognized:
cv2.destroyWindow(win_name + str(success_count))
success_count += 1
cv2.imshow(win_name + str(success_count), frame)
key = cv2.waitKey(10)
if (key == 27):
break
Is there any way i can make my own train set for face recognition in python ? To be more specific i want to make a train set like an AT&T Face database. I want my camera to take 20 images of each person(30 max) and store it in the separate folders by the name of each person.
import cv2, sys, numpy, os
size = 4
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'att_faces'
fn_name = sys.argv[1]
path = os.path.join(fn_dir, fn_name)
if not os.path.isdir(path):
os.mkdir(path)
(im_width, im_height) = (112, 92)
haar_cascade = cv2.CascadeClassifier(fn_haar)
webcam = cv2.VideoCapture(0)
# The program loops until it has 20 images of the face.
count = 0
while count < 20:
(rval, im) = webcam.read()
im = cv2.flip(im, 1, 0)
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
mini = cv2.resize(gray, (gray.shape[1] / size, gray.shape[0] / size))
faces = haar_cascade.detectMultiScale(mini)
faces = sorted(faces, key=lambda x: x[3])
if faces:
face_i = faces[0]
(x, y, w, h) = [v * size for v in face_i]
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (im_width, im_height))
pin=sorted([int(n[:n.find('.')]) for n in os.listdir(path)
if n[0]!='.' ]+[0])[-1] + 1
cv2.imwrite('%s/%s.png' % (path, pin), face_resize)
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.putText(im, fn_name, (x - 10, y - 10), cv2.FONT_HERSHEY_PLAIN,
1,(0, 255, 0))
count += 1
cv2.imshow('OpenCV', im)
key = cv2.waitKey(10)
if key == 27:
break
For this, you just need to provide a particular path to save all the image with (.png) or (.bmp) or (.jpg) extension in a sorted manner.
# train.py
import cv2, sys, numpy, os
size = 4
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'face_data'
fn_name = sys.argv[0]
path = os.path.join(fn_dir, fn_name)
(im_width, im_height) = (112, 92)
haar_cascade = cv2.CascadeClassifier(fn_haar)
webcam = cv2.VideoCapture(0)
# Generate name for image file
pin=sorted([int(n[:n.find('.')]) for n in os.listdir(path)
if n[0]!='.' ]+[0])[-1] + 1
# Beginning message
print("\n\033[94mThe program will save 20 samples. \
Move your head around to increase while it runs.\033[0m\n")
# The program loops until it has 20 images of the face.
count = 0
pause = 0
count_max = 20
while count < count_max:
# Loop until the camera is working
rval = False
while(not rval):
# Put the image from the webcam into 'frame'
(rval, frame) = webcam.read()
if(not rval):
print("Failed to open webcam. Trying again...")
# Get image size
height, width, channels = frame.shape
# Flip frame
frame = cv2.flip(frame, 1, 0)
# Convert to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Scale down for speed
mini = cv2.resize(gray, (int(gray.shape[1] / size), int(gray.shape[0] / size)))
# Detect faces
faces = haar_cascade.detectMultiScale(mini)
# We only consider largest face
faces = sorted(faces, key=lambda x: x[3])
if faces:
face_i = faces[0]
(x, y, w, h) = [v * size for v in face_i]
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (im_width, im_height))
# Draw rectangle and write name
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.putText(frame, fn_name, (x - 10, y - 10), cv2.FONT_HERSHEY_PLAIN,
1,(0, 255, 0))
# Remove false positives
if(w * 6 < width or h * 6 < height):
print("Face too small")
else:
# To create diversity, only save every fith detected image
if(pause == 0):
print("Saving training sample "+str(count+1)+"/"+str(count_max))
# Save image file
cv2.imwrite('%s/%s.png' % (path, pin), face_resize)
pin += 1
count += 1
pause = 1
if(pause > 0):
pause = (pause + 1) % 5
cv2.imshow('OpenCV', frame)
key = cv2.waitKey(10)
if key == 27:
break
This code will help you to get the cropped images from the webcam and store them in a directory name as face_data for training purpose.
In case, you don't want to train your dataset from webcam, you can simply do one thing:
that just create a directory and create 5-6 sub-directory in it as in Happy, Sad, Angry, Neutral, Calm, etc.
Download the images and put them in corresponding folders for training purpose, now follow this code.
## This program first ensures if the face of a person exists in the given image or
not then if it exists, it crops
## the image of the face and saves to the given directory.
## Importing Modules
import cv2
import os
directory = "C:\\Users\\hp"
## directory where the images to be saved:
f_directory = "C:\\Users\\hp\\face_data/"
def facecrop(image):
## Crops the face of a person from an image!
## OpenCV XML FILE for Frontal Facial Detection using HAAR CASCADES.
facedata=
"C:\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_default.xml"
cascade = cv2.CascadeClassifier(facedata)
## Reading the given Image with OpenCV
img = cv2.imread(image)
try:
minisize = (img.shape[1],img.shape[0])
miniframe = cv2.resize(img, minisize)
faces = cascade.detectMultiScale(miniframe)
for f in faces:
x, y, w, h = [ v for v in f ]
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
sub_face = img[y:y+h, x:x+w]
f_name = image.split('/')
f_name = f_name[-1]
## Change here the Desired directory.
cv2.imwrite(f_directory + f_name, sub_face)
print ("Writing: " + image)
except:
pass
if __name__ == '__main__':
images = os.listdir(directory)
i = 0
for img in images:
file = directory + img
print (i)
facecrop(file)
i += 1