I have following code:
import numpy as np
import cv2
import pickle
import rtsp
import PIL as Image
face_cascade = cv2.CascadeClassifier('cascades\data\haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainner.yml")
labels = {"person_name": 1}
with open("labels.pickle", 'rb') as f:
og_labels = pickle.load(f)
labels = {v:k for k,v in og_labels.items()}
url = 'rtsp://user:pass#xxx.xxx.x.xxx:YYYY/stream0/mobotix.mjpeg'
with rtsp.Client(url) as client:
client.preview()
while True:
frame = client.read(raw=True)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
for (x,y,w,h) in faces:
print(x,y,w,h)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
#recognize?
id_, conf = recognizer.predict(roi_gray)
if conf>=45: # and conf <=85:
print(id_)
print(labels[id_])
font = cv2.FONT_HERSHEY_SIMPLEX
name = labels[id_]
color = (0,0,255)
stroke = 2
cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)
#img_item = "my-image.png"
#cv2.imwrite(img_item, roi_gray)
color = (0, 0, 255)
stroke = 2
end_cord_x = x + w
end_cord_y = y + h
cv2.rectangle(frame, (x,y), (end_cord_x, end_cord_y), color, stroke)
cv2.imshow('IP cam',frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
Everything is working fine, I'm running my code and first it's opening the Cam view of "client.preview", face detection is not working at this time. When I close this one, the IPcam windows opens and everything is working. (I'm still getting a lot of missed frames by the RTSP stream but no direct issue).
If I leave the code "client.preview" out of it, I'm getting an error from opencv because of src_empty.
If I try to change the code to "client.read()" idem an error occurs from opencv because of src_empty.
How should I fix this?
Ok I understand that the RTSP protocol is first sending empty frames and building up the buffer.
with rtsp.Client(url) as client:
while True:
frame = client.read(raw=True)
if not frame:
time.sleep(.30)
else:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
for (x,y,w,h) in faces:
cv2.imshow('IP cam',frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
I deleted the line : client.preview() because of a double function.
The code is starting and after period I receive following error:
if not frame:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Before the rtsp client has received its first frame, the read call on the rtsp client will return None. When you call "client.preview" the time taken for the window to open gives the rtsp client enough time to receive the first frame from the stream before the first read is called. All calls to read beyond this will always return a frame, which is why everything works when it is included in the code. The solution to your problem would be check the result from read function of the rtsp client to ensure that you have received a frame before processing it.
import numpy as np
import cv2
import pickle
import rtsp
import PIL as Image
import time
face_cascade = cv2.CascadeClassifier('cascades\data\haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainner.yml")
labels = {"person_name": 1}
with open("labels.pickle", 'rb') as f:
og_labels = pickle.load(f)
labels = {v:k for k,v in og_labels.items()}
url = 'rtsp://user:pass#xxx.xxx.x.xxx:YYYY/stream0/mobotix.mjpeg'
with rtsp.Client(url) as client:
client.preview()
while True:
frame = client.read(raw=True)
if frame is not None:
time.sleep(.10)
else:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
for (x,y,w,h) in faces:
print(x,y,w,h)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
#recognize?
id_, conf = recognizer.predict(roi_gray)
if conf>=45: # and conf <=85:
print(id_)
print(labels[id_])
font = cv2.FONT_HERSHEY_SIMPLEX
name = labels[id_]
color = (0,0,255)
stroke = 2
cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)
#img_item = "my-image.png"
#cv2.imwrite(img_item, roi_gray)
color = (0, 0, 255)
stroke = 2
end_cord_x = x + w
end_cord_y = y + h
cv2.rectangle(frame, (x,y), (end_cord_x, end_cord_y), color, stroke)
cv2.imshow('IP cam',frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
Related
This is my code:
import numpy as np
import cv2
import pickle
face_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_frontalface_alt2.xml')
eye_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_eye.xml')
smile_cascade = cv2.CascadeClassifier('cascades/data/haarcascade_smile.xml')
[enter image description here][1]
recognizer = cv2.face.LBPHFaceRecognizer_create()
I'm getting #module 'cv2.cv2' has no attribute 'legacy' Error. How can I fix it? I'm using windows 10 and opencv 4.5.1 version. I tried to install pip install opencv_contrib_python, but it did not work.
recognizer.read("./recognizers/face-trainner.yml")
labels = {"person_name": 1}
with open("pickles/face-labels.pickle", 'rb') as f:
og_labels = pickle.load(f)
labels = {v:k for k,v in og_labels.items()}
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=5)
for (x, y, w, h) in faces:
#print(x,y,w,h)
roi_gray = gray[y:y+h, x:x+w] #(ycord_start, ycord_end)
roi_color = frame[y:y+h, x:x+w]
# recognize? deep learned model predict keras tensorflow pytorch scikit learn
id_, conf = recognizer.predict(roi_gray)
if conf>=4 and conf <= 85:
#print(5: #id_)
#print(labels[id_])
font = cv2.FONT_HERSHEY_SIMPLEX
name = labels[id_]
color = (255, 255, 255)
stroke = 2
cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)
img_item = "7.png"
cv2.imwrite(img_item, roi_color)
color = (255, 0, 0) #BGR 0-255
stroke = 2
end_cord_x = x + w
end_cord_y = y + h
cv2.rectangle(frame, (x, y), (end_cord_x, end_cord_y), color, stroke)
#subitems = smile_cascade.detectMultiScale(roi_gray)
#for (ex,ey,ew,eh) in subitems:
# cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I remember getting this error a while back.
In your CMD prompt run these three commands and then try to run your program again.
pip3 install opencv-python==4.4.0.46
pip3 install opencv-contrib-python==4.4.0.46
pip3 install opencv-contrib-python-headless==4.4.0.46
The version specifics may not be necessary but it's what worked last for me.
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
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 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.
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