Kürzlich habe ich von einer Bibliothek namens Trio erfahren.
[Asynchrones Python + Trio-Codierungsmuster] (https://qiita.com/yura/items/689d065aba00fe14fbba)
Bitte wende dich an die.
Wenn Sie ein Bildverarbeitungs- / Bilderkennungsprogramm schreiben, möchten Sie das nächste Bild während der Bildverarbeitungs- / Erkennungszeit lesen. Also habe ich beschlossen, ein Multithread-Programm in Python zu schreiben.
Ich habe eine sequentielle Verarbeitungsversion geschrieben, wie später beschrieben. Ich möchte das nächste Bild während dieses Erkennungsprozesses laden. Bereiten Sie für den Betrieb ein Eingabebild vor, um Personen zu erkennen. pat = r"*.png " Bitte schreiben Sie das Teil entsprechend um.
Sequentielle Verarbeitungsversion
detectLoop.py
# -*- coding: utf-8 -*-
# pylint: disable-msg=C0103
import glob
import cv2
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def detect(img):
found = hog.detectMultiScale(img, winStride=(8, 8), padding=(32, 32), scale=1.05)
return found
def draw_detections(img, rects, thickness=1):
for x, y, w, h in rects:
# the HOG detector returns slightly larger rectangles than the real objects.
# so we slightly shrink the rectangles to get a nicer output.
pad_w, pad_h = int(0.15*w), int(0.05*h)
cv2.rectangle(img, (x+pad_w, y+pad_h), (x+w-pad_w, y+h-pad_h), (0, 255, 0), thickness)
if __name__ == '__main__':
pat = r"*.png "
names = glob.glob(pat)[:100]
e1 = cv2.getTickCount()
imgname = names[0]
img = cv2.imread(imgname)
for i in range(1, len(names), 1):
found, scores = detect(img)
imgnameNext = names[i]
imgNext = cv2.imread(imgnameNext)
if 0:
print i, imgnameNext, imgNext.shape
print found
oldImg, imgname, img = img, imgnameNext, imgNext
draw_detections(oldImg, found)
cv2.imshow("detected", oldImg)
cv2.waitKey(1)
e2 = cv2.getTickCount()
timeDiff = (e2 - e1)/ cv2.getTickFrequency()
print timeDiff
"Es gibt zwei Möglichkeiten, mit Threads im Threading-Modul umzugehen. Erstellen Sie eine Unterklasse von Threading.Thread. Erstellen Sie eine Instanz von threading.Thread. "" Wählen wir jedoch eine Methode zum direkten Erstellen einer Instanz.
Schauen wir uns zunächst ein Multithread-Beispiel für die Verarbeitung an, bei dem kein Ergebnis einer Funktion zurückgegeben wird.
Dann wurde klar, dass der nächste Teil der Hauptpunkt war.
\ # Erstellt eine Instanz des Threads. t = threading.Thread (Ziel = Funktion, Argumente = Tapple von Funktionsargumenten) t.start() Andere Verarbeitung t.join()
In diesem Beispiel kann das Ergebnis der Funktion nicht zurückgegeben werden. Um das Ergebnis zwischen Threads zurückzugeben, wird Queue verwendet, um Daten zwischen Threads zu übergeben.
def Funktionsname(queue,Streit):
Funktionsverarbeitung
queue.put(Rückgabewert)
t = threading.Thread(target=Funktionsname, args=(queue,Streit))
t.start()
#Schreiben Sie den Prozess
t.join()
Funktionsrückgabewert= queue.get()
Es gibt zwei Möglichkeiten, um zu prüfen, ob das Bild aufgerufen oder die Person in einem separaten Thread erkannt werden soll. Hier habe ich versucht, den Personenerkennungsprozess zu einem separaten Thread zu machen. Wenn Sie so schreiben, laden Sie das nächste Bild und verarbeiten das geladene Bild Es scheint, dass es parallel betrieben werden kann.
Multithread-Version
detectLoop_thread.py
# -*- coding: utf-8 -*-
# pylint: disable-msg=C0103
import threading
import Queue
import glob
import cv2
global hog
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def detect2(queue, img):
global hog
found = hog.detectMultiScale(img, winStride=(8, 8), padding=(32, 32), scale=1.05)
queue.put(found)
def draw_detections(img, rects, thickness=1):
for x, y, w, h in rects:
# the HOG detector returns slightly larger rectangles than the real objects.
# so we slightly shrink the rectangles to get a nicer output.
pad_w, pad_h = int(0.15*w), int(0.05*h)
cv2.rectangle(img, (x+pad_w, y+pad_h), (x+w-pad_w, y+h-pad_h), (0, 255, 0), thickness)
if __name__ == '__main__':
pat = r"*.png "
names = glob.glob(pat)[:100]
e1 = cv2.getTickCount()
queue = Queue.Queue()
imgname = names[0]
img = cv2.imread(imgname)
for i in range(1, len(names), 1):
t = threading.Thread(target=detect2, args=(queue, img, ))
t.start()
imgnameNext = names[i]
imgNext = cv2.imread(imgnameNext)
t.join()
found, scores = queue.get()
if 0:
print i, imgnameNext, imgNext.shape
print found
oldImg, imgname, img = img, imgNext, imgNext
draw_detections(oldImg, found)
cv2.imshow("detected", oldImg)
cv2.waitKey(1)
e2 = cv2.getTickCount()
timeDiff = (e2 - e1)/ cv2.getTickFrequency()
print timeDiff
Was das Operationsergebnis betrifft, wird die Verarbeitungszeit beim Lesen von 100 PNG-Dateien um etwa 0,8 Sekunden reduziert. (In dem Beispiel ist ersichtlich, dass es notwendig ist, die Zeit zu reduzieren, die für den Personenerkennungsprozess selbst erforderlich ist.)
Sekunden der sequentiellen Verarbeitung 29.5429292224 Multithread-Version von Sekunden 28.7976980869
detectLoop_thread2.py
# -*- coding: utf-8 -*-
# pylint: disable-msg=C0103
import threading
import Queue
import glob
import cv2
global hog
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def imread2(queue, imgnameNext):
imgNext = cv2.imread(imgnameNext)
queue.put(imgNext)
def draw_detections(img, rects, thickness=1):
for x, y, w, h in rects:
# the HOG detector returns slightly larger rectangles than the real objects.
# so we slightly shrink the rectangles to get a nicer output.
pad_w, pad_h = int(0.15*w), int(0.05*h)
cv2.rectangle(img, (x+pad_w, y+pad_h), (x+w-pad_w, y+h-pad_h), (0, 255, 0), thickness)
if __name__ == '__main__':
pat = r"*.png "
names = glob.glob(pat)[:100]
e1 = cv2.getTickCount()
queue = Queue.Queue()
imgname = names[0]
img = cv2.imread(imgname)
for i in range(1, len(names), 1):
imgnameNext = names[i]
t = threading.Thread(target=imread2, args=(queue, imgnameNext, ))
t.start()
found, scores = hog.detectMultiScale(img, winStride=(8, 8), padding=(32, 32), scale=1.05)
t.join()
imgNext = queue.get()
if 0:
print i, imgnameNext, imgNext.shape
print found
oldImg, imgname, img = img, imgNext, imgNext
draw_detections(oldImg, found)
cv2.imshow("detected", oldImg)
cv2.waitKey(1)
e2 = cv2.getTickCount()
timeDiff = (e2 - e1)/ cv2.getTickFrequency()
print timeDiff
Nachtrag: Was ich kürzlich gedacht habe. Es besteht die Möglichkeit, dass das Bild in jedem Thread gelesen und erkannt wird. Wenn diese Methode verwendet werden kann, sollte es möglich sein, Bilder mit gleichmäßig verteilten Arbeiten zu parallelisieren, anstatt sie mit völlig unterschiedlichen Berechnungszeiten für das Laden und Erkennen von Bildern zu parallelisieren.
http://docs.python.jp/2/library/multiprocessing.html
16.2. Threading - High-Level-Threading-Schnittstelle http://docs.python.jp/2/library/threading.html
Versuchen Sie es mit einem Python-Thread (2) http://bty.sakura.ne.jp/wp/archives/69
Multithread-Verarbeitung mit Python http://qiita.com/konnyakmannan/items/2f0e3f00137db10f56a7
In Verbindung stehender Artikel Versuchen Sie, das Bild in einen separaten Thread zu laden (C ++ - Version) http://qiita.com/nonbiri15/items/016bb38eb42a219e98e2
Hinweis: Ich habe gehört, dass es eine Bibliothek namens TRIO gibt, die Sie verwenden sollten.
https://trio.readthedocs.io/en/latest/#
Recommended Posts