Kamera mit Tracking-Funktion

Ich möchte eine autonome Drohne bauen, die selbst den Weg zum Ziel und zurück findet und dabei alle Hindernisse umgeht, ohne jemanden zu treffen. Ich beschloss, mit einem neuronalen Netzwerk und einer Webcam zu beginnen. Und so stellte sich dieses Projekt heraus Bild

Die Essenz des Projekts ist ein neuronales Netzwerk oder vielmehr das in Python unter Keras geschriebene imageai-Framework, das eine Person auf dem Bild findet und die Koordinaten seiner Box ausgibt. Weiter entlang der Horizontalen finden wir die Mitte des Blocks und bewegen die Kamera dorthin (wobei natürlich etwas Hysterese für die Kamera verbleibt, damit sie nicht hin und her springt). Als nächstes finden wir die zweite Mitte, aber bereits vertikal, fügen Sie einige Dutzend Pixel hinzu, damit die Kamera sein Gesicht erfasst, wenn eine Person steht. Ich wollte auch Gesichtserkennung anbringen, aber die Webcam ist billig und hat daher keine Autofokus-Funktion.

Für das Projekt hat es gedauert


STM32f4discovery - Debug-Board
MT415 ein paar Lokführer
2 Schrittmotoren
Netzteil 24 V 2,5 A
ImageAI

Ich werde den Python-Code kurz beschreiben


Imageai wird initialisiert. Wählen Sie den Typ des neuronalen Netzwerks - Yolo und die Größe des Bildblitzes. Beim Blitzlicht wird das Bild auf eine kleine Größe reduziert (ich weiß nicht mehr, welche), und das Netzwerk wird dadurch beschleunigt.

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

Funktionen zum Senden eines Zeichens an den Mikrocontroller für einen Schritt entlang der horizontalen und vertikalen Achse

 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 

Die Funktion, die die Position des linken und rechten Rahmens der Box am Eingang erhält, findet die Mitte und entscheidet, in welche Richtung gedreht werden muss, damit sich das Objekt in der Mitte der Kamera befindet. Auch hier werden Steuerzeichen an Mikrometer gesendet.

 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 

Die vertikale Steuerfunktion ist nahezu identisch. Die Unterschiede sind oben beschrieben.

In Maine empfangen wir bereits zwei Objekte aus dem neuronalen Netzwerk des Netzwerks. Das erste ist ein Bild mit der gemalten Position des Objekts, und das zweite ist ein Array von erkannten Objekten mit ihren Koordinaten.

  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"]) 

Nun der Code für MK


Funktion zum Empfangen von Daten über einen virtuellen COM-Port.

 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 */ } 

Schritttreiber verwalten. Wenn step == 1, dann nehmen wir einen Impuls und bekommen einen Schritt. Die Richtung wird in der Variablen dir festgelegt

  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); } 

Nun, das ist es im Grunde.


Link zur Quelle

Vielen Dank an Artem Lisin für die Hilfe beim Schreiben des Programms in Python!

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


All Articles