Caméra avec fonction de suivi

Je veux faire un drone autonome qui pourrait lui-même trouver le chemin du but et revenir, tout en évitant tous les obstacles sans toucher personne. J'ai décidé de commencer avec un réseau neuronal et une webcam. Et donc ce projet s'est avéré image

L'essence du projet est un réseau de neurones, ou plutôt le cadre imageai écrit en python sous keras, trouve une personne dans l'image et donne les coordonnées de sa boîte. Plus loin dans l'horizontale, nous trouvons le centre du bloc et y déplaçons la caméra (laissant naturellement une certaine hystérésis pour la caméra afin qu'elle ne saute pas d'avant en arrière). Ensuite, nous trouvons le deuxième centre, mais déjà verticalement, ajoutez-y plusieurs dizaines de pixels, de sorte que lorsqu'une personne est debout, l'appareil photo capture son visage. Je voulais également attacher la reconnaissance faciale, mais la webcam est bon marché et n'a donc pas de fonction de mise au point automatique.

Pour le projet, il a fallu


STM32f4discovery - carte de débogage
MT415 un couple de pilotes de moteur
2 moteurs pas à pas
PSU 24 V 2,5 A
ImageAI

Je décrirai brièvement le code python


Initialisation de l'imageai. Sélectionnez le type de réseau neuronal - yolo et la taille de l'image - flash. Au flash, l'image est réduite à une petite taille (je ne me souviens pas laquelle) et pour cette raison, le réseau accélère.

detector = ObjectDetection() detector.setModelTypeAsYOLOv3() detector.setModelPath("yolo.h5") detector.loadModel(detection_speed="flash") 

Fonctions d'envoi d'un caractère au microcontrôleur pour une étape le long de l'axe horizontal et vertical

 def step(): i = 1 u = 0 while i: while u!=1: u = ser.write( b'v') u=0 ff=ser.read(1) print(1111) if ff==b'B': i=0 def step_y(): i = 1 u = 0 while i: while u!=1: u = ser.write( b'V') u=0 ff=ser.read(1) #print(1111) if ff==b'B': i=0 

La fonction qui reçoit la position des bordures gauche et droite de la boîte à l'entrée, trouve le centre et décide dans quel sens tourner afin que l'objet se trouve au milieu de la caméra. Encore une fois, les caractères de contrôle sont envoyés en microns.

 def rotate_x(left, right): center = (right - left)/2 + left u = 0 if center < 320: i=1 while i: while u!=1: u = ser.write( b'r') u=0 ff=ser.read(1) #print(1111) if ff==b'B': i=0 # print("right") if center > 320: i=1 while i: while u!=1: u = ser.write( b'l') u=0 ff=ser.read(1) print(1111) if ff==b'B': i=0 #print("left") global step_right global step_left if center > 360: step_right = step_right + 1 step_left = step_left - 1 if step_left < 0: step_left = 0 if step_right < 30: step() else: step_right = 30 if (center < 250 and center != 0): step_right = step_right - 1 step_left = step_left + 1 if step_right < 0: step_right = 0 if step_left < 30: step() else: step_left = 30 

La fonction de contrôle vertical est presque la même. Les différences sont décrites ci-dessus.

Dans le Maine, nous recevons déjà deux objets du réseau neuronal du réseau. Le premier est une image avec la position peinte de l'objet, et le second est un tableau d'objets détectés avec leurs coordonnées.

  detected_copy, detections = detector.detectObjectsFromImage(input_image=frame, input_type ="array", output_type = "array") for eachObject in detections: if eachObject["name"] == "person": str1 = eachObject["box_points"] str2= str(str1) n = 1 for i in range(5): if str2[i] in [","]: detect1 = int(str2[1:i]) #print(detect1) print (eachObject["box_points"]) 

Maintenant, le code pour MK


Fonction de réception de données via un port de communication virtuel.

 static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ //USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); strncpy(buffer,(char*)Buf,*Len); /* if ((buffer[0] == 0x76)&&(h == 0)) { // h=1; //i=0; CDC_Transmit_FS("B", 1); }*/ if (buffer[0] == 0x76)//v { step = 1; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x73)///s { step = 0; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x6C)//l { dir = 0; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x72)///r { dir = 1; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x56)///V { step1 = 1; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x53)////S { step1 = 0; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x4c)////L { dir1 = 0; CDC_Transmit_FS("B", 1); } if (buffer[0] == 0x52)///R { dir1 = 1; CDC_Transmit_FS("B", 1); } /* picture[i]=buffer[0]; ///CDC_Transmit_FS("Z", 1); i ++; if(i == 9599) { start = 1; }*/ /// CDC_Transmit_FS((unsigned char*)str_rx, strlen(str_rx)); USBD_CDC_ReceivePacket(&hUsbDeviceFS); //CDC_Transmit_FS((unsigned char*)str_rx, strlen(str_rx)); return (USBD_OK); /* USER CODE END 6 */ } 

Gestion des pilotes d'étape. Si étape == 1, nous prenons une impulsion et obtenons une étape. La direction est définie dans la variable dir

  if(step == 1) { GPIOC->ODR &= ~(1<<0); HAL_Delay(1); GPIOC->ODR |= 1<<0; HAL_Delay(1); i++; if(i == 1) { i = 0; step = 0; /* if(dir == 0) { dir = 1; } else { dir = 0; } ////HAL_Delay(1000);*/ } } if(dir == 1) { GPIOC->ODR |= 1<<1; } else { GPIOC->ODR &= ~(1<<1); } if(step1 == 1) { GPIOC->ODR &= ~(1<<2); HAL_Delay(1); GPIOC->ODR |= 1<<2; HAL_Delay(1); i1++; if(i1 == 1) { i1 = 0; step1 = 0; /* if(dir1 == 0) { dir1 = 1; } else { dir1 = 0; } ////HAL_Delay(1000);*/ } } if(dir1 == 1) { GPIOC->ODR |= 1<<3; } else { GPIOC->ODR &= ~(1<<3); } 

Eh bien, c'est tout.


Lien vers la source

Un grand merci à Artem Lisin pour l'aide à l'écriture du programme en python!

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


All Articles