无人机实验笔记(识别交点 / 巡线) 您所在的位置:网站首页 怎样制作无人机最简单的 无人机实验笔记(识别交点 / 巡线)

无人机实验笔记(识别交点 / 巡线)

2024-07-13 14:16| 来源: 网络整理| 查看: 265

        由于我们的实验场地并不是一根纯黑线,中间的交线会对识别造成一定的影响,从而导致无人机在交线处飞偏,所以就想识别交点坐标,保证无人机始终在直线上飞行,最后的实验结果也很理想。

      识别交线代码是在网上看到的一段代码,后来发现它的算法思路很新奇,且应用过程中发现它的用武之地还蛮多的。

算法思路:

      这是一张二值化后的图,对应像素值:白色:255,黑色:0。 我用数值表示为:

      这是一张5*7大小的二值图,白色像素值为255,黑色像素值为0,我的目的是要求得(3,4)这个交点坐标。以求X坐标为例,先将每一列的值相加存入数组得到 [255, 255, 1785, 255, 255] ,可以看到出现了一个最大值1785,然后将相邻的列相减(从第二列开始,后一列减去前一列)的值存入另一个数组得到 [0,1530,-1530,0] ,可以看到出现了一个极大值和极小值,而这两个值对应的索引(列号)就是我们需要的值。取得极大值的索引:2; 极小值的索引: 3 。对应二值图可以看到,2就是我们需要求的X坐标的左邻列,3+1 就是X坐标的右邻列。最后求的 X = (2+4)/2 = 3 。同理,Y= (3 +5 )/2 = 4 。

代码:

import cv2 import numpy as np import imutils frame = cv2.imread("Cross 2.jpg") frame = imutils.resize(frame, width=160) #调整图片大小 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) ret, th1 = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY_INV) #转化为二值图 mask = cv2.dilate(th1, None, iterations=1) #膨胀一下,补足一些残缺部分 ROImask = mask[0:120, 50:110] cnts2 = cv2.findContours(ROImask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts2 = cnts2[0] if imutils.is_cv2() else cnts2[1] if (len(cnts2) > 0): #取得面积最大的轮廓并重绘(减少噪音干扰) area = [cv2.contourArea(i) for i in cnts2] area = np.array(area) index = np.argmax(area) img = np.zeros(ROImask.shape) im = cv2.drawContours(img, cnts2, index, 255, -1) #求交点X坐标 (可以封装成函数) x_acc = np.sum(im, axis=0) x_diff = np.diff(x_acc) x_index1 = np.argmax(x_diff) x_index2 = np.argmin(x_diff) + 1 x_max = max(x_diff) x_min = min(x_diff) if (x_max < 1000 and x_min > -1000): Postion_x = 80 #图像中点 else: Postion_x = (x_index1 + x_index2) // 2 + 50 #ROImask取的范围在[50,110],所以+50 # 求交点Y坐标 y_acc = np.sum(im, axis=1) y_diff = np.diff(y_acc) y_index1 = np.argmax(y_diff) y_index2 = np.argmin(y_diff) + 1 y_max = max(y_diff) y_min = min(y_diff) if (y_max < 1000 and y_min > -1000): Postion_y = 60 #图像中点 else: Postion_y = (y_index1 + y_index2) // 2 else: Postion_x = 80 Postion_y = 60 cv2.circle(frame, (Postion_x, Postion_y), 4, (0, 0, 255), -1) #画出交点 print('Postion_x,Postion_y', Postion_x, Postion_y) cv2.imshow('mask', mask) cv2.imshow('frame', frame) cv2.waitKey(0)

 结果图:

代码说明:

ROImask = mask[0:120, 50:110]

cnts2 = cv2.findContours(ROImask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cnts2 = cnts2[0] if imutils.is_cv2() else cnts2[1]

        只取了二值图中间一部分[50,110]来求解,因为无人机在飞行起点与终点,左右两边直线外的图像会带来干扰,索性只取了中间一段来求交点。当无人机飞出了终点,也就是cnts2没有轮廓点了,可以做额外的动作,比如降落。

if (x_max < 1000 and x_min > -1000):         Postion_x = 80 else:         Postion_x = (x_index1 + x_index2) // 2 + 50

    这里做了一个最大最小值判断,如果图像上不存在交点,只是一根单纯的直线。例如下图,它只能找到直线的中点Y坐标。

       这时X坐标应为图像的中点(或者往某一方向飞行所需的定值)。所以,用这个算法巡线也完全OK。( // 2 为取整。)

        缺陷:飞行时需将无人机摆正(不用完全与直线重合),因为算法是对像素的操作,如果无人机与直线倾斜的角度大了,得到的图像存在一定角度,算法就失效了。

其它应用:

  1、 绕矩形框飞行,正如一个矩形框的拐角,可以作为条件判断来控制无人机的飞行方向。

  2、在交点处悬停  

源码下载:

https://github.com/LNanL/drone

矩形框代码没有测飞过,因为没有场地。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有