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à.
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.
Cette fois, nous utiliserons ar1.png.
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