├── README.md ├── inRange2.py ├── inRange.py ├── line_2019.py ├── aim_area.py ├── line_walking.py └── rectangle_walking.py /README.md: -------------------------------------------------------------------------------- 1 | # drone 2 | 无人机视觉(opencv) 3 | 4 | inRange : 目标跟踪、颜色识别。 5 | blog : https://blog.csdn.net/LNL_LNL/article/details/99675801 6 | 7 | inRange2 : 识别黄色条形码并保存图片。 8 | 9 | line_walking : 巡线、识别交点。 10 | blog : https://blog.csdn.net/LNL_LNL/article/details/100119625 11 | 12 | rectangle_walking: 绕矩形框飞行(没有实际测飞过),参照 line_walking 博客。 13 | 14 | aim_area : 目标区域提取. 15 | blog : https://blog.csdn.net/LNL_LNL/article/details/100126127 16 | 17 | line_2019 : 2019电赛识别电缆线. 18 | blog : https://blog.csdn.net/LNL_LNL/article/details/100127957 19 | -------------------------------------------------------------------------------- /inRange2.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import time 4 | 5 | cap = cv2.VideoCapture(0) 6 | cap.set(3, 640) 7 | cap.set(4, 480) 8 | time.sleep(1.0) 9 | 10 | OK = True 11 | 12 | print('ready...') 13 | 14 | while (True): 15 | ret, frame = cap.read() 16 | 17 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 18 | 19 | mask_yellow = cv2.inRange(hsv, np.array((26., 43., 46)), np.array((34., 255., 255.))) 20 | mask_yellow = cv2.medianBlur(mask_yellow, 3) 21 | cnts_yellow = cv2.findContours(mask_yellow.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 22 | cnts_yellow = cnts_yellow[0] if imutils.is_cv2() else cnts_yellow[1] 23 | 24 | if (len(cnts_yellow) > 0): 25 | area = [cv2.contourArea(i) for i in cnts_yellow] 26 | index = np.argmax(area) 27 | maxarea = max(area) 28 | rect_yellow = cv2.minAreaRect(cnts_yellow[index]) 29 | box_yellow = np.int0(cv2.boxPoints(rect_yellow)) 30 | cv2.drawContours(frame, [box_yellow], 0, (0, 0, 255), 2) 31 | 32 | if OK == True and maxarea > 20: 33 | cv2.imwrite('yellow.jpg',frame) 34 | OK = False 35 | 36 | cv2.imshow('frame', frame) 37 | cv2.imshow('mask_yellow', mask_yellow) 38 | 39 | cv2.waitKey(2) 40 | -------------------------------------------------------------------------------- /inRange.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import imutils 4 | 5 | 6 | frame = cv2.imread("UAV.jpg") 7 | frame = imutils.resize(frame, width=320) 8 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 9 | 10 | mask_red = cv2.inRange(hsv, np.array((110., 50., 50)), np.array((170., 255., 255.))) 11 | mask_red = cv2.medianBlur(mask_red, 3) 12 | cnts_red = cv2.findContours(mask_red.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 13 | cnts_red = cnts_red[0] if imutils.is_cv2() else cnts_red[1] 14 | 15 | mask_blue = cv2.inRange(hsv, np.array((40., 50., 50.)), np.array((140., 255., 255.))) 16 | mask_blue = cv2.medianBlur(mask_blue, 3) 17 | cnts_blue = cv2.findContours(mask_blue.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 18 | cnts_blue = cnts_blue[0] if imutils.is_cv2() else cnts_blue[1] 19 | 20 | if (len(cnts_red) > 0): 21 | area = [cv2.contourArea(i) for i in cnts_red] 22 | index = np.argmax(area) 23 | rect_red = cv2.minAreaRect(cnts_red[index]) 24 | box_red = np.int0(cv2.boxPoints(rect_red)) 25 | cv2.drawContours(frame, [box_red], 0, (0, 0, 255), 2) 26 | cv2.putText(frame,"head",(int(rect_red[0][0]),int(rect_red[0][1])),cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0), 1) 27 | 28 | 29 | if (len(cnts_blue) > 0): 30 | area = [cv2.contourArea(i) for i in cnts_blue] 31 | index = np.argmax(area) 32 | rect_blue = cv2.minAreaRect(cnts_blue[index]) 33 | box_blue = np.int0(cv2.boxPoints(rect_blue)) 34 | cv2.drawContours(frame, [box_blue], 0, (0, 0, 255), 2) 35 | cv2.putText(frame, "tail", (int(rect_blue[0][0]), int(rect_blue[0][1])),cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0), 1) 36 | 37 | cv2.line(frame,(int(rect_red[0][0]),int(rect_red[0][1])), (int(rect_blue[0][0]), int(rect_blue[0][1])),(0, 255, 0),2) 38 | 39 | cv2.imshow('frame', frame) 40 | cv2.imshow('mask_red', mask_red) 41 | cv2.imshow('mask_blue', mask_blue) 42 | 43 | cv2.waitKey(0) 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /line_2019.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import numpy as np 3 | import imutils 4 | import time 5 | import cv2 6 | 7 | # Position 8 | Postion_x = 80 9 | Postion_y = 60 10 | 11 | cap = cv2.VideoCapture(0) 12 | cap.set(3, 320) 13 | cap.set(4, 240) 14 | time.sleep(2.0) 15 | print("ready...") 16 | 17 | 18 | if __name__ == '__main__': 19 | while (True): 20 | distance = 0 21 | index = 0 22 | ok = True 23 | 24 | ret, frame = cap.read() 25 | 26 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 27 | ret, th1 = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY_INV) 28 | mask = cv2.dilate(th1, None, iterations=1) 29 | cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 30 | cnts = cnts[0] if imutils.is_cv2() else cnts[1] 31 | 32 | if len(cnts) > 0: 33 | j=0 34 | for i in cnts: 35 | x_max = max(i[:,:,0]) 36 | x_min = min(i[:,:,0]) 37 | if(x_max-x_min > distance): 38 | distance = x_max-x_min 39 | index = j 40 | j += 1 41 | 42 | c = cnts[index] 43 | 44 | mid = np.median(c[:,:,1]) 45 | for i in c: 46 | if i[0][1] - mid > 20 or i[0][1] - mid <-20: 47 | ok = False 48 | i[0][1] = mid 49 | 50 | rect = cv2.minAreaRect(c) 51 | box = np.int0(cv2.boxPoints(rect)) 52 | cv2.drawContours(frame, [box], 0, (0, 0, 255), 2) 53 | Postion_x = int(rect[0][0]//2) 54 | Postion_y = int(rect[0][1]//2) 55 | else: 56 | Postion_x = 80 57 | Postion_y = 60 58 | 59 | 60 | cv2.circle(frame,(Postion_x*2,Postion_y*2),4,(0,0,255),-1) 61 | 62 | print('ok:',ok) 63 | print('Postion_x,Postion_y', Postion_x, Postion_y) 64 | 65 | cv2.imshow('frame',frame) 66 | cv2.waitKey(2) 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /aim_area.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import imutils 4 | from imutils.perspective import four_point_transform 5 | 6 | 7 | frame = cv2.imread("cut3.JPG") 8 | frame = imutils.resize(frame, width=320) #调整图片大小 9 | 10 | edges = cv2.Canny(frame,100,300) #边缘检测,只是为了显示 11 | 12 | #提取白色区域 13 | hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 14 | mask = cv2.inRange(hsv, np.array((0., 0., 160)), np.array((180., 15.,255.))) 15 | mask = cv2.medianBlur(mask,3) #去椒盐噪 16 | 17 | #提取白色区域轮廓点 18 | cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 19 | cnts = cnts[0] if imutils.is_cv2() else cnts[1] 20 | aimcnt = None 21 | 22 | 23 | if len(cnts) > 0: 24 | #根据面积大小,从大到小排序 25 | cnts = sorted(cnts, key=cv2.contourArea, reverse=True) 26 | #找到目标轮廓四个角点 27 | for i in cnts: 28 | arc = cv2.arcLength(i, True) #计算周长,下面函数一般要以周长为参数 29 | approx = cv2.approxPolyDP(i, 0.1 * arc, True) #提取近似轮廓点 30 | if len(approx) == 4: 31 | aimcnt = approx 32 | break 33 | 34 | #rect = cv2.minAreaRect(cnts[0]) 35 | #box = np.int0(cv2.boxPoints(rect)) #这里也能得到四个轮廓点,只是在这幅图中效果没有上面方法理想 36 | 37 | 38 | #绘制四个目标轮廓点 39 | newFrame=frame.copy() 40 | for i in aimcnt: 41 | cv2.circle(newFrame, (i[0][0],i[0][1]),4, (0, 0, 255), -1) 42 | 43 | 44 | #提取目标区域 45 | aimFrame = four_point_transform(frame, aimcnt.reshape(4, 2)) 46 | aimMask = four_point_transform(mask, aimcnt.reshape(4, 2)) 47 | aimEdges = four_point_transform(edges, aimcnt.reshape(4, 2)) 48 | 49 | aimGray = cv2.cvtColor(aimFrame,cv2.COLOR_BGR2GRAY) #转化为灰度图,进行霍夫圆检测 50 | 51 | #检测圆 52 | circles = cv2.HoughCircles(aimGray,cv2.HOUGH_GRADIENT,1,100,param1=100,param2=20,minRadius=1,maxRadius=20) 53 | 54 | #绘出圆 55 | if circles is not None: 56 | for i in circles[0,:]: 57 | cv2.circle(aimFrame,(i[0],i[1]),i[2],(255,0,0),2) 58 | Circles_x = int(i[0]) 59 | Circles_y = int(i[1]) 60 | cv2.line(aimFrame, (circles[0][0][0], circles[0][0][1]), (circles[0][1][0], circles[0][1][1]), (255, 0, 0), 2) 61 | else: 62 | Circles_x = 160 #开启摄像头时的图像中点 63 | Circles_y = 120 64 | 65 | 66 | cv2.imshow('newFrame',newFrame) 67 | cv2.imshow('mask',mask) 68 | cv2.imshow('edges',edges) 69 | 70 | cv2.imshow('aimFrame',aimFrame) 71 | cv2.imshow('aimMask',aimMask) 72 | cv2.imshow('aimEdges',aimEdges) 73 | 74 | 75 | cv2.waitKey(0) 76 | -------------------------------------------------------------------------------- /line_walking.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import imutils 4 | import time 5 | 6 | cap = cv2.VideoCapture(0) 7 | cap.set(3,320) 8 | cap.set(4,240) 9 | time.sleep(2.0) 10 | print("ready...") 11 | 12 | 13 | if __name__ == '__main__': 14 | while(True): 15 | 16 | ret,frame = cap.read() 17 | frame = imutils.resize(frame, width=160) #调整图片大小 18 | 19 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 20 | ret, th1 = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY_INV) #转化为二值图 21 | mask = cv2.dilate(th1, None, iterations=1) #膨胀一下,补足一些残缺部分 22 | 23 | ROImask = mask[0:120, 50:110] 24 | cnts2 = cv2.findContours(ROImask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 25 | cnts2 = cnts2[0] if imutils.is_cv2() else cnts2[1] 26 | 27 | if (len(cnts2) > 0): 28 | #取得面积最大的轮廓并重绘(减少噪音干扰) 29 | area = [cv2.contourArea(i) for i in cnts2] 30 | area = np.array(area) 31 | index = np.argmax(area) 32 | img = np.zeros(ROImask.shape) 33 | im = cv2.drawContours(img, cnts2, index, 255, -1) 34 | 35 | #求交点X坐标 (可以封装成函数) 36 | x_acc = np.sum(im, axis=0) 37 | x_diff = np.diff(x_acc) 38 | x_index1 = np.argmax(x_diff) 39 | x_index2 = np.argmin(x_diff) + 1 40 | x_max = max(x_diff) 41 | x_min = min(x_diff) 42 | 43 | if (x_max < 1000 and x_min > -1000): 44 | Postion_x = 80 45 | else: 46 | Postion_x = (x_index1 + x_index2) // 2 + 50 #ROImask取的范围在[50,110],所以+50 47 | 48 | # 求交点Y坐标 49 | y_acc = np.sum(im, axis=1) 50 | y_diff = np.diff(y_acc) 51 | y_index1 = np.argmax(y_diff) 52 | y_index2 = np.argmin(y_diff) + 1 53 | y_max = max(y_diff) 54 | y_min = min(y_diff) 55 | 56 | if (y_max < 1000 and y_min > -1000): 57 | Postion_y = 60 58 | else: 59 | Postion_y = (y_index1 + y_index2) // 2 60 | 61 | else: 62 | Postion_x = 80 63 | Postion_y = 60 64 | 65 | cv2.circle(frame, (Postion_x, Postion_y), 4, (0, 0, 255), -1) 66 | 67 | print('Postion_x,Postion_y', Postion_x, Postion_y) 68 | 69 | cv2.imshow('frame', frame) 70 | cv2.imshow('mask', mask) 71 | 72 | k = cv2.waitKey(2) 73 | if k==27: 74 | break 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /rectangle_walking.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import numpy as np 3 | import imutils 4 | import serial 5 | import time 6 | import cv2 7 | 8 | 9 | #Position 10 | Postion_x = 80 11 | Postion_y = 60 12 | 13 | land = 0 14 | turn = False 15 | num = 0 16 | 17 | cap = cv2.VideoCapture(0) 18 | cap.set(3,320) 19 | cap.set(4,240) 20 | print("start reading video...") 21 | time.sleep(2.0) 22 | print("start working") 23 | 24 | 25 | if __name__ == '__main__': 26 | while(True): 27 | 28 | ret,frame = cap.read() 29 | frame = imutils.resize(frame, width=160) #调整图片大小 30 | 31 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 32 | ret, img = cv2.threshold(gray,80, 255, cv2.THRESH_BINARY_INV)#转化为二值图 33 | mask = cv2.dilate(img, None, iterations=1) #膨胀一下,补足一些残缺部分 34 | 35 | #寻找x坐标 36 | x_acc = np.sum(mask,axis=0) 37 | x_diff = np.diff(x_acc) 38 | x_index1 = np.argmax(x_diff) 39 | x_index2 = np.argmin(x_diff)+1 40 | x_max = max(x_diff) 41 | x_min = min(x_diff) 42 | 43 | #寻找y坐标 44 | y_acc = np.sum(mask,axis =1) 45 | y_diff = np.diff(y_acc) 46 | y_index1 = np.argmax(y_diff) 47 | y_index2 = np.argmin(y_diff)+1 48 | y_max = max(y_diff) 49 | y_min = min(y_diff) 50 | 51 | #判断是否为拐角 52 | if(x_max <2000 and x_min>-2000 and y_max < 2000 and y_min > -2000): 53 | if turn == False: 54 | num++ 55 | turn = True 56 | else: 57 | turn = False 58 | 59 | print('num:',num) 60 | 61 | #矩形框右下角拐角为第一个点,无人机顺时针飞行 62 | if(num==1): 63 | Postion_x = 82 #控制pitch正向条件 64 | Postion_y = (y_index1+y_index2)//2 65 | elif(num==2): 66 | Postion_x = (x_index1+x_index2)//2 67 | Postion_y = 62 #控制roll正向条件 68 | elif(num==3): 69 | Postion_x = 75 #控制pitch反向条件 70 | Postion_y = (y_index1+y_index2)//2 71 | elif(num==4): 72 | Postion_x = (x_index1+x_index2)//2 73 | Postion_y = 55 #控制pitch反向条件 74 | else: 75 | land = 0x10 #降落标志位 76 | 77 | cv2.circle(frame,(Postion_x,Postion_y ),4,(0,0,255),-1) 78 | 79 | print('Postion_x,Postion_y',Postion_x,Postion_y) 80 | 81 | cv2.imshow('frame', frame) 82 | cv2.imshow('mask', mask) 83 | 84 | k = cv2.waitKey(2) 85 | if k==27: 86 | break 87 | 88 | --------------------------------------------------------------------------------