Performance issue was due to a bad compilation of dlib. Do not use pip install dlib which runs very very slowly for some reason compared to the proper compilation. I went from almost 10 seconds lag to about 2 seconds this way. So finally I didn't need multi-threading/processing, but I'm working on it to enhance the speed even more. Thanks for the help :)

Answer from Simon on Stack Overflow
🌐
DEV Community
dev.to › tecnosam › multiprocessing-in-python-part-2-584g
Multiprocessing in Python (Part 2) - DEV Community
August 15, 2022 - import cv2 import time from requests import post from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor cascPath = "haarcascade_frontalface_default.xml" # Create the haar cascade faceCascade = cv2.CascadeClassifier(cascPath) def draw_face(image): # More Info: https://realpython.com/face-recognition-with-python/ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Detect faces in the image faces = faceCascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30) ) # Draw a rectangle around the faces for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x+w, y+
Top answer
1 of 5
8

Performance issue was due to a bad compilation of dlib. Do not use pip install dlib which runs very very slowly for some reason compared to the proper compilation. I went from almost 10 seconds lag to about 2 seconds this way. So finally I didn't need multi-threading/processing, but I'm working on it to enhance the speed even more. Thanks for the help :)

2 of 5
3

i tried a simplified approach like P.Ro mentioned in his answer with processes writing to an output queue but somehow the queue got locked most of the time because all the processes wrote to it at the same time. (just my guess) i probably did something wrong.

in the end i ended up using pipes.

the code is nasty. but if i was me a few hours ago. i would still be glad to find an example that actually runs without effort.

from multiprocessing import Process, Queue, Manager,Pipe
import multiprocessing
import face_recognition as fik
import cv2
import time


video_input = 0

obama_image = fik.load_image_file("obama.png")
obama_face_encoding = fik.face_encodings(obama_image)[0]



quality = 0.7


def f(id,fi,fl):
    import face_recognition as fok

    while True:
        small_frame = fi.get()
        print("running thread"+str(id))
        face_locations = fok.face_locations(small_frame)

        if(len(face_locations)>0):
            print(face_locations)
            for (top7, right7, bottom7, left7) in face_locations:

                small_frame_c = small_frame[top7:bottom7, left7:right7]
                fl.send(small_frame_c)

