[PYTHON] Suivez le marqueur AR avec un servo à 2 axes

Cette fois, quand j'ai fait une démonstration du système pour suivre le matériel pédagogique, j'ai été obligé de suivre le marqueur AR, donc mon propre mémo à ce moment-là.

Flux de mise en œuvre

L'arconv d'OpneCV peut être utilisé pour identifier les marqueurs AR et capturer leurs coordonnées et leurs angles à partir d'images. [^ 1]

Pour le moment, générez un marqueur AR.

make.py


#/usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2
import sys
#bibliothèque aruco
aruco = cv2.aruco 
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)

def make():
    for i in range(30):
        generator = aruco.drowMarker(dictionary, i, 100)
        cv2.imwrite('ar' + str(i) + 'png', generator)

if __name__ == '__main__';
    make():

Si vous exécutez ce fichier, vous devriez avoir 30 images de marqueurs AR. スクリーンショット 2019-07-27 14.01.53.PNG

Cette fois, nous utiliserons ar1.png. スクリーンショット 2019-07-27 14.01.53.jpg

Ensuite, regardons le programme actuel. Tout d'abord, l'image est acquise et la taille de l'image est acquise et redimensionnée.

main.py


while True:
            #Obtenir des images de la capture vidéo
            ret, frame = cap.read()
            #Obtenir la taille
            Height, Width = frame.shape[:2]
            # resize
            img = cv2.resize(frame,(int(Width),int(Height)))

Ensuite, le marqueur est détecté et identifié, et les coordonnées du centre sont obtenues.

main.py


            #Détecter les marqueurs
            corners, ids, rejectedImgPoints = aruco.detectMarkers(img, dictionary) 

            if len(corners) > 0:
                #print(ids[0])
                #Lorsque le marqueur 01 est détecté
                if ids[0] == 1:
                    square_points = np.reshape(np.array(corners), (4, -1))
                    G = np.mean(square_points, axis = 0)
                    x = G[0]
                    y = G[1]
                    #Spécifiez le point de coordonnées que vous souhaitez faire correspondre
                    markerrect = [[x,y-40]]
                    print(markerrect)
                    for rect in markerrect:
                        img_x = rect[0]
                        img_y = rect[1]

A ce moment, les coordonnées mobiles sont calculées. Il est nécessaire de changer la valeur en fonction de l'angle auquel le servo est installé. Ajustez comme il convient. De plus, comme il était nécessaire de limiter le mouvement ascendant, afin d'éviter que la plage de fonctionnement ne soit dépassée, la valeur était continuellement substituée lorsque la coordonnée y dépassait la valeur spécifiée.

main.py


                        #Déplacement du jeu de coordonnées
                        move_degree_x = now_degree_x - (img_x-160)*0.06
                        move_degree_y = now_degree_y - (img_y-50)*0.06
                        #Prévention du dépassement de la plage mobile
                        if move_degree_y > 650:
                            move_degree_y = 650
                        print('deg: ', move_degree_x , move_degree_y)
                        pwm.set_pwm(15, 0, int(move_degree_x))
                        pwm.set_pwm(14, 0, int(move_degree_y))
                        #Jeu de coordonnées post-déplacement
                        now_degree_x = move_degree_x
                        now_degree_y = move_degree_y

Adafruit_PCA9685 a été utilisé pour contrôler le servomoteur. [^ 2] Avec cela, une pluralité de servomoteurs peuvent être commandés.

Le résultat final est le suivant.

main.py


#/usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2
import numpy as np
import time
import Adafruit_PCA9685
#bibliothèque aruco
aruco = cv2.aruco 
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)

class MarkerCtl():

    def arReader(self,Sb):
        # initial   
        pwm = Adafruit_PCA9685.PCA9685()
        pwm.set_pwm_freq(60)
        pwm.set_pwm(14, 0, 600)
        time.sleep(1)
        pwm.set_pwm(15, 0, 450)
        time.sleep(1)

        #Démarrer la capture vidéo
        cap = cv2.VideoCapture(0) 
        cap.set(3, 320)
        cap.set(4, 240)
        color = (255, 255, 255)

        #Ensemble d'état actuel du servo
        now_degree_x, now_degree_y, move_degree_x, move_degree_y = 450, 600, 0, 0
        while True:
            #Obtenir des images de la capture vidéo
            ret, frame = cap.read()
            #Obtenir la taille
            Height, Width = frame.shape[:2]
            # resize
            img = cv2.resize(frame,(int(Width),int(Height)))
            #Détecter le marqueur
            corners, ids, rejectedImgPoints = aruco.detectMarkers(img, dictionary) 

            if len(corners) > 0:
                #print(ids[0])
                #Lorsque le marqueur 01 est détecté
                if ids[0] == 1:
                    square_points = np.reshape(np.array(corners), (4, -1))
                    G = np.mean(square_points, axis = 0)
                    x = G[0]
                    y = G[1]
                    #Spécifiez le point de coordonnées que vous souhaitez faire correspondre
                    markerrect = [[x,y-40]]
                    print(markerrect)
                    for rect in markerrect:
                        img_x = rect[0]
                        img_y = rect[1]
                        #print('img: ',img_x, img_y)
                        #Déplacement du jeu de coordonnées
                        move_degree_x = now_degree_x - (img_x-160)*0.06
                        move_degree_y = now_degree_y - (img_y-50)*0.06
                        #Prévention du dépassement de la plage mobile
                        if move_degree_y > 650:
                            move_degree_y = 650
                        print('deg: ', move_degree_x , move_degree_y)
                        pwm.set_pwm(15, 0, int(move_degree_x))
                        pwm.set_pwm(14, 0, int(move_degree_y))
                        #Jeu de coordonnées post-déplacement
                        now_degree_x = move_degree_x
                        now_degree_y = move_degree_y

        #Terminer le traitement
        cap.release()
        cv2.destroyAllWindows()
        

[^ 1]: "[Programmation avec Python] J'ai essayé de reconnaître le marqueur AR en utilisant la bibliothèque aruco" http://okatenari.com/2017/11/28/python-ar/

Recommended Posts

Suivez le marqueur AR avec un servo à 2 axes
Suivez la hiérarchie des fichiers avec fts
Rechercher le labyrinthe avec l'algorithme python A *
Un mémo expliquant la spécification de l'axe de l'axe
Un modèle qui identifie la guitare avec fast.ai
[Python] Récupérez les fichiers dans le dossier avec Python
Comment dessiner un graphique à 2 axes avec pyplot
Trouvez la position au-dessus du seuil avec NumPy
Enregistrer l'objet dans un fichier avec pickle
Créez un outil de traduction avec Translate Toolkit
matplotlib: remplacez l'axe lui-même par un autre.
Dessinez un graphique avec PyQtGraph Partie 5-Augmentez l'axe Y
Un mémo pour comprendre visuellement l'axe des pandas.
Comment créer un sous-menu avec le plug-in [Blender]
Essayez de créer une application Todo avec le framework Django REST
Faire un point d'arrêt sur la couche c avec python
Une histoire qui a eu du mal avec l'ensemble commun HTTP_PROXY = ~
Essayez de déplacer le servomoteur avec RasPi (version à 180 degrés)
Remplissez l'arrière-plan d'une seule couleur avec OpenCV2 + Python
Visualisez le vocabulaire caractéristique d'un document avec D3.js
Créez une carte thermique de tweet avec l'API Google Maps
Un mémo que j'ai touché au magasin de données avec python
Transition vers l'écran de mise à jour avec le Django a tag
Calculer le produit des matrices avec une expression de caractère?