Ajoutez des yeux au robot

Parfois, un robot doit saisir quelque chose. Ce robot sans yeux comme sans mains. Au sens littéral. Après tout, ne sachant pas où se trouve le délicieux, le robot ne pourra pas l'atteindre avec ses bras robotiques. Ou d'autres manipulateurs.

Dans cet article, nous allons voir comment calibrer le robot afin de pouvoir basculer entre le Robot Coordinate System et la caméra 3D SK.



Étape 1. Prenez le robot

Nous aurons des objets de mouvement Dobot Magicien. Regardez comment il déplacera des objets - Intel Realsense D435. Et l'objet d'étalonnage devra être une boule rouge.

Voilà comment ils se regardent.



La boule rouge est choisie non seulement pour que quelqu'un décore le sapin de Noël . Rouge - pour qu'il puisse être facilement trouvé dans l'image (sans apprendre un autre réseau). Balle - pour calculer plus précisément son centre dans l'image. Mais nous y reviendrons plus tard.

Étape 2. Où le robot déplace la balle

L'algorithme d'étalonnage peut être décrit comme suit:

  1. Générer une liste de positions dans l'espace
  2. Le robot déplace le ballon dans la liste, prenant des images avec lui.
  3. Pour chaque image, nous trouvons les coordonnées de la balle
  4. Nous calculons la conversion des coordonnées de la caméra en coordonnées du robot

Les positions doivent être choisies pour couvrir autant d'espace disponible que possible. Il vaut mieux ne pas prendre une petite balle, cela réduira la précision de l'étalonnage.

Nous ne donnerons pas ici le code d'enregistrement de l'étalonnage, car il dépend trop du robot lui-même, de la caméra, de l'environnement dans lequel tout est exécuté (par exemple, nous l'avons fait dans ROS). L'important est que pour un étalonnage supplémentaire, vous pouvez prendre des photos même en mode manuel, en envoyant des étapes pour envoyer le robot à des positions et en enregistrant des photos.

La seule exigence est que les positions relatives de la caméra et du robot restent inchangées tout le temps. Nous vous recommandons également de prendre immédiatement la deuxième série d'images pour validation - afin d'évaluer la précision du calcul de l'étalonnage.

Étape 3. Obtenez les coordonnées

Nous connaissons les coordonnées du manipulateur, car nous envoyons spécialement le robot aux positions spécifiées dans la liste. Pour les robots avec un grand nombre de degrés de liberté, vous devrez spécifier plus de paramètres, mais dans notre bras robotique à 4 axes, la position est uniquement déterminée par les coordonnées de la pointe du bras robotique. Donc, nous gardons simplement les positions dans lesquelles les mains sont allées.



Pour les images de balle, ses coordonnées doivent encore être calculées. Nous utiliserons un objet bien choisi pour l'étalonnage. Nous reformulons la tâche de trouver une balle comme "trouver la plus grande région de rouge", qui sur python + opencv ressemblera à:

def get_center(image): #       image = cv2.GaussianBlur(image, (7, 7), 0) #     HSV hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) #    saturation = hsv[...,1] saturation[(hsv[..., 0] > 15) & (hsv[..., 0] < 165)] = 0 _, image1 = cv2.threshold(saturation, 92, 255, cv2.THRESH_BINARY) #     contours = cv2.findContours(image1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0] contour = max(contours, key=cv2.contourArea) #    b_circle = cv2.minEnclosingCircle(contour) return b_circle[0] 

Examinons de plus près.

Après la conversion en espace HSV, l'image ressemble à ceci:



Comme vous pouvez le voir, pour les pixels sombres, la teinte est assez bruyante et un critère supplémentaire de segmentation est nécessaire. Ne laisser que les pixels rouges  texthue[u,v] in[15;15] et regardez le canal de saturation. Sur ce canal, la boule de calibration se détache clairement.

Ensuite, le critère final ressemblera à ceci:

  • Vérifiez que la teinte est approximativement rouge
  • Ne laisser que des pixels dont la saturation dépasse un seuil donné
  • Binariser l'image

Après quoi, nous obtenons quelque chose comme ceci:



Vous devez maintenant trouver les coordonnées du centre de la sphère. Il existe différentes approches, par exemple, vous pouvez personnaliser le modèle 3D de la sphère en nuage de points. Cependant, pour realsense D435, les valeurs de profondeur aux frontières des objets sont assez bruyantes, nous allons donc suivre une voie différente.

Nous supposons que la balle est ici la plus grande zone connectée. Ensuite, nous trouvons son centre et découvrons la profondeur jusqu'à ce point sur la surface de la balle à partir de la profondeur du canal. Et avec un peu d'aide de la stéréométrie, passons du point visible sur la surface de la balle à son centre.

Pour trouver le centre de la balle, nous utilisons la connaissance que la projection doit être un cercle et nous voulons obtenir une estimation impartiale du centre (mais la ventouse du robot essaie de nous empêcher). Ici, il suffit de trouver un cercle de surface minimale qui décrit cette zone, et cela a déjà été décidé dans opencv - minEnclosingCircle .

