ageitgey / face_recognition

The world's simplest facial recognition api for Python and the command line
MIT License
53.44k stars 13.49k forks source link

Exception when trying to recognize faces using PI camera #483

Open MMavrick23 opened 6 years ago

MMavrick23 commented 6 years ago

Description

I'm trying to do face detection and recognition through the raspberry pi camera which is somehow not easy as openCV doesn't support this without special driver, however the driver slows down the FPS while I need full FPS for my project.

I used a custom module ( Videostream.zip ) to do this instead and also with higher FPS using threading (ex. cap = PiVideoStream().start()) ans this works fine with cv2, however when trying to use face recognition module it take a lot of processing to detect faces so instead I detect faces using haar cascades then pass it to face recognition to identify faces and this works just fine on imported images except when I try to use the camera instead, it gives an exception (expected writable numpy.ndarray with shape set).

What should I do ? What is the problem ?

What I Did

That's my code :-

from Videostream import PiVideoStream import face_recognition import numpy as np import time import cv2

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cap = PiVideoStream().start() time.sleep(2.0)

image = face_recognition.load_image_file("mavImg.jpg") image_encoding = face_recognition.face_encodings(image)[0]

known_face_encodings = [image_encoding] known_face_names = ["Mavrick"]

while 1: Frame = cap.read() FrameRGB = Frame[:, :, ::-1] FrameGRY = cv2.cvtColor(Frame, cv2.COLOR_BGR2GRAY)

IPers = face_cascade.detectMultiScale(FrameGRY)
if (len(IPers) != 0):
    for (x,y,w,h) in IPers:
        FrameROI = FrameRGB[y:y+h, x:x+w]
        TName = " "

         IPersE = face_recognition.face_encodings(FrameROI) ##The exception rises here
         if IPersE:
             IPerE = IPersE[0]
             Matches = face_recognition.compare_faces(known_face_encodings, IPerE)
             if True in Matches:
                 TName = known_face_names[Matches.index(True)]

        cv2.rectangle(Frame, (x,y), (x+w,y+h), (0,0,0), 2)
        cv2.putText(Frame, TName, (x+w+5,y+23), cv2.FONT_HERSHEY_DUPLEX, 0.8, (0,0,0), 2, cv2.LINE_AA)

cv2.imshow('Frame', Frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
    break
theBullWhoCodes commented 6 years ago

You need to set the frame flag to Writable:true. After getting frame picamera. Example Code

import the necessary packages

from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2

initialize the camera and grab a reference to the raw camera capture

camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))

allow the camera to warmup

time.sleep(0.1)

capture frames from the camera

for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
    # grab the raw NumPy array representing the image, then initialize the timestamp
    # and occupied/unoccupied text
    image = frame.array

set flag to true

image.setflags(write=True)

  print(image.flags)
    print(type(image))
    # show the frame
    cv2.imshow("Frame", image)
    key = cv2.waitKey(1) & 0xFF
# clear the stream in preparation for the next frame

`rawCapture.truncate(0)`

# if the q key was pressed, break from the loop
 if key == ord("q"):
        break

cv2.destroyAllWindows()

it would work fine then.