OpenCV核心内容100讲【第84讲】计算机视觉在无人机技术中的应用

文摘   2024-12-15 00:01   天津  

欢迎单击如下公众号“计算机视觉之,关注我


84 计算机视觉在无人机技术中的应用

无人机技术近年来取得了巨大的进展,实现无人机的自动飞行和任务执行,离不开计算机视觉的支持。本节我们将深入探讨计算机视觉在无人机技术中的应用,并通过OpenCV-Python对相关技术进行实现。

一、计算机视觉在无人机中的应用场景

  1. 实时目标跟踪:无人机实时跟踪目标物体,如人、车辆等,用于安全监控、物流配送等。
  2. 环境感知与避障:通过视觉传感器感知周围环境,避免碰撞,确保飞行安全。
  3. **地图构建与定位 (SLAM)**:自主构建环境地图,实现无人机室内外自主导航。
  4. 精确着陆:通过视觉引导实现无人机在指定地点精确降落。

二、相关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] - 1for 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, (416416), (000), 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.50.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), (02550), 2)
        label = str(classes[class_ids[i]])
        cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (02550), 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, (55), 0)
    edged = cv2.Canny(gray, 35125)
    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 NoneNoneNone

    # 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 NoneNoneNone

    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 - 1for i in unconnected_out_layers]
        else:
            output_layers = [layer_names[i[0] - 1for 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 NoneNoneNone

    return net, classes, output_layers

# 目标检测
def detect_objects(net, output_layers, image):
    blob = cv2.dnn.blobFromImage(image, 0.00392, (416416), (000), 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.50.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), (02550), 2)
        label = str(classes[class_ids[i]])
        cv2.putText(image, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (02550), 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/

资料3

https://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模拟试卷】获得《数字图像处理(OpenCV-Python》模拟试卷及参考答案。
在公众号【计算机视觉之光】回复 【Python试卷】获得《Python程序设计》模拟试卷及参考答案。

单击【阅读原文】参加OpenCV-Python课程学习。

在本公众号【计算机视觉之光】回复关键字“叮叮当当”获取更多的Python学习资料。

欢迎单击如下公众号“计算机视觉之光”,关注我




计算机视觉之光
电子工业出版社优秀作者,代表作《OpenCV轻松入门》,《计算机视觉40例》。
 最新文章