crop face from video and save as image - python

I am trying to crop a face everytime it appears in video but it does not seem to be creating the image file.
I have included an imshow line to see if there is an image being created from the bounding boxes and there is a face that gets cropped. Any help would be appreciated.
Code:
import numpy as np
import cv2
import os
detector= cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
cap = cv2.VideoCapture("smallvid.mp4")
while(True):
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector.detectMultiScale(gray, 1.3, 5)
count = 1
for (x,y,w,h) in faces:
cropped = img[ y : y+h, x : x+w ]
cv2.imwrite("cropped_face" + str(id) + ".png", cropped)
count=count+1
cv2.imshow(out_dir+str(count), cropped); # show an image of each face
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # create bounding box around face
cv2.imshow('frame',img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
enter code here

You can crop just like this.
img[y:y+w, x:x+w]

Related

Opencv face detection webcam is not saving detected faces

Im using opencv to detect faces in my webcam and whenever a face is detected I want to crop the ROI of face and save its image locally on my system. But when I run the code it doesnt do anything at all.
My webcam is working in opencv(which Ive already tested). But this specific code isnt working, for unknown reasons.
import os
import cv2
ctr=0
# import face detection cascade
face_cascade = cv2.CascadeClassifier('/home/opi/opencv-3.3.0/data/haarcascades/haarcascade_frontalface_default.xml')
# create capture object
cap = cv2.VideoCapture(0)
while(True):
# capture frame-by-frame
ret, img = cap.read()
# convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(img, 1.3, 5)
# for each face draw a rectangle around and copy the face
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_color = img[y:y+h, x:x+w]
roi_gray = gray[y:y+h, x:x+w]
#SAVE THE DETECTED FACES LOCALLY
roi_gray=cv2.resize(roi_gray,(100,100))
cv2.imwrite('faces'+'/'+str(ctr)+'.jpg',roi_gray)
ctr+=1
# display the resulting frame
cv2.imshow('frame',img)
# when everything done, release the capture
cap.release()
cv2.destroyAllWindows()
When I kill the code pressing Ctrl+C, I can see this error which also doesnt make much sense :-
opi#admin:~$ python input.py
^CTraceback (most recent call last):
File "input.py", line 18, in <module>
faces = face_cascade.detectMultiScale(img, 1.3, 5)
KeyboardInterrupt
You have forgotten to add cv2.waitKey(1) and that is why your code crashes while it is in an infinite loop ( while True: ... ). We can also say that there is no time for showing(refreshing) frames ...
Add this block of code:
# display the resulting frame
cv2.imshow('frame',img)
key = cv2.waitKey(1)
if key == 32: # if the space key is pressed
break
The final code :
import os
import cv2
ctr=0
# import face detection cascade
face_cascade = cv2.CascadeClassifier('/home/opi/opencv-3.3.0/data/haarcascades/haarcascade_frontalface_default.xml')
# create capture object
cap = cv2.VideoCapture(0)
while True:
# capture frame-by-frame
ret, img = cap.read()
# convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(img, 1.3, 5)
# for each face draw a rectangle around and copy the face
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_color = img[y:y+h, x:x+w]
roi_gray = gray[y:y+h, x:x+w]
#SAVE THE DETECTED FACES LOCALLY
roi_gray=cv2.resize(roi_gray,(100,100))
cv2.imwrite('faces'+'/'+str(ctr)+'.jpg',roi_gray)
ctr+=1
# display the resulting frame
cv2.imshow('frame',img)
key = cv2.waitKey(1)
if key == 32: # if space key is pressed
break
# when everything done, release the capture
cap.release()
cv2.destroyAllWindows()

webcam image distorted in python

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

Opencv (in python) gives error - !_src.empty() in function 'cv2::cvtColor '

I'm currently trying to run a simple python program to detect face and eyes.
I downloaded the appropriate classifiers and they're in the same directory. I even checked my camera settings and it's set to on with permission to python. Any ideas how to solve this?
import cv2
import numpy as np
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
cap = cv2.VideoCapture(0)
while True:
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectange(img, (x,y), (x+w, y+h), (255,0,0), 2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,ehh) in eyes:
cv2.rectangle(roi_color, (ex,ey), (ex+ew,ey+eh), (0,255,0), 2)
cv2.imshow('img',img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
Why does this OpenCV program give the error:
My camera settings show that python is using it:
Thank you!
!_src.empty() means you have an empty frame
You can check the frame to make sure you actually get the image:
ret, img = cap.read()
if img is not None:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else: < implement how you want to deal with empty frame >

Capturing Screenshot in When when Face is detected

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

auto detect face and take a snapshot with opencv

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

Categories

Resources