fps_var =0
if __name__ == '__main__':
        multiprocessing.set_start_method('spawn')


        # global megaman
        with Manager() as manager:

            video_capture = cv2.VideoCapture(video_input)

            fi = Queue(maxsize=14)

            threads = 8
            proc = []

            parent_p = []
            thread_p = []
            # procids = range(0,threads)
            for t in range(0,threads):
                p_t,c_t = Pipe()
                parent_p.append(p_t)
                thread_p.append(c_t)
                print(t)
                proc.append(Process(target=f, args=(t,fi,thread_p[t])))
                proc[t].start()


            useframe = False

            frame_id = 0
            while True:
                # Grab a single frame of video
                ret, frame = video_capture.read()
                effheight, effwidth = frame.shape[:2]
                if effwidth < 20:
                    break
                # Resize frame of video to 1/4 size for faster face recognition processing
                xxx = 930
                yyy = 10/16 #0.4234375
                small_frame = cv2.resize(frame, (xxx, int(xxx*yyy)))
                if frame_id%2 == 0:
                    if not fi.full():


                        fi.put(small_frame)

                        print(frame_id)

                        cv2.imshow('Video', small_frame)


                        print("FPS: ", int(1.0 / (time.time() - fps_var)))
                        fps_var = time.time()


                #GET ALL DETECTIONS
                for t in range(0,threads):
                    if parent_p[t].poll():
                        small_frame_c = parent_p[t].recv()
                        cv2.imshow('recc', small_frame_c)
                        height34, width34 = small_frame_c.shape[:2]
                        # print fsizeee
                        if(width34<20):
                            print("face 2 small")
                            print(width34)
                            break
                        face_encodings_cam = fik.face_encodings(small_frame_c,[(0, width34, height34, 0)])

                        match = fik.compare_faces([obama_face_encoding], face_encodings_cam[0])
                        name = "Unknown"

                        if match[0]:
                            name = "Barack"

                        print(name)
                        break

                frame_id += 1

                # Hit 'q' on the keyboard to quit!
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
🌐
CSDN
devpress.csdn.net › python › 62f4dce5c6770329307fa644.html
Multiprocessing in Python (Part 2)_python_Mangs-DevPress官方社区
August 11, 2022 - import cv2 import time from requests import post from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor cascPath = "haarcascade_frontalface_default.xml" # Create the haar cascade faceCascade = cv2.CascadeClassifier(cascPath) def draw_face(image): # More Info: https://realpython.com/face-recognition-with-python/ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Detect faces in the image faces = faceCascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30) ) # Draw a rectangle around the faces for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x+w, y+
🌐
GitHub
github.com › ageitgey › face_recognition › issues › 314
Face_recognition and Multiprocessing troubles · Issue #314 · ageitgey/face_recognition
January 21, 2018 - self.pool = concurrent.futures.ProcessPoolExecutors() ....... #The function being called as a different proces: def threadComparison(self, vals): boole = fr.compare_faces(vals[0], vals[2][0]) val = self.RecFaces(boole) if val is not None: self.found.append(vals[1][val]) #The function handling data sorting and main processing: def searchFace(self, encoding): #Pull faces from database values = self.fdr.select('faces', '*') counter = 0 buff = [] names = [] bit = False for face in values: if len(self.found) > 0: bit = True break #Sorts facial encodings with names buff.append(np.array(face[1].split(' '))) names.append(face[0]) #Tried debugging here, all are list, strings, etc.
Author: ageitgey
🌐
PyImageSearch
pyimagesearch.com › home › blog › multiprocessing with opencv and python
Multiprocessing with OpenCV and Python - PyImageSearch
December 29, 2022 - Now, let’s assume we launch our Python script. The operating system will assign the process to a single one of those cores: Figure 2: Without multiprocessing, your OpenCV program may not be efficiently using all cores or processors available on your machine.
🌐
GitHub
github.com › ageitgey › face_recognition › issues › 812
How to use multiprocessing for face_recognition.face_encodings · Issue #812 · ageitgey/face_recognition
face_recognition version: 1.2.3 Python version: 3.6.5 Operating System: Windows I tried multiprocessing by using pool in python for the face_recognition.face_encodings but it doesn't work. So I wou...
Author: ageitgey
Find elsewhere
🌐
PyPI
pypi.org › project › face-recognition
face-recognition · PyPI
Face recognition can be done in parallel if you have a computer with · multiple CPU cores. For example if your system has 4 CPU cores, you can · process about 4 times as many images in the same amount of time by using ... You can also pass in --cpus -1 to use all CPU cores in your system. You can import the face_recognition module and then easily manipulate
🌐
Stack Overflow
stackoverflow.com › questions › 67263551 › multithreading-face-recognition-python
Multithreading Face-recognition python - Stack Overflow
April 26, 2021 - import face_recognition import cv2 from threading import Thread from collections import deque import pickle svm = pickle.load(open('svm.pkl','rb')) deque = deque() def open_camera(url): print('start camera') #capture = cv2.VideoCapture('rtsp://'+str(url)) capture = cv2.VideoCapture(0) while capture.isOpened(): _,frame = capture.read() frame_resize = cv2.resize(frame,(640,480)) cv2.imshow('Video',frame_resize) if cv2.waitKey(1) & 0xFF==ord('q'): break # cvtColor frame_resize = frame_resize[:, :, ::-1] deque.append(frame_resize) capture.release() cv2.destroyAllWindows() def spin(seconds): time.s
🌐
GitHub
github.com › ageitgey › face_recognition › issues › 443
How to use face_recognition in Python so that it can make use of all CPUs ?? · Issue #443 · ageitgey/face_recognition
April 10, 2018 - face_recognition version: latest Python version: 3.6 Operating System: Ubuntu Description Running the example I noticed it use only 1 CPU, I'm not talinking about the command line face:recognit...
Author: ageitgey
🌐
FaceOnLive
faceonlive.com › home › face recognition python: build your own powerful and accurate facial recognition tool
Face Recognition Python: Build Your Own Powerful and Accurate Facial Recognition Tool - FaceOnLive : On-Premises ID Verification & Biometrics Solution Provider
July 24, 2023 - Parallel processing: Utilizing multi-threading or multiprocessing techniques allows for simultaneous processing of multiple frames or regions within a frame. Handling multiple faces simultaneously requires additional considerations: Face tracking: Once a face is detected, we can track its movement across subsequent frames, reducing the need for continuous detection. Face recognition...
🌐
GitHub
github.com › ageitgey › face_recognition › issues › 227
multiprocessing of face_distance (question) · Issue #227 · ageitgey/face_recognition
November 7, 2017 - Hi, I'd like to use more CPUs when using face_distance in my python scripts. If I see well, multiprocess is implemented only in the CLI interface. Do you have plans to have this in the libs?
Author: ageitgey
🌐
Medium
medium.com › analytics-vidhya › exploiting-multithreading-and-multiprocessing-in-python-as-a-data-scientist-e2c98b61997a
Exploiting Multiprocessing and Multithreading in Python as a Data Scientist | by Parthasarathy Subburaj | Analytics Vidhya | Medium
November 17, 2020 - def face_detection(image_path): image_name = os.path.basename(image_path) image = cv2.imread(image_path) face_rect = image.copy() faces = face_detector(image) if len(faces) !=0: for face in faces: x1 = face.left() y1 = face.top() x2 = face.right() y2 = face.bottom() face_rect = cv2.rectangle(face_rect, (x1,y1), (x2,y2), (255,0,0), 5) cv2.imwrite("./Datasets/face_processed/" + image_name, face_rect) As usual let’s compare the results of executing this function in series, multithreading, multiprocessing mode.
🌐
GitHub
github.com › ageitgey › face_recognition › issues › 649
face_recognition uses only one CPU core. Is there a way to run it multithreaded? · Issue #649 · ageitgey/face_recognition
October 16, 2018 - face_recognition version: 1.2.3 dlib version: 19.16.99 from Git Python version: Python 3.6.5 (default, Apr 1 2018, 05:46:30) Operating System: Ubuntu 18.04 I am working on a program, that should recognize (identify) and track a lot of fa...
Author: ageitgey
🌐
Readthedocs
face-recognition.readthedocs.io › en › latest › readme.html
Face Recognition — Face Recognition 1.4.0 documentation
Face recognition can be done in parallel if you have a computer with · multiple CPU cores. For example if your system has 4 CPU cores, you can · process about 4 times as many images in the same amount of time by using ... You can also pass in --cpus -1 to use all CPU cores in your system. You can import the face_recognition module and then easily manipulate
Top answer
1 of 2
3

