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()
Related
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.
I'm working on Face recognition project in python, trying to take a snapshot of a human face from an IP cam whenever a human comes in the cam steam. Here is the code:
import numpy as np
import cv2
import time
#import the cascade for face detection
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
def TakeSnapshotAndSave():
video = cv2.VideoCapture("rtsp://user:password#0.0.0.0:553/Streaming/Channels/401")
width = 1500
height = 1080
dim = (width, height)
num = 0
while True:
_, 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:
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
frame = cv2.resize(frame, (1500, 1000))
cv2.imshow("Lodhran Camera", frame)
k = cv2.waitKey(1)
if k == ord('q'):
break
video.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
TakeSnapshotAndSave()
But it takes the image of the full frame not only the face, while I just want the only faces to be snapped and to be saved like if the frame has 5 humans in the frame at the same time, the out put will be 5 images of the faces of that 5 humans, not the full frame with all humans. Any help with the code will be appreciated, thanks in advance.
I guess you need to modify your code to make a cropped image for every facebox and then write the cropped image, not a basic frame:
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]
cropped_frame = frame[(x, y), (x + w, y + h)]
cv2.imwrite("some_name.jpg", cropped_frame)
...
I am trying to run my python programme in the Linux server but there have some problem. I am using openCV to build a fall-detection and it can run in my local computer, but when I put the python into the linux server it can't run it... Here is my code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import codecs, sys , cgi
import cv2
import time
import os
sys.stdout = codecs.getwriter('utf8')(sys.stdout.buffer)
# Start html
print('Content-type: text/html\r\n')
# Video clip
cap = cv2.VideoCapture('Testvideo.mkv')
# Webcam camera
#cap = cv2.VideoCapture(0)
print("Start Fall detection")
#time.sleep(2)
fgbg = cv2.createBackgroundSubtractorMOG2()
f = 0
j = 0
while(True):
ret, frame = cap.read()
# Convert each frame to gray scale and subtract the background
try:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = fgbg.apply(gray)
# Find contours
contours, _ = cv2.findContours(
fgmask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if contours:
# List to hold all areas
areas = []
for contour in contours:
ar = cv2.contourArea(contour)
areas.append(ar)
max_area = max(areas, default=0)
max_area_index = areas.index(max_area)
cnt = contours[max_area_index]
M = cv2.moments(cnt)
x, y, w, h = cv2.boundingRect(cnt)
cv2.drawContours(fgmask, [cnt], 0, (255, 255, 255), 3, maxLevel=0)
if h < w:
j += 1
if j > 25:
print(f"FALL !! ==> {f+1}")
f += 1
if f ==5:
print("Danger!!!")
#os.system("python send.py")
#os.system("python sms.py")
#cv2.putText(fgmask, 'FALL Detect', (x, y), cv2.FONT_HERSHEY_TRIPLEX, 0.5, (255,255,255), 2)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
if h > w:
j = 0
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('video', frame)
if cv2.waitKey(33) == 27:
break
except Exception as e:
break
cv2.destroyAllWindows()
And it only will display
Start Fall detection
in the server, Please give me some help
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 has raspberry pi 3 with raspbian jessie installed. Open CV3 and python 3.0 also installed. I get a python sample code which detect the face. I need write some text on the screen but it's not write on it. I need write text once instead of repeated on top of each faces. Below is the code
import cv2
import sys
from tkinter import *
from tkinter import messagebox
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
video_capture = cv2.VideoCapture(0)
video_capture.set(3,500)
video_capture.set(4,300)
video_capture.set(12, 0.1)
frameWidth = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH))
frameHeight = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
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:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
#cv2.putText(frame, 'How are you', (x - 1, y - 1), cv2.FONT_HERSHEY_PLAIN,2,(0, 255, 0))
#if the puttext at here, it will write the text on top of each face detected. But I just need the text appear once.
# Display the resulting frame
cv2.imshow('Video', frame)
if len(faces) > 0:
cv2.putText(img = frame, text = 'How are you', org = (int(frameWidth/2 - 20),int(frameHeight/2)), fontFace = cv2.FONT_HERSHEY_DUPLEX, fontScale = 3,
color = (0, 255, 0))
#print(int(frameWidth/2 - 20),int(frameHeight/2))
#print('Found ' + str(len(faces)) + ' face(s)')
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
You are calling imshow before putText so you'll never see the results of putText. Move the imshow statement to the line before waitKey.