Essayez de charger l'image dans un thread séparé (OpenCV-Python)

Récemment, j'ai découvert une bibliothèque appelée trio.

[Modèle de codage asynchrone Python + Trio] (https://qiita.com/yura/items/689d065aba00fe14fbba)

Veuillez vous référer au.


Si vous écrivez un programme de traitement d'image / reconnaissance d'image, vous voudrez charger l'image suivante pendant le traitement d'image / temps de reconnaissance. J'ai donc décidé d'écrire un programme multi-thread en Python.

  1. Écrivez une version sérialisée.
  2. Passez en revue le cadre multithread dans cette langue.
  3. Pensez à quel processus et quel processus sont indépendants et comment le multithreading est possible.
  4. Implémentez une version multithread

Écrivez une version séquentielle.

J'ai écrit une version de traitement séquentiel comme décrit plus tard. Je souhaite charger l'image suivante pendant ce processus de détection. Pour le fonctionnement, préparez une image d'entrée pour détecter les personnes, pat = r"*.png " Veuillez réécrire la partie de.

Version de traitement séquentiel

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

Passez en revue le cadre multithread dans cette langue

"Il existe deux manières de gérer les threads dans le module de threading. Créez une sous-classe de threading.Thread. Créez une instance de threading.Thread. " Cependant, choisissons une méthode pour créer directement une instance.

Tout d'abord, examinons un exemple de traitement multi-thread qui ne renvoie pas de résultat à partir d'une fonction.

Ensuite, il est devenu clair que la partie suivante était le point principal.

\ # Créez une instance du thread. t = threading.Thread (cible = fonction, args = tapple d'arguments de fonction) t.start() Autre traitement t.join()

Dans cet exemple, le résultat de la fonction ne peut pas être retourné, donc pour renvoyer le résultat entre les threads, Queue est utilisé pour transmettre des données entre les threads.

nom de la fonction def(queue,argument):
Traitement des fonctions
    queue.put(Valeur de retour)

t = threading.Thread(target=Nom de la fonction, args=(queue,argument)) 
t.start()
#Ecrire le processus
t.join()
Valeur de retour de la fonction= queue.get()

Pensez à la façon dont le multithreading est possible

Il existe deux façons de décider d'appeler l'image ou de détecter la personne dans un fil distinct. Ici, j'ai essayé de faire du processus de détection de personne un fil distinct. En écrivant comme ceci, en chargeant l'image suivante et en traitant l'image chargée Il semble qu'il puisse fonctionner en parallèle.

Implémenter une version multi-thread

Version multithread

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

Quant au résultat de l'opération, le temps de traitement est réduit d'environ 0,8 seconde lors de la lecture de 100 fichiers png. (Dans l'exemple, on peut voir qu'il est nécessaire de réduire le temps nécessaire au processus de détection de personne lui-même.)

Version de traitement séquentiel secondes 29.5429292224 Version multithread de secondes 28.7976980869

# Version multithread (autre version)

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

Post-scriptum: Ce que j'ai pensé récemment. Il est possible que l'image soit lue et détectée dans chaque thread. Si cette méthode peut être utilisée, il devrait être possible de paralléliser des images avec un travail uniformément réparti plutôt que de les paralléliser avec des temps de calcul complètement différents pour le chargement et la détection des images.

http://docs.python.jp/2/library/multiprocessing.html

Exemple de script référencé

16.2 Filetage - interface de filetage de haut niveau http://docs.python.jp/2/library/threading.html

Essayez un fil Python (2) http://bty.sakura.ne.jp/wp/archives/69

Traitement multithread avec Python http://qiita.com/konnyakmannan/items/2f0e3f00137db10f56a7

Article associé Essayez de charger l'image dans un thread séparé (version C ++) http://qiita.com/nonbiri15/items/016bb38eb42a219e98e2


Remarque: J'ai entendu dire qu'il existe une bibliothèque appelée TRIO et que vous devriez l'utiliser.

https://trio.readthedocs.io/en/latest/#

Recommended Posts

Essayez de charger l'image dans un thread séparé (OpenCV-Python)
L'image est Namekuji
Essayez une recherche similaire de recherche d'images à l'aide du SDK Python [Recherche]
J'ai écrit un script qui divise l'image en deux
Détecter les points de mosaïque dans l'image
Gérer les demandes dans un processus distinct
Essayez de modifier une nouvelle image à l'aide du modèle StyleGAN2 entraîné
Essayez Cython dans les plus brefs délais
Essayez de brouiller l'image avec opencv2
Essayez d'utiliser l'API Wunderlist en Python
Essayez d'utiliser l'API Kraken avec Python
Essayez d'utiliser la bande HL dans l'ordre
Ecrire le test dans la docstring python
Essayez de dessiner une animation simple en Python
Changer la liste dans l'instruction for
Exécuter l'interpréteur Python dans le script
Essayez le nouveau chaînage du planificateur dans PyTorch 1.4
Essayez un tube de programmation fonctionnel en Python
Essayez d'accéder à l'API Spotify dans Django.
Disposez les nombres en forme de spirale
Créer en Python sans fichier image factice dans Django et tester le téléchargement de l'image
Essayez d'ajouter la distorsion de l'objectif fisheye à l'image
[Python] Récupérez les fichiers dans le dossier avec Python
Calculons en fait le problème statistique avec Python
Utilisez le dernier pip dans un environnement virtualenv
Récupérer l'appelant d'une fonction en Python
Essayez d'utiliser l'API BitFlyer Ligntning en Python
Copiez la liste en Python
Trouvez le nombre de jours dans un mois
Programme pour rechercher la même image
Obtenir uniquement les éléments de sous-classe dans une liste
Déterminer s'il y a des oiseaux dans l'image
Déterminez les nombres dans l'image prise avec la webcam
Détecter les dossiers avec la même image dans ImageHash
Définir une adresse IP fixe dans l'environnement Linux
Essayez de modifier un peu la vue du fichier de TortoiseHg
Sortie sous la forme d'un tableau python
[Python] Trouvez la matrice de translocation en notation d'inclusion
Essayez d'implémenter la méthode Monte Carlo en Python
Supplément à "Calibration de la caméra" des didacticiels OpenCV-Python
N'y a-t-il pas une valeur par défaut dans le dictionnaire?
Essayez d'utiliser l'API DropBox Core avec Python
Essayez de faire une stratégie de blackjack en renforçant l'apprentissage (② Enregistrer l'environnement dans le gymnase)
Une note qui implémente une tâche en Python qui charge un fichier GCS dans BigQuery