как использовать функцию opencv «detectMultiScale ()» в многопоточности в Raspberry Pi - PullRequest
0 голосов
/ 27 июня 2019

Функция defineMultiScale () Python OpenCV перестает отвечать на запросы, когда я использую его в сценарии многопоточности в raspberry pi 3.

Я надеюсь создать два потока;один для показа живых изображений, а другой для обнаружения объекта и нахождения его центра.Даже несмотря на то, что функция показа живого изображения работает гладко, ее функция DetectMultiScale () не показывает никакого отклика.Я провел онлайн-исследование и выяснил, что OpenCV плохо справляется с параллельной обработкой.

import threading
import cv2
import numpy as np
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
global image, center
center=[]
def capture():
    global image, center
    cv2.namedWindow('image',cv2.WINDOW_NORMAL)
    cv2.moveWindow('image',0,0)
    cv2.resizeWindow('image', 800,608)
    camera=PiCamera()
    camera.resolution=(800,608)
    camera.framerate=50
    rawCapture=PiRGBArray(camera,size=(800,608))
    for frame in camera.capture_continuous(rawCapture,format='bgr',use_video_port=True):
        image=frame.array      
        cv2.imshow('image',image)

        key=cv2.waitKey(1)& 0xFF
        rawCapture.truncate(0)
        if key==ord('q'):
            break    
    cv2.destroyAllWindows()

def detect():
    global image, center
    time.sleep(2)
    drop_cascade = cv2.CascadeClassifier('cascade.xml')
    while True:
        faces = drop_cascade.detectMultiScale(image, 1.25, 7)
        for (x, y, w, h) in faces:
            center.append([x,y,w,h])

if __name__ == '__main__':
    thread1=threading.Thread(target=capture)
    thread2=threading.Thread(target=detect)
    thread1.start()
    thread2.start()

1 Ответ

0 голосов
/ 27 июня 2019

Проблема присуща Threads, она вызвана глобальной блокировкой интерпретатора.Потоки разделяют память программы.Чтобы защитить от конфликтов, вызванных изменением одной и той же переменной отдельными потоками, Python блокирует выполнение для определенного потока.Это означает, что в любой момент работает только один поток.Когда процессор простаивает, программа переключается между потоками, что ускоряет работу приложений, связанных с вводом-выводом.

Чтобы одновременно выполнять тяжелые задачи процессора, вы должны использовать multiprocessing.Процессы работают одновременно на отдельных ядрах процессора и не разделяют память.

Здесь - превосходное и более подробное объяснение о Глобальной блокировке интерпретатора.

Редактировать:

Здесь - это информация о многопроцессорной обработке.

Пример кода, который сравнивает потоки с асинхронной многопроцессорной обработкой:

    import time
    import threading
    from  multiprocessing import Pool

    # cpu heavy functions
    def doTask(val):
            for i in range(10000000):
                    x = i*i
            print(str.format('Task {} done!',val))

    def doOtherTask(val):
            for i in range(10000000):
                    x = i*i
            print(str.format('Other Task {} done!',val))

    if __name__ == '__main__':
            print('Threads:')
            # note starttime        
            starttime = time.time()
            # create and run threads
            thread1 = threading.Thread(doTask(1))
            thread2 = threading.Thread(doTask(2))
            thread3 = threading.Thread(doOtherTask(1))
            thread4 = threading.Thread(doOtherTask(2))
            thread1.start()
            thread2.start()
            thread3.start()
            thread4.start()

            print(str.format('Threads took {} seconds', time.time()-starttime))

            print('Multiprocessing:')
            #reset starttime
            starttime = time.time()
            # create and run processes
            arguments = [1,2]
            p = Pool()
            p.map_async(doTask,arguments)
            p.map_async(doOtherTask,arguments)
            # close and join pool, so program execution waits 
            # for all tasks to finish
            p.close()
            p.join()

            print(str.format('Multiprocessing took {} seconds', time.time()-starttime))
...