Câmera com função de rastreamento

Quero fazer um drone autônomo que possa encontrar o caminho para o gol e voltar, evitando todos os obstáculos sem atingir ninguém. Eu decidi começar com uma rede neural e webcam. E esse projeto acabou imagem

A essência do projeto é uma rede neural, ou melhor, o quadro imagético escrito em python sob keras, encontra uma pessoa na imagem e fornece as coordenadas de sua caixa. Mais adiante, na horizontal, encontramos o centro do bloco e movemos a câmera para lá (naturalmente deixando alguma histerese para a câmera, para que ela não pule para frente e para trás). Em seguida, encontramos o segundo centro, mas já na vertical, adicionamos várias dezenas de pixels a ele, para que quando uma pessoa estiver de pé, a câmera capture o rosto. Eu também queria anexar o reconhecimento de rosto, mas a webcam é barata e, portanto, não possui uma função de foco automático.

Para o projeto que levou


STM32f4discovery - placa de depuração
MT415 um par de motoristas
2 motores de passo
PSU 24 V 2,5 A
ImageAI

Descreverei brevemente o código python


Inicializando imagens. Selecione o tipo de rede neural - yolo e o tamanho da imagem - flash. Quando flash, a imagem é reduzida para um tamanho pequeno (não me lembro qual) e, por isso, a rede acelera.

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

Funções para enviar um caractere ao microcontrolador por um passo no eixo horizontal e 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 

A função que recebe a posição da borda esquerda e direita da caixa na entrada localiza o centro e decide para que lado é necessário girar para que o objeto fique no meio da câmera. Novamente, os caracteres de controle são enviados para mícrons.

 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 

A função de controle vertical é quase a mesma. As diferenças estão descritas acima.

Em maine, já recebemos dois objetos da rede neural da rede. A primeira é uma imagem com a posição pintada do objeto e a segunda é uma matriz de objetos detectados com suas coordenadas.

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

Agora o código para MK


Função para receber dados através de uma porta virtual.

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

Gerenciando drivers de etapa. Se o passo == 1, tomamos um impulso e obtemos um passo. A direção é definida na variável 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); } 

Bem, é basicamente isso.


Link para fonte

Muito obrigado a Artem Lisin pela ajuda na criação do programa em python!

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


All Articles