You should check out the multiprocessing library. If you have parts of you program that you can run in parallel, like processing multiple images and detecting a faces, you can simply define a process Pool. By default a pool will start as many processes simultaneously as you have processors. You can also define the pool size and fix it to 4.

e.g:

from multiprocessing import Pool
from glob import glob

def detect_face(file_name):
    ...

if __name__ == '__main__':
    with Pool() as p:
       p.map(detect_face, glob('*.jpg'))

You should also checkout sherlock, a collection of example on how to combine multiprocessing and opencv.

Limitations:

The algorithms in OpenCV itself are not easily executed in multiple processes. As OpenCV is written in C++, their execution depends highly on their implementation.

2 of 2
3

If you compile the OpenCV library with the OpenMP option active in the cmake file (it is off by default), many algorithms will use multiple cores automatically, without you needing to change anything in your source code. In my case I managed to achieve an up to 4.5x increase in performance. Yes, the Raspberry Pi 2 only has 4 cores, but if you do heavy number-crunching, a good division of the tasks can significantly reduce waiting times. For shorter algorithms don't expect much more than a 3x speedup.

Take care, with compiling the OpenMP libraries there is a bug in the libpng package. If the make halts with an error because libpng cannot find zlib, a quick and dirty solution can be that you just copy the source of zlib into the libpng source folder (or turn libpng off, if you don't need it).

🌐
GitHub
github.com › ageitgey › face_recognition
GitHub - ageitgey/face_recognition: The world's simplest facial recognition api for Python and the command line · GitHub
Face recognition can be done in parallel if you have a computer with multiple CPU cores. For example, if your system has 4 CPU cores, you can process about 4 times as many images in the same amount of time by using all your CPU cores in parallel. If you are using Python 3.4 or newer, pass in a --cpus <number_of_cpu_cores_to_use> parameter:
🌐
GitHub
github.com › ageitgey › face_recognition › issues › 258
How Face Recognition get full benefits from the ALL CPU and CORES ? · Issue #258 · ageitgey/face_recognition
December 11, 2017 - I am working on the python face_recognition (both hog and cnn) and I couldnt find a way to use all my 8 cores cpu to fasten the face detection and recognition. It is alway using 1 cpu. I dig a little bit on the Dlib compiling with BLAS a...
Author: ageitgey
Top answer
1 of 2
1

Yes, you can multithread the process. Use the threading library in python 2, or thread in python 3.

Here is a simple example.

Besides your main thread,

Have one thread only operating the camera and constantly updating the latest frame, which is global in this case.

def camera_thread():       
    cam = cv2.VideoCapture(1)
    _ret, self.image = cam.read()
    cv2.imshow('camera', self.image)

A second thread can run the inference from the model using the latest frame.

An optional third could perhaps draw a bounding box over the face, or perform other operations etc.

You might need mutex locks in between 2nd and 3rd threads in this case as you can only begin drawing boxes after you obtain an output from the model. This allows your 2nd thread to begin inference of the next frame without waiting for other threads.

The above example will result in a smooth video output with the inference lagging behind slightly. If you're not sure how multithreading works, I suggest reading up on the basics first.

2 of 2
1

update. I use separate thread to capture image from camera and I don't see any speed up of FPS compare to serial... Please see my code.

import threading
import time
import cv2
import numpy as np
class myThread (threading.Thread):
    def __init__(self, src):
        print("thread -------------init-------------")
        threading.Thread.__init__(self)
        self.cap = cv2.VideoCapture(src)
        self.stop = False
    def run(self):
        while(self.stop == False):
            self.ret, self.frame = self.cap.read()

    def Stop(self):
        self.cap.release()
        self.stop = True

    def read(self):
        return self.ret, self.frame

recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);

