الكاميرا مع وظيفة التتبع

أريد أن أصنع طائرة بدون طيار مستقلة يمكنها أن تجد نفسها الطريق إلى الهدف والعودة ، مع تجنب كل العقبات دون ضرب أي شخص. قررت أن أبدأ بشبكة عصبية وكاميرا ويب. وهكذا تحول هذا المشروع صورة

إن جوهر المشروع هو شبكة عصبية ، أو بالأحرى إطار عمل خيال مكتوب بيثون تحت keras ، ويجد شخصًا في الصورة ويعطي إحداثيات صندوقه. علاوة على ذلك ، نجد الأفقي مركز الكتلة ونحرك الكاميرا هناك (مع ترك بعض التباطؤ بشكل طبيعي للكاميرا بحيث لا تقفز ذهابًا وإيابًا). بعد ذلك ، نجد المركز الثاني ، ولكن بالفعل رأسيًا ، نضيف عدة عشرات من البيكسلات إليه ، بحيث عندما تقف شخص ما ، تلتقط الكاميرا وجهه. أردت أيضًا إرفاق التعرف على الوجوه ، لكن كاميرا الويب رخيصة وبالتالي لا تحتوي على وظيفة ضبط تلقائي للصورة.

للمشروع استغرق الأمر


STM32f4discovery - لوحة التصحيح
MT415 زوجين من السائقين المحرك
2 السائر المحركات
PSU 24 V 2.5 A
ImageAI

سوف أصف بإيجاز رمز الثعبان


تهيئة imageai. حدد نوع الشبكة العصبية - yolo وحجم الصورة - فلاش. عند وميض ، يتم تقليل الصورة إلى حجم صغير (لا أتذكر أي واحد) ونتيجة لذلك ، تتسارع الشبكة.

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

وظائف لإرسال حرف إلى متحكم لخطوة واحدة على طول المحور الأفقي والرأسي

 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 

تقوم الوظيفة التي تستقبل موضع الحد الأيسر والأيمن من المربع عند الإدخال بالعثور على الوسط وتحديد الطريقة التي يجب بها الدوران بحيث يكون الكائن في منتصف الكاميرا. مرة أخرى ، يتم إرسال أحرف التحكم إلى الميكرونات.

 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 

وظيفة التحكم العمودي هي نفسها تقريبا. تم وصف الاختلافات أعلاه.

في مين ، تلقينا بالفعل كائنين من الشبكة العصبية للشبكة. الأول هو صورة ذات موضع ملون للكائن ، والثاني عبارة عن مجموعة من الكائنات المكتشفة مع إحداثياتها.

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

الآن رمز ل MK


وظيفة لتلقي البيانات من خلال منفذ com الظاهري.

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

إدارة السائقين خطوة. إذا كانت الخطوة == 1 فإننا نأخذ دفعة واحدة ونحصل على خطوة واحدة. يتم تعيين الاتجاه في متغير دير

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

حسنا ، هذا هو الأساس.


رابط للمصدر

شكرا جزيلا لأرتيم ليسين للمساعدة في كتابة البرنامج في بيثون!

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


All Articles