Print only once in a live detection model - python

import cv2
from tensorflow.keras.preprocessing.image import img_to_array
import os
import numpy as np
from tensorflow.keras.models import model_from_json
root_dir = os.getcwd()
# Load Face Detection Model
face_cascade = cv2.CascadeClassifier("models/haarcascade_frontalface_default.xml")
# Load Anti-Spoofing Model graph
json_file = open('antispoofing_models/finalyearproject_antispoofing_model_mobilenet.json','r')
loaded_model_json = json_file.read()
json_file.close()
model = model_from_json(loaded_model_json)
# load antispoofing model weights
model.load_weights('antispoofing_models/finalyearproject_antispoofing_model_99-0.976842.h5')
print("Model loaded from disk")
# video.open("http://192.168.1.101:8080/video")
# vs = VideoStream(src=0).start()
# time.sleep(2.0)
video = cv2.VideoCapture(0)
while True:
try:
ret,frame = video.read()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.3,5)
for (x,y,w,h) in faces:
face = frame[y-5:y+h+5,x-5:x+w+5]
resized_face = cv2.resize(face,(160,160))
resized_face = resized_face.astype("float") / 255.0
# resized_face = img_to_array(resized_face)
resized_face = np.expand_dims(resized_face, axis=0)
# pass the face ROI through the trained liveness detector
# model to determine if the face is "real" or "fake"
preds = model.predict(resized_face)[0]
# print(preds)
if preds> 0.45:
label = 'spoof'
cv2.putText(frame, label, (x,y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255), 2)
cv2.rectangle(frame, (x, y), (x+w,y+h),
(0, 0, 255), 2)
print("SPOOFED FACE DETECTED")
break
else:
label = 'real'
cv2.putText(frame, label, (x,y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.rectangle(frame, (x, y), (x+w,y+h),
(0, 255, 0), 2)
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
except Exception as e:
pass
video.release()
cv2.destroyAllWindows()
The above code detects the real and spoofed faces but I want to print("SPOOFED FACE DETECTED") only once in 1 min when the preds> 0.45 but it prints it continuously.
how to add a time delay that after every 1 min on detecting spoofed face, it should print("SPOOFED FACE DETECTED") but the program will keep on executing.

It will print if preds> 0.45 while the while loop is running. If you want to print once every one minute without interrupting the while loop then you'll need to use a timer and adjust your condition.
I'm not familiar with the openCV library, so I'm not sure if there's a better way to track the elapsed time of the capture. But, using the included python time library, you could do something like
while True:
start = time.time() # CHANGE start time counter
delta = 60
try:
ret,frame = video.read()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.3,5)
for (x,y,w,h) in faces:
face = frame[y-5:y+h+5,x-5:x+w+5]
resized_face = cv2.resize(face,(160,160))
resized_face = resized_face.astype("float") / 255.0
# resized_face = img_to_array(resized_face)
resized_face = np.expand_dims(resized_face, axis=0)
# pass the face ROI through the trained liveness detector
# model to determine if the face is "real" or "fake"
preds = model.predict(resized_face)[0]
# print(preds)
if preds> 0.45: # CHANGE; compute delta and compare with threshold
label = 'spoof'
cv2.putText(frame, label, (x,y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255), 2)
cv2.rectangle(frame, (x, y), (x+w,y+h),
(0, 0, 255), 2)
if (time.time() - start) >= delta:
print("SPOOFED FACE DETECTED")
start = time.time()
break
else:
label = 'real'
cv2.putText(frame, label, (x,y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.rectangle(frame, (x, y), (x+w,y+h),
(0, 255, 0), 2)
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
except Exception as e:
pass
video.release()
cv2.destroyAllWindows()
I've omitted the bits outside the loop , and marked the changes for readibility

Related

cv2.findcontours returning none in Motion Detector App

I followed a video online about motion detection using openCV however I came across the problem that the findContours function is not returning a value. Any help is appreceated.
Here is the code:
import cv2
import time
import datetime
import imutils
def motion_detection():
video_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
time.sleep(2)
first_frame = None
while True:
frame = video_capture.read()[1]
text = 'Unoccupied'
greyscale_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gaussian_frame = cv2.GaussianBlur(greyscale_frame, (21, 21), 0)
blur_frame = cv2.blur(gaussian_frame, (5, 5))
greyscale_image = blur_frame
if first_frame is None:
first_frame = greyscale_image
else:
pass
frame = imutils.resize(frame, width=500)
frame_delta = cv2.absdiff(first_frame, greyscale_image)
# edit the ** thresh ** depending on the light/dark in room,
# change the 100(anything pixel value over 100 will become 255(white)
thresh = cv2.threshold(frame_delta, 100, 255, cv2.THRESH_BINARY)[1]
dilate_image = cv2.dilate(thresh, None, iterations=2)
cnt = cv2.findContours(dilate_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
for c in cnt:
if cv2.contourArea(c) > 800:
(x, y, w, h) = cv2.boundingRect(
c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = 'Occupied'
# text that appears when there is motion in video feed
else:
pass
''' now draw text and timestamp on security feed '''
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, '{+} Room Status: %s' % text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, datetime.datetime.now().strftime('%A %d %B %Y %I:%M:%S%p'),
(10, frame.shape[0] - 10), font, 0.35, (0, 0, 255), 1)
cv2.imshow('Security Feed', frame)
cv2.imshow('Threshold(foreground mask)', dilate_image)
cv2.imshow('Frame_delta', frame_delta)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
cv2.destroyAllWindows()
break
if __name__ == '__main__':
motion_detection()
I have tried to debug and find the problem the code is exactly what the video said to write and I have had no luck.

it is possible to create a real time face recognition with openCV and Face-recognition library?

I am trying to build a face recognition in Python
at first I build a face detection with openCV and using documentation example in Face-Recognition library I did that
and right now im trying to merge those two library and I get an error
heres are my example code im trying build
import cv2
import pathlib
import face_recognition
casface = pathlib.Path(cv2.__file__).parent.absolute() / "data/haarcascade_frontalface_default.xml"
clf = cv2.CascadeClassifier(str(casface))
video = cv2.VideoCapture(0)
picture_of_me = face_recognition.load_image_file("images/art.jpg") # my image location
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
while True:
suc, img = video.read()
frame = cv2.flip(img, 1) # Flip camera vertically
vds_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
small_frame = cv2.resize(img,(0,0), fx=0.25,fy=0.25)
# smalller_fram = small_frame[:,:,::-1]
face_detect = clf.detectMultiScale(
vds_gray,
scaleFactor=1.2,
minNeighbors=1,
minSize=(30,30),
)
# the faces detected on my webcam and encode it on facerecognition
face_locas = face_recognition.face_locations(small_frame)
face_ecnod = face_recognition.face_encodings(face_locas)[0]
try:
# comparing my image and webcam
results = face_recognition.compare_faces([my_face_encoding], face_ecnod)
if results[0]:
for (x,y,w,h) in face_detect:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 1)
cv2.putText(
frame,
'it is me!',
(x,y+h + 30),
cv2.FONT_HERSHEY_PLAIN,
2,
(0,255,0),
2,
cv2.LINE_AA
)
else:
print("It's not a picture of me!")
for (x,y,w,h) in face_detect:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 1)
cv2.putText(
frame,
'hindi',
(x,y+h + 30),
cv2.FONT_HERSHEY_PLAIN,
2,
(0,255,0),
2,
cv2.LINE_AA
)
except IndexError as e:
print(e)
cv2.imshow('frame',frame)
k = cv2.waitKey(30) & 0xff
if k == 27: # press 'ESC' to quit
break
video.release()
cv2.destroyAllWindows()
im beginner and 4th year college student is there any recommendation such as library i use ? i mean there is no training data
I tried to look up
Pytorch
tensorFlow
keras
packages but it kind of hard for me to understand , any recommendation or website/articles for begginer to understand the facial recognition

My Code is only detecting single face only after applying For Loop also

I am trying to Detect Emotions using my model which takes images as an array, but my code is detecting faces using MTCNN in which the code is detecting only a single face, I have also applied for loop but still it is detecting single face only. Detecting Single face in Single Frame.
import keras
from keras.models import load_model
from time import sleep
from keras.preprocessing.image import img_to_array
from keras.preprocessing import image
import cv2
import numpy as np
from configs import Configs
from PIL import Image
from keras.applications.vgg16 import preprocess_input
from mtcnn.mtcnn import MTCNN
cfg = Configs()
detector = MTCNN()
model = load_model(cfg.model_path)
emotions = ['Angry', 'Disgust', 'Fear', 'Happy',
'Neutral', 'Pain', 'Sad', 'Surprise']
# Sample Video on which we have to Test
cap = cv2.VideoCapture(cfg.video_path)
while(cap.isOpened()):
ret, frame = cap.read()
faces = detector.detect_faces(frame)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if ret == False:
break
#for face in faces:
# x = faces[0]['box'][0]
# y = faces[0]['box'][1]
# w = faces[0]['box'][2]
# h = faces[0]['box'][3]
#face = x,y,w,h
for face in faces:
x = faces[0]['box'][0]
y = faces[0]['box'][1]
w = faces[0]['box'][2]
h = faces[0]['box'][3]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 255), 2)
roi_gray = gray[y:y+h, x:x+w]
roi_gray = cv2.resize(roi_gray, (48, 48), interpolation=cv2.INTER_AREA)
if np.sum([roi_gray]) != 0:
roi = roi_gray.astype('float')/255.0
roi = img_to_array(roi)
roi = np.expand_dims(roi, axis=0)
prediction = model.predict(roi)[0]
label = emotions[prediction.argmax()]
label_position = (x, y)
cv2.putText(frame, label, label_position,
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
else:
cv2.putText(frame, 'No Faces', (30, 80),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
size = cv2.resize(frame[:, :, ::1], (560, 640))
cv2.imshow('Emotion Detector', size)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()

Python CV2 video writer doesn't save video

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).

Real time face recognition ran slowly on Raspberry Pi3

I am using Raspberry Pi3 for face recognition and this is my code to detect the faces but the real time recognition ran slowly
cam = cv2.VideoCapture(0)
rec = cv2.face.LBPHFaceRecognizer_create();
rec.read(...'/data/recognizer/trainingData.yml')
getId = 0
font = cv2.FONT_HERSHEY_SIMPLEX
userId = 0
i = 0
while (cam.isOpened() and i<91):
i=i+1
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceDetect.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
getId, conf = rec.predict(gray[y:y + h, x:x + w]) # This will predict the id of the face
# print conf;
if conf < 50:
userId = getId
cv2.putText(img, "Detected", (x, y + h), font, 2, (0, 255, 0), 2)
record = Records.objects.get(id=userId)
record.is_present = True
record.save()
else:
cv2.putText(img, "Unknown", (x, y + h), font, 2, (0, 0, 255), 2)
# Printing that number below the face
# #Prams cam image, id, location,font style, color, stroke
cv2.imshow("Face", img)
cv2.waitKey(50)`
How to correct it please ? Thanks for your helping hand.
You should use threads to mazimize performance. imutils is a library that lets you use threading both on picamera and webcam capture. The issue here is that there are too many Input output operations being performed in between frames.
Here is the article that helped increase my fps:
https://www.pyimagesearch.com/2015/12/28/increasing-raspberry-pi-fps-with-python-and-opencv/
And this is the code you can add:
import imutils
from imutils.video.pivideostream import PiVideoStream
Then instead of cam = cv2.VideoCapture(0)
use cam = PiVideoStream().start()
and instead of ret, img = cam.read()
use im = cam.read()
and to release the camera use:
cam.stop()

Categories

Resources