Après avoir reçu les 2 coordonnées du point u, v en pixels et la profondeur en millimètres, nous les traduisons en coordonnées physiques dans la caméra SK:

 def get_world_coords(u, v, depth, camera_matrix): f = np.linalg.inv(camera_matrix) l = np.array([u,v,1]) * depth return np.dot(f,l) 

camera_matrix - matrice des paramètres internes de la caméra, selon la formule .

Étape 4. Effectuez l'étalonnage

À l'heure actuelle, nous avons reçu 2 ensembles de points pour différentes positions dans l'espace: les coordonnées du haut de la sphère - le point pour lequel la balle aspire le robot dans le SC du robot, et les coordonnées du centre visible de la balle - le point de la sphère la plus proche de la caméra, dans le SC de la caméra. Pour les comparer, vous devez d'abord les amener à un point physique du ballon.

Et le moyen le plus simple est de traduire ces points au centre de la balle. Nous mesurons son rayon r = 24 mm. Ensuite, il est clair comment obtenir les coordonnées du centre de la balle O à partir du point de tangence K - le toucher est toujours 1 rayon plus haut le long de l'axe Z.

Il reste à traduire les coordonnées du centre V de la région visible en coordonnées du centre de la balle O. Pour expliquer comment procéder, utilisez la figure:



Il s'avère que le centre réel de la balle O est toujours exactement 1 rayon plus profond que le point visible V. Cela signifie que le vecteur de rayon trouvé doit être étendu de 24 mm.

 vecCO= vecCV+ frac vecCV| vecCV|r



Reste un peu - ayant 2 ensembles de coordonnées 3D correspondant aux mêmes points physiques, retrouvez la transformation du premier ensemble au second. Nous utiliserons pour cela la fonction opencv cv2.estimateAffine3D. Pour des coordonnées idéalement trouvées, la transformation affine est bien sûr une énumération, afin de décrire la transformation des points, la rotation et le déplacement suffisent, l'extension sera superflue. Cependant, l'utilisation de la transformation affine vous permet de compenser les inexactitudes avec une matrice mal calculée des paramètres internes de la caméra. Plus encore, cela vous permet d'obtenir un étalonnage sans les connaître du tout.

 transformation = cv2.estimateAffine3D(camera_coords, robot_coords) 

La sortie est une matrice de transformation 3x4, les premiers composants 3x3 sont une matrice de rotation combinée avec une extension le long des axes. Avec un étalonnage correct de la caméra et de bonnes données d'entrée, vous devriez obtenir une matrice proche de la matrice de rotation. Les 3 chiffres restants sont le vecteur de déplacement entre la caméra et le robot.

Étape 5. Nous utilisons l'étalonnage

Afin d'utiliser l'étalonnage obtenu, il est nécessaire de répéter les transformations indiquées. Nous les regroupons dans un seul algorithme.

  1. On retrouve sur l'image RGBD les coordonnées du point u, v, profondeur qui nous intéresse
  2. Nous les traduisons en coordonnées physiques x, y, z dans la caméra SK en utilisant la matrice des paramètres internes
  3. Dans le cas d'une balle, le point qui nous intéresse est dans la profondeur de la balle v= frac|v|+r|v| cdotv,v=[x,y,z]
  4. Nous appliquons la transformation transformation trouvée, que nous désignons par la matrice T
    v=T fois[v0,v1,v2,1]T
  5. Nous avons obtenu les coordonnées du centre de la balle dans le robot SK. Pour que le robot n'essaye pas de percer la balle, nous envoyons un point 1 rayon plus haut pour le contrôle v=[v0,v1,v2+r]

Précision d'étalonnage

Nous avons calculé l'étalonnage à 9 positions. Sur un ensemble de validation de 6 positions supplémentaires, une précision de 2,5 mm a été obtenue avec une taille de zone de travail de 16x30x5 cm. Pour cela, nous avons appliqué la transformation trouvée aux images restantes et calculé la longueur moyenne du vecteur d'erreur.

Étape 6. Nous utilisons dans les tâches appliquées

Après avoir fait l'étalonnage, vous pouvez commencer à résoudre de vrais problèmes. Par exemple, nous avons connecté un casque VR avec des contrôleurs et avons pu contrôler le robot et déplacer les cubes en réalité virtuelle.


Mais cette méthode d'étalonnage est assez générale. Peu importe la caméra et le robot utilisés, la méthode décrite permet de calculer facilement la relation entre les systèmes de coordonnées du robot et de la caméra. De plus, avec de petits changements, la méthode est autonome afin que le robot puisse effectuer automatiquement l'étalonnage, car au fil du temps, la caméra se déplacera par rapport au robot.

Vasyutka et ZlodeiBaal et moi prévoyons de continuer à parler du monde des robots, de la réalité virtuelle et de l'apprentissage automatique, si cela est intéressant. Et les sources d'étalonnage peuvent être trouvées dans mon geit .

Source: https://habr.com/ru/post/fr475916/


All Articles