欢迎单击如下公众号“计算机视觉之光”,关注我们。
84 计算机视觉在无人机技术中的应用
无人机技术近年来取得了巨大的进展,实现无人机的自动飞行和任务执行,离不开计算机视觉的支持。本节我们将深入探讨计算机视觉在无人机技术中的应用,并通过OpenCV-Python对相关技术进行实现。
一、计算机视觉在无人机中的应用场景
实时目标跟踪:无人机实时跟踪目标物体,如人、车辆等,用于安全监控、物流配送等。 环境感知与避障:通过视觉传感器感知周围环境,避免碰撞,确保飞行安全。 **地图构建与定位 (SLAM)**:自主构建环境地图,实现无人机室内外自主导航。 精确着陆:通过视觉引导实现无人机在指定地点精确降落。
二、相关OpenCV函数的介绍
在应用场景中,我们会运用到一些核心的OpenCV函数和技术,在此做简要介绍。
1. 目标检测与跟踪
1.1 YOLO (You Only Look Once) 实时目标检测
YOLO是目前最流行的目标检测算法之一,适合无人机实时检测任务。
使用OpenCV加载YOLO模型函数如下:
def load_yolo_model(config_path, weights_path, names_path):
net = cv2.dnn.readNet(weights_path, config_path)
with open(names_path, 'r') as f:
classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
return net, classes, output_layers
参数: config_path
: YOLO配置文件的路径。weights_path
: YOLO预训练权重文件的路径。names_path
: 类别名称文件的路径。
返回值: net
: 初始化的YOLO网络。classes
: 类别名称列表。output_layers
: YOLO的输出层名称。
1.2 目标检测与绘制边界框
通过YOLO模型进行目标检测并绘制边界框:
def detect_objects(net, output_layers, image):
blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
return outs
def draw_labels(outs, classes, image):
Height, Width = image.shape[:2]
boxes = []
class_ids = []
confidences = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * Width)
center_y = int(detection[1] * Height)
w = int(detection[2] * Width)
h = int(detection[3] * Height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indices:
i = i[0]
box = boxes[i]
x, y, w, h = box[0], box[1], box[2], box[3]
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
label = str(classes[class_ids[i]])
cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return image
参数: outs
: YOLO网络的输出。classes
: 类别名称列表。image
: 输入图像。
返回值: image
: 绘制了边界框和标签的图像。
2. 环境感知与避障
2.1 深度感知 (Stereo Vision)
通过双目相机获取深度信息从而实现避障。
def calculate_disparity(left_image, right_image):
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
gray_left = cv2.cvtColor(left_image, cv2.COLOR_BGR2GRAY)
gray_right = cv2.cvtColor(right_image, cv2.COLOR_BGR2GRAY)
disparity = stereo.compute(gray_left, gray_right)
return disparity
参数: left_image
: 左目图像。right_image
: 右目图像。
返回值: disparity
: 视差图,包含深度信息。
3. 精确着陆
3.1 基于视觉的标志检测
无人机可以识别地面标志符号,从而精确降落。可以使用OpenCV的形状检测功能实现。
def find_marker(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)
contours, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
c = max(contours, key=cv2.contourArea)
return cv2.minAreaRect(c)
参数: image
: 输入图像。
返回值: marker
: 最小外接矩形,包括中心点和角度。
三、综合示例
下面我们通过一个综合示例,展示如何利用YOLO进行目标检测,实现无人机的实时目标跟踪。
# 作者:李立宗
# 公众号:计算机视觉之光
import cv2
import numpy as np
def load_yolo_model(config_path, weights_path, names_path):
print(f"Loading YOLO model with config: {config_path}, weights: {weights_path}, names: {names_path}")
try:
net = cv2.dnn.readNet(weights_path, config_path)
print("YOLO network loaded successfully.")
except Exception as e:
print(f"Failed to load network: {e}")
return None, None, None
# Read class names
try:
with open(names_path, 'r') as f:
classes = [line.strip() for line in f.readlines()]
print(f"Classes: {classes}")
except Exception as e:
print(f"Failed to read class names: {e}")
return None, None, None
layer_names = net.getLayerNames()
print(f"Network layer names: {layer_names}")
try:
unconnected_out_layers = net.getUnconnectedOutLayers()
print(f"Unconnected out layers: {unconnected_out_layers}")
if unconnected_out_layers.ndim == 1:
output_layers = [layer_names[i - 1] for i in unconnected_out_layers]
else:
output_layers = [layer_names[i[0] - 1] for i in unconnected_out_layers]
print(f"Output layers: {output_layers}")
except IndexError as e:
print(f"IndexError: {e}. Check if the config or weights paths are correct and if the model is compatible with your OpenCV version.")
return None, None, None
return net, classes, output_layers
# 目标检测
def detect_objects(net, output_layers, image):
blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
return outs
# 绘制边界框
def draw_labels(outs, classes, image):
Height, Width = image.shape[:2]
boxes = []
class_ids = []
confidences = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * Width)
center_y = int(detection[1] * Height)
w = int(detection[2] * Width)
h = int(detection[3] * Height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indices:
box = boxes[i]
x, y, w, h = box[0], box[1], box[2], box[3]
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
label = str(classes[class_ids[i]])
cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return image
# 主程序
def main():
config_path = 'yolov3.cfg' # 配置文件路径
weights_path = 'yolov3.weights' # 权重文件路径
names_path = 'coco.names' # 类别名称文件路径
net, classes, output_layers = load_yolo_model(config_path, weights_path, names_path)
if not output_layers: # 检查是否成功加载输出层
print("Failed to load YOLO model.")
return
# 打开摄像头
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Error: Unable to open the video capture.")
return
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
outs = detect_objects(net, output_layers, frame)
frame = draw_labels(outs, classes, frame)
cv2.imshow('Image', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
解释: load_yolo_model
函数用于加载YOLO模型配置、权重和类别文件。detect_objects
函数用于利用YOLO模型对图像进行目标检测。draw_labels
函数用于在检测到的目标上绘制边界框和类别标签。main
函数是主程序,使用摄像头捕获视频帧,进行实时目标检测并显示。
通过上述示例,我们展示了如何应用OpenCV实现无人机的目标跟踪,为计算机视觉在无人机技术中的应用提供了实践参考。
本节小结
本节我们详细介绍了计算机视觉在无人机技术中的应用,包括实时目标跟踪、环境感知与避障、精确着陆等核心场景。通过学习YOLO模型的配置与应用及其他相关技术,读者能够掌握无人机视觉应用的基础方法,并能应用这些方法解决实际的问题。希望大家能够通过本节的学习,为将来从事无人机视觉开发打下坚实的基础。
资料1
https://dojofordrones.com/opencv-drone/
资料2
https://learnopencv.com/category/drone-programming/
https://learnopencv.com/drone-programming-with-computer-vision/
资料3https://pyimagesearch.com/autonomous-drones-with-computer-vision-and-opencv/
参考资料:
https://www.computervision.zone/dsc/
https://github.com/puku0x/cvdrone
https://github.com/Kenil16/master_project
https://arxiv.org/pdf/2104.09815
https://github.com/topics/drone-detection
使用的源文件及素材下载在知识星球:
这里简单介绍了一些基本知识点,更细致的内容请参考:
84 计算机视觉在无人机技术中的应用
无人机技术近年来取得了巨大的进展,实现无人机的自动飞行和任务执行,离不开计算机视觉的支持。本节我们将深入探讨计算机视觉在无人机技术中的应用,并通过OpenCV-Python对相关技术进行实现。
一、计算机视觉在无人机中的应用场景
实时目标跟踪:无人机实时跟踪目标物体,如人、车辆等,用于安全监控、物流配送等。 环境感知与避障:通过视觉传感器感知周围环境,避免碰撞,确保飞行安全。 **地图构建与定位 (SLAM)**:自主构建环境地图,实现无人机室内外自主导航。 精确着陆:通过视觉引导实现无人机在指定地点精确降落。
二、相关OpenCV函数的介绍
在应用场景中,我们会运用到一些核心的OpenCV函数和技术,在此做简要介绍。
1. 目标检测与跟踪
1.1 YOLO (You Only Look Once) 实时目标检测
YOLO是目前最流行的目标检测算法之一,适合无人机实时检测任务。 使用OpenCV加载YOLO模型函数如下:
def load_yolo_model(config_path, weights_path, names_path):
net = cv2.dnn.readNet(weights_path, config_path)
with open(names_path, 'r') as f:
classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
return net, classes, output_layers
参数: config_path
: YOLO配置文件的路径。weights_path
: YOLO预训练权重文件的路径。names_path
: 类别名称文件的路径。返回值: net
: 初始化的YOLO网络。classes
: 类别名称列表。output_layers
: YOLO的输出层名称。
1.2 目标检测与绘制边界框
通过YOLO模型进行目标检测并绘制边界框:
def detect_objects(net, output_layers, image):
blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
return outs
def draw_labels(outs, classes, image):
Height, Width = image.shape[:2]
boxes = []
class_ids = []
confidences = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * Width)
center_y = int(detection[1] * Height)
w = int(detection[2] * Width)
h = int(detection[3] * Height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indices:
i = i[0]
box = boxes[i]
x, y, w, h = box[0], box[1], box[2], box[3]
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
label = str(classes[class_ids[i]])
cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return image
参数: outs
: YOLO网络的输出。classes
: 类别名称列表。image
: 输入图像。返回值: image
: 绘制了边界框和标签的图像。
2. 环境感知与避障
2.1 深度感知 (Stereo Vision)
通过双目相机获取深度信息从而实现避障。
def calculate_disparity(left_image, right_image):
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
gray_left = cv2.cvtColor(left_image, cv2.COLOR_BGR2GRAY)
gray_right = cv2.cvtColor(right_image, cv2.COLOR_BGR2GRAY)
disparity = stereo.compute(gray_left, gray_right)
return disparity
参数: left_image
: 左目图像。right_image
: 右目图像。返回值: disparity
: 视差图,包含深度信息。
3. 精确着陆
3.1 基于视觉的标志检测
无人机可以识别地面标志符号,从而精确降落。可以使用OpenCV的形状检测功能实现。
def find_marker(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)
contours, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
c = max(contours, key=cv2.contourArea)
return cv2.minAreaRect(c)
参数: image
: 输入图像。返回值: marker
: 最小外接矩形,包括中心点和角度。
三、综合示例
下面我们通过一个综合示例,展示如何利用YOLO进行目标检测,实现无人机的实时目标跟踪。
# 作者:李立宗
# 公众号:计算机视觉之光
import cv2
import numpy as np
def load_yolo_model(config_path, weights_path, names_path):
print(f"Loading YOLO model with config: {config_path}, weights: {weights_path}, names: {names_path}")
try:
net = cv2.dnn.readNet(weights_path, config_path)
print("YOLO network loaded successfully.")
except Exception as e:
print(f"Failed to load network: {e}")
return None, None, None
# Read class names
try:
with open(names_path, 'r') as f:
classes = [line.strip() for line in f.readlines()]
print(f"Classes: {classes}")
except Exception as e:
print(f"Failed to read class names: {e}")
return None, None, None
layer_names = net.getLayerNames()
print(f"Network layer names: {layer_names}")
try:
unconnected_out_layers = net.getUnconnectedOutLayers()
print(f"Unconnected out layers: {unconnected_out_layers}")
if unconnected_out_layers.ndim == 1:
output_layers = [layer_names[i - 1] for i in unconnected_out_layers]
else:
output_layers = [layer_names[i[0] - 1] for i in unconnected_out_layers]
print(f"Output layers: {output_layers}")
except IndexError as e:
print(f"IndexError: {e}. Check if the config or weights paths are correct and if the model is compatible with your OpenCV version.")
return None, None, None
return net, classes, output_layers
# 目标检测
def detect_objects(net, output_layers, image):
blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
return outs
# 绘制边界框
def draw_labels(outs, classes, image):
Height, Width = image.shape[:2]
boxes = []
class_ids = []
confidences = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * Width)
center_y = int(detection[1] * Height)
w = int(detection[2] * Width)
h = int(detection[3] * Height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indices:
box = boxes[i]
x, y, w, h = box[0], box[1], box[2], box[3]
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
label = str(classes[class_ids[i]])
cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return image
# 主程序
def main():
config_path = 'yolov3.cfg' # 配置文件路径
weights_path = 'yolov3.weights' # 权重文件路径
names_path = 'coco.names' # 类别名称文件路径
net, classes, output_layers = load_yolo_model(config_path, weights_path, names_path)
if not output_layers: # 检查是否成功加载输出层
print("Failed to load YOLO model.")
return
# 打开摄像头
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Error: Unable to open the video capture.")
return
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
outs = detect_objects(net, output_layers, frame)
frame = draw_labels(outs, classes, frame)
cv2.imshow('Image', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
解释: load_yolo_model
函数用于加载YOLO模型配置、权重和类别文件。detect_objects
函数用于利用YOLO模型对图像进行目标检测。draw_labels
函数用于在检测到的目标上绘制边界框和类别标签。main
函数是主程序,使用摄像头捕获视频帧,进行实时目标检测并显示。
通过上述示例,我们展示了如何应用OpenCV实现无人机的目标跟踪,为计算机视觉在无人机技术中的应用提供了实践参考。
本节小结
本节我们详细介绍了计算机视觉在无人机技术中的应用,包括实时目标跟踪、环境感知与避障、精确着陆等核心场景。通过学习YOLO模型的配置与应用及其他相关技术,读者能够掌握无人机视觉应用的基础方法,并能应用这些方法解决实际的问题。希望大家能够通过本节的学习,为将来从事无人机视觉开发打下坚实的基础。
资料1
https://dojofordrones.com/opencv-drone/
资料2
https://learnopencv.com/category/drone-programming/
https://learnopencv.com/drone-programming-with-computer-vision/
资料3https://pyimagesearch.com/autonomous-drones-with-computer-vision-and-opencv/
参考资料:
https://www.computervision.zone/dsc/
https://github.com/puku0x/cvdrone
https://github.com/Kenil16/master_project
https://arxiv.org/pdf/2104.09815
https://github.com/topics/drone-detection
使用的源文件及素材下载在知识星球:
这里简单介绍了一些基本知识点,更细致的内容请参考:
李立宗,OpenCV轻松入门(第2版),电子工业出版社,2023
李立宗,计算机视觉40例(从入门到深度学习:OpenCV-Python),电子工业出版社,2022
单击【阅读原文】参加OpenCV-Python课程学习。
单击【阅读原文】参加OpenCV-Python课程学习。
在本公众号【计算机视觉之光】回复关键字“叮叮当当”获取更多的Python学习资料。