I have done tons of research into this , and I think my logic are worn out , almost there but can't seem to understand why nothing is display in the cv2.imshow() windows just a grey box , however good news is I am able to detect a face and crop that face then save it in the folder.
can you please shed some light of where I have gone wrong
#Author: Waheed Rafiq
#Research Student Birmingham City University
#Date: 03/11/2016
#Description :detect and Save capture face in a folder.
#Import library required for Capture face.
import cv2
#import the cascade for face detection
FaceClassifier =cv2.CascadeClassifier
('haarcascade_frontalface_default.xml')
# access the webcam (every webcam has
capture = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = capture.read()
if not capture:
print "Error opening webcam device"
sys.exit(1)
# to detect faces in video
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = FaceClassifier.detectMultiScale(gray, 1.3, 5)
# Resize Image
minisize = (frame.shape[1],frame.shape[0])
miniframe = cv2.resize(frame, minisize)
# Store detected frames in variable name faces
faces = FaceClassifier.detectMultiScale(miniframe)
# Draw rectangle
for f in faces:
x, y, w, h = [ v for v in f ]
cv2.rectangle(frame, (x,y), (x+w,y+h), (255,255,255))
#Save just the rectangle faces in SubRecFaces
sub_face = frame[y:y+h, x:x+w]
FaceFileName = "unknowfaces/face_" + str(y) + ".jpg"
cv2.imwrite(FaceFileName, sub_face)
#Display the image
cv2.imshow('Result',frame)
break
# When everything done, release the capture
img.release()
cv2.waitKey(20)
cv2.destroyAllWindows()
really would appericate your support
I had to revamp my code , and re-think the logics again: for those of you who wish to know how to detect a face from webcam or Raspberry PI using Opencv and then crop that detected face this is how you do it in python 2.7 using OpenCV 2.4.12
# croppfacedetection.py
#Author: Waheed Rafiq
#Research Student Birmingham City University
#Date: 03/11/2016
#Description : Save capture face in a folder.
#Import library required for Capture face.
# Should you wish to use this code for
#education purpose in your assignment or dissertation
# please use the correct citation and give credit where required.
import cv2
size = 4
webcam = cv2.VideoCapture(0) #Use camera 0
# We load the xml file
classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Above line normalTest
#classifier = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
#Above line test with different calulation
#classifier = cv2.CascadeClassifier('haarcascade_frontalface_alt_tree.xml')
#classifier = cv2.CascadeClassifier('lbpcascade_frontalface.xml')
while True:
(rval, im) = webcam.read()
im=cv2.flip(im,1,0) #Flip to act as a mirror
# Resize the image to speed up detection
mini = cv2.resize(im, (im.shape[1] / size, im.shape[0] / size))
# detect MultiScale / faces
faces = classifier.detectMultiScale(mini)
# Draw rectangles around each face
for f in faces:
(x, y, w, h) = [v * size for v in f] #Scale the shapesize backup
cv2.rectangle(im, (x, y), (x + w, y + h),(0,255,0),thickness=4)
#Save just the rectangle faces in SubRecFaces
sub_face = im[y:y+h, x:x+w]
FaceFileName = "unknowfaces/face_" + str(y) + ".jpg"
cv2.imwrite(FaceFileName, sub_face)
# Show the image
cv2.imshow('BCU Research by Waheed Rafiq (c)', im)
key = cv2.waitKey(10)
# if Esc key is press then break out of the loop
if key == 27: #The Esc key
break
remember you will need to create a folder and within that area you will need a folder named unknownfaces run the script from root of the folder and it should save any faces it detects into unknowfaces folder.
further information about this code will be available soon my site
waheedrafiq.net
It's the 'working' version of the code with Python 3.6 OpenCV 4+. You don't have to refer anyone, use it freely.
import cv2
import os
classifier = cv2.CascadeClassifier(cv2.data.haarcascades+"haarcascade_frontalface_default.xml")
dirFace = 'cropped_face'
# Create if there is no cropped face directory
if not os.path.exists(dirFace):
os.mkdir(dirFace)
print("Directory " , dirFace , " Created ")
else:
print("Directory " , dirFace , " has found.")
webcam = cv2.VideoCapture(0) # Camera 0 according to USB port
# video = cv2.VideoCapture(r"use full windows path") # video path
while (True):
(f, im) = webcam.read() # f returns only True, False according to video access
# (f, im) = video.read() # video
if f != True:
break
# im=cv2.flip(im,1,0) #if you would like to give mirror effect
# detectfaces
faces = classifier.detectMultiScale(
im, # stream
scaleFactor=1.10, # change these parameters to improve your video processing performance
minNeighbors=20,
minSize=(30, 30) # min image detection size
)
# Draw rectangles around each face
for (x, y, w, h) in faces:
cv2.rectangle(im, (x, y), (x + w, y + h),(0,0,255),thickness=2)
# saving faces according to detected coordinates
sub_face = im[y:y+h, x:x+w]
FaceFileName = "cropped_face/face_" + str(y+x) + ".jpg" # folder path and random name image
cv2.imwrite(FaceFileName, sub_face)
# Video Window
cv2.imshow('Video Stream',im)
key = cv2.waitKey(1) & 0xFF
# q for exit
if key == ord('q'):
break
webcam.release()
It looks like cv2.waitKey(20) is not reached by your code. You should move it before the break statement.
In OpenCV cv2.waitKey completes the image display task. It is not just for adding a pause.
Related
I am trying to run this OpenCV code to detect faces with my video camera. It's giving me this error whenever I run my code. The light on my video camera blinks but then shuts down with this error in the console box along with this one cv2.error: OpenCV(4.5.1) error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'
Here's the code
# Load the cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# To capture video from webcam.
cap = cv2.VideoCapture(0)
# To use a video file as input
# cap = cv2.VideoCapture('filename.mp4')
while True:
# Read the frame
_, img = cap.read()
# Convert to grayscale
#THIS IS THE ERROR AREA
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect the faces
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
# Draw the rectangle around each face
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
# Display
cv2.imshow('img', img)
# Stop if escape key is pressed
k = cv2.waitKey(30) & 0xff
if k == 27:
break
# Release the VideoCapture object
cap.release()
It seems your script is not able to find the haarcascade_frontalface_default.xml file properly because of relative path. Try to give an absolute path and check.
This is a facial recognition app I had created using python , opencv and haar cascade classifier, the app is working good in classifying trained persons, however the app has a problem of detecting unknown persons as a known person who is trained previously , How to fix such problem ?
this is the dataset creation code
import cv2
import os
import time
cam = cv2.VideoCapture(0)
cam.set(3, 640) # set video width
cam.set(4, 480) # set video height
face_detector = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')
# For each person, enter one numeric face id
face_id = input('\n enter user id end press <return> ==> ')
print("\n [INFO] Initializing face capture. Look the camera and wait ...")
# Initialize individual sampling face count
count = 0
while(True):
ret, img = cam.read()
img = cv2.flip(img, 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale(gray, 1.3, 5)
width_d, height_d = 150, 150
for (x,y,w,h) in faces:
cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
count += 1
# Save the captured image into the datasets folder
cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", cv2.resize(gray[y:y+h,x:x+w] , (width_d, height_d)))
cv2.imshow('image', img)
k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
if k == 27:
break
elif count >= 400: # Take 30 face sample and stop video
break
# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
This is the training phase
import cv2
import numpy as np
from PIL import Image
import os
# Path for face image database
path = 'dataset'
recognizer = cv2.face.LBPHFaceRecognizer_create()
detector = cv2.CascadeClassifier("Cascades/haarcascade_frontalface_default.xml");
# function to get the images and label data
def getImagesAndLabels(path):
width_d, height_d = 150, 150 # Declare your own width and height
imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
faceSamples=[]
ids = []
for imagePath in imagePaths:
PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
img_numpy = np.array(PIL_img,'uint8')
id = int(os.path.split(imagePath)[-1].split(".")[1])
faces = detector.detectMultiScale(img_numpy)
for (x,y,w,h) in faces:
faceSamples.append(cv2.resize(img_numpy[y:y+h,x:x+w], (width_d, height_d)))
ids.append(id)
return faceSamples,ids
print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
faces,ids = getImagesAndLabels(path)
recognizer.train(faces, np.array(ids))
# Save the model into trainer/trainer.yml
recognizer.write('trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi
# Print the numer of faces trained and end program
print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))
This is the recognizing phase
import cv2
import numpy as np
import os
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "Cascades/haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
font = cv2.FONT_HERSHEY_SIMPLEX
#iniciate id counter
id =0
# names related to ids: example ==> Marcelo: id=1, etc
names = ['Mamdouh Alaa' , 'Dr.Ahmed Seddawy' , 'Dr.Ismail Abdulghaffar']
# Initialize and start realtime video capture
cam = cv2.VideoCapture(0)
cam.set(3, 1366) # set video widht
cam.set(4, 768) # set video height[enter image description here][1]
# Define min window size to be recognized as a face
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
while True:
ret, img =cam.read()
img = cv2.flip(img, 1)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
width_d, height_d = 150, 150
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), (255,0,0), 2)
id, confidence = recognizer.predict(cv2.resize(gray[y:y+h,x:x+w], (width_d, height_d)))
# Check if confidence is less them 100 ==> "0" is perfect match
if (confidence < 100) :
id = names[id]
confidence = " {0}%".format(round(100 - confidence))
else:
id = "unknown person"
confidence = " {0}%".format(round(100 - confidence))
cv2.putText(img, str(id), (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('IFR',img)
k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
if k == 27:
break
# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
I am working on a face detection use case and want to print a message when the face is not detected in the frame, and draw the bounding box when the face is detected. I am using open-cv for the same
Here is my code so far, please let me know what changes need to be made.
import cv2
cascPath = 'haarcascade_frontalface_dataset.xml'
faceCascade = cv2.CascadeClassifier(cascPath)
video_capture = cv2.VideoCapture(0)
while True :
_, frame = video_capture.read(0)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# cv2.imshow("face detection", frame)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
if w == 0:
cv2.putText(frame,'No face',(0,130), font, 1, (200,255,155))
else:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Display the resulting frame in browser
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
I figured out the solution, go through it if you want to have a look , just add this if statement before for loop, it writes no face in the window if no face is detected
if len(faces) == 0:
cv2.putText(frame,'No face',(0,130), 4,1, (200,255,155))
This guide in geeksforgeeks can help you. Also you can follow link on tproger, so I recommend to use google transltator.
https://www.geeksforgeeks.org/python-opencv-cv2-puttext-method/
https://tproger.ru/translations/opencv-python-guide/#text
Using Opencv to make a face recognition
This is the code I am using to recognize faces in my webcam, but once the camera do not recognize a face, it is stopping to record and I want it countinuous.
import cv2
import logging as log
from time import sleep
import datetime as dt
import numpy as np
cascPath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)
cam = cv2.VideoCapture(0);
anterior = 0
log.basicConfig(filename='webcam.log',level=log.INFO)
rec = cv2.face.LBPHFaceRecognizer_create();
rec.read('recognizer/trainningData.yml')
id=0
font = cv2.FONT_HERSHEY_SIMPLEX
fontscale = 1
fontcolor = (255,255,255)
while(True):
if not cam.isOpened():
print('Unable to load camera.')
sleep(5)
pass
ret, img = cam.read();
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1,minNeighbors=5,minSize=(30, 30))
for(x, y, w, h) in faces:
cv2.rectangle(img, (x,y), (x+w, y+h), (0,255,0),2)
id, conf = rec.predict(gray[y:y+h,x:x+w])
if(id == 1):
id = "Nome do usuário detectado";
cv2.putText(img,str(id),(x,y-10),font,0.55,(0,255,0),1);
cv2.imshow("Face", img);
if(conf<=20):
if(id!=None):
cv2.putText(img,str(id),(x,y-10),font,0.55,(0,255,0),1);
else:
cv2.putText(img,"Unknown",(x,y+h-10),font,0.55, (0,255,0),1);
if anterior != len(faces):
anterior = len(faces)
log.info("ID: " + str(id) + " faces: "+str(len(faces))+" at "+str(dt.datetime.now()))
if(cv2.waitKey(1)==ord('q')):
break;
cam.release()
cv2.destroyAllWindows()
Look at your code closely...you're calling imshow() method, which is responsible for showing the image, inside the for loop that is processing the detected faces.
This means that if faces are not detected, then that for loop is not executed, and thus imshow() is not called.
If you want to show the image regardless of detection result, move imshow() call to the while loop
i'm working on face recognition project with my college. what i'm trying to take a snapshot and save it if the face is detected automatically before closing the webcam.
what I have now is open cam and wait if face is detected and press "q" to take snapshot and save the image.
Here is the code:
import numpy as np
import cv2
import time
#import the cascade for face detection
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
def TakeSnapshotAndSave():
# access the webcam (every webcam has a number, the default is 0)
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# to detect faces in video
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
x = 0
y = 20
text_color = (0,255,0)
# write on the live stream video
cv2.putText(frame, "Press q when ready", (x,y), cv2.FONT_HERSHEY_PLAIN, 1.0, text_color, thickness=2)
# if you want to convert it to gray uncomment and display gray not fame
#gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',frame)
# press the letter "q" to save the picture
if cv2.waitKey(1) & 0xFF == ord('q'):
# write the captured image with this name
cv2.imwrite('try.jpg',frame)
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
TakeSnapshotAndSave()
thank you in advance
I adapted your code to save 10 images just for testing, if you want infinite photos, just change the while condition. So in your code you were overwriting the current image so I changed the string parameter so that it was possible to take lots of pictures.
import numpy as np
import cv2
import time
#import the cascade for face detection
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
def TakeSnapshotAndSave():
# access the webcam (every webcam has a number, the default is 0)
cap = cv2.VideoCapture(0)
num = 0
while num<10:
# Capture frame-by-frame
ret, frame = cap.read()
# to detect faces in video
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
x = 0
y = 20
text_color = (0,255,0)
cv2.imwrite('opencv'+str(num)+'.jpg',frame)
num = num+1
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
TakeSnapshotAndSave()
Perform imwrite() in the for (x,y,w,h) in faces: loop itself. If you use a constant filename, your last detected face will be saved and the rest will be overwritten