thread = myThread(0)
thread.start()
time.sleep(1)

start = time.time()
frames = 0
font = cv2.FONT_HERSHEY_SIMPLEX
cap = cv2.VideoCapture(0)
while(True):
    ret, frame = thread.read()
    frame = cv2.resize(frame, (640, 480))
    frames += 1
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(gray, 1.2, 5)
    for(x,y,w,h) in faces:
        # Create rectangle around the face
        cv2.rectangle(frame, (x-20,y-20), (x+w+20,y+h+20), (0,255,0), 4)
        Id, con = recognizer.predict(gray[y:y+h,x:x+w])
        print(Id, con)

        # Check the ID if exist
        if(con < 60):
            if(Id == 1):
                Id = "HUY"
            if(Id == 2):
                Id = "HOA"
        #If not exist, then it is Unknown
        else:
            #print(Id)
            Id = "Unknow"

        # Put text describe who is in the picture
        cv2.rectangle(frame, (x-22,y-90), (x+w+22, y-22), (0,255,0), -1)
        cv2.putText(frame, str(Id), (x,y-40), font, 2, (255,255,255), 3)  

    if cv2.waitKey(10) & 0xFF == ord('q'):
        thread.Stop()
        break
    cv2.imshow("frame", frame) 
end = time.time()
second = end - start
print("second:", + second)
print(frames/second)
cv2.destroyAllWindows()