i Have to make a code that caputres screenshot when a face is detected in a video so that the image can be used for image recognition dataset
i made a program that captures all frames but i need to make it capture only when a face is detected
import cv2
cap = cv2.VideoCapture('test.mp4')
count = 0
while cap.isOpened():
ret,frame = cap.read()
cv2.imshow('window-name',frame)
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.imwrite("frame%d.jpg" % count, frame)
count = count + 1
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows() # destroy all the opened windows
I just tried your code and it has 1 small mistake. You don't specify the XML classifier path correctly. I fixed the path using full path where the XML file is located and works successfully.
import cv2
import numpy as np
cap = cv2.VideoCapture('test.mp4')
#cap = cv2.VideoCapture(0) # I tried using webcam and works
count = 0
while cap.isOpened():
ret,frame = cap.read()
cv2.imshow('window-name',frame)
# Below you have to insert the full path of XML file, below is mine
face_cascade = cv2.CascadeClassifier('C:/ProgramData/Anaconda2/pkgs/opencv-3.2.0-np111py27_0/Library/etc/haarcascades/haarcascade_frontalface_default.xml')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.imwrite("frame%d.jpg" % count, frame)
count = count + 1
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows() # destroy all the opened windows
Related
when I start my program on vscode I got this error :
enter image description here
Whereas when I execute the .py the program work well. I don't understand why vscode don't run the the python file. Here is my code:
import cv2
img = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier("cascade.xml")
while(True):
ret, frame = img.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.3,4)
for (x,y,w,h) in faces:
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),3)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
import cv2
import sys
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
video_capture = cv2.VideoCapture(0)
img_counter = 0
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
k = cv2.waitKey(1)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.5,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# Display the resulting frame
cv2.imshow('FaceDetection', frame)
if k%256 == 27: #ESC Pressed
break
elif k%256 == 32:
# SPACE pressed
img_name = "facedetect_webcam_{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
after running the code in python the image of my webcam turn into this
Your code works for me without any problems.
The output image looks like there is a problem with the data type of the input image.
Something similar was discussed here:
https://answers.opencv.org/question/174027/c-ycbcr422-to-rgb-convert-from-raw-data-file/
Can you please also post your input frame grayscale image?
What camera are you using?
try add this code after video_capture.read() and post output.
print(frame.dtype)
print(frame.shape)
Mine is: dtype - uint8, shape - (480, 640, 3).
You can have a problem with the number of channels (for example RGBA) and rectangle function.
These are just my ideas of what could be wrong. But for me, your code works fine.
br Jozef
I have a face detection program.
I tried to run the code but it's not working.
import cv2
import numpy as np
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainer/trainer.yml")
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
cam = cv2.VideoCapture(0)
fontFace = cv2.FONT_HERSHEY_SIMPLEX
fontScale = 1
fontColor = (255, 255, 255)
while True:
ret, im =cam.read()
gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
faces=faceCascade.detectMultiScale(gray, 1.2,5)
for(x,y,w,h) in faces:
cv2.rectangle(im,(x,y),(x+w,y+h),(225,0,0),2)
Id, conf = recognizer.predict(gray[y:y+h,x:x+w])
if(conf<50):
if(Id==1):
Id="chandra"
elif(Id==2):
Id="vamsi"
else:
Id="Unknown"
cv2.putText(im,str(Id), (x,y+h),fontFace, 255)
cv2.imshow('im',im)
if (cv2.waitKey(10) == ord('q')):
break
cam.release()
cv2.destroyAllWindows()
I got this error:
(-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'
I'm using opencv2 and python 3.7
Maybe this will help:
try:
ret, im =cam.read()
except:
continue
Please, use this code below to check if you have any images coming from your camera:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I have a problem with saving cropped images in a loop. My code:
def run(self, image_file):
print(image_file)
cap = cv2.VideoCapture(image_file)
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
img = frame
min_h = int(max(img.shape[0] / self.min_height_dec, self.min_height_thresh))
min_w = int(max(img.shape[1] / self.min_width_dec, self.min_width_thresh))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = self.face_cascade.detectMultiScale(gray, 1.3, minNeighbors=5, minSize=(min_h, min_w))
images = []
for i, (x, y, w, h) in enumerate(faces):
images.append(self.sub_image('%s/%s-%d.jpg' % (self.tgtdir, self.basename, i + 1), img, x, y, w, h))
print('%d faces detected' % len(images))
for (x, y, w, h) in faces:
self.draw_rect(img, x, y, w, h)
# Fix in case nothing found in the image
outfile = '%s/%s.jpg' % (self.tgtdir, self.basename)
cv2.imwrite(outfile, img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
return images, outfile
I have a loop for every frame with cropping on faces. The problem is that for every cropped image and picture it gives the same name, and in the end I have faces only from the last frame. How should I fix this code to save all cropped faces and images?
You are saving each file with the same name. Hence you are overwriting previous saved images
outfile = '%s/%s.jpg' % (self.tgtdir, self.basename)
Change the line to this to add a random string in the name
outfile = '%s/%s.jpg' % (self.tgtdir, self.basename + str(uuid.uuid4()))
You will need to import uuid at the top of your file too
You may use the datetime module to get the current time with milliseconds precision, which would avoid the name conflicts, to assign the name before saving the image as:
from datetime import datetime
outfile = '%s/%s.jpg' % (self.tgtdir, self.basename + str(datetime.now()))
cv2.imwrite(outfile, img)
You can also use other techniques such as uuid4 to get unique random id for each frame, but since the name would be random it would cumbersome on some platforms to display them in sorted orders, So I think using timestamp in name would get your job done.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
i = 0
while(True):
# Capture frame-by-frame
i = i +1
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',frame)
**cv2.imwrite("template {0}.jpg".format(i),gray)**
if cv2.waitKey(0) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
--- Code by rohbhot
i think this will helpful...
import cv2
vid = cv2.VideoCapture("video.mp4")
d = 0
ret, frame = vid.read()
while ret:
ret, frame = vid.read()
filename = "images/file_%d.jpg"%d
cv2.imwrite(filename, frame)
d+=1
this will save every frame with different name.
plt.savefig('/content/drive/MyDrive/Colab Notebooks/res_data/dimers/'+str(yname)+'_'+str(xname)+'_'+str(dimername), bbox_inches='tight' )
you can save as :
/content/drive/MyDrive/Colab Notebooks/res_data/dimers/zeta_beta_GA.png
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