Python-opencv之目标定位

2023-11-19

最近团队准备参加一个无人机比赛,大致的规则是这样的:固定翼飞机从跑道起飞,然后在空中转体360°,通过GPS粗定位飞行至一个高13米左右,宽6米左右八字形框前(距离约50米左右),这时依靠计算机视觉的方法,让飞机准确的穿过去。(之后还有其他的动作,但是第一步大体就是这样)。

    初步的方案:①通过机载摄像机获取图像序列

                        ②选取关键帧进行处理,获得框的中心点图像坐标

                        ③将框的中心点图像坐标与图像中心坐标进行比较,将偏差信息反馈给控制系统,使其自动调节

    关键点:如何准确地定位目标框,并提取出框中心点图像坐标。


——————————————————————————————————————————————

以下是一个比较简单的实现方案

    通过颜色提取出大致区域->形态学处理->轮廓提取->利用轮廓大小关系找到目标框->获得中心点信息并比较反馈


代码部分

# coding:UTF-8
import cv2
import numpy as np


class Detect:
    def __init__(self, path):
        # 原始图像信息
        self.ori_img = cv2.imread(path)
        self.gray = cv2.cvtColor(self.ori_img, cv2.COLOR_BGR2GRAY)
        self.hsv = cv2.cvtColor(self.ori_img, cv2.COLOR_BGR2HSV)
        # 获得原始图像行列
        rows, cols = self.ori_img.shape[:2]
        # 工作图像
        self.work_img = cv2.resize(self.ori_img, (cols / 4, rows / 4))
        self.work_gray = cv2.resize(self.gray, (cols / 4, rows / 4))
        self.work_hsv = cv2.resize(self.hsv, (cols / 4, rows / 4))

    # 颜色区域提取
    def color_area(self):
        # 提取红色区域(暂定框的颜色为红色)
        low_red = np.array([156, 43, 46])
        high_red = np.array([180, 255, 255])
        mask = cv2.inRange(self.work_hsv, low_red, high_red)
        red = cv2.bitwise_and(self.work_hsv, self.work_hsv, mask=mask)
        return red

    # 形态学处理
    def good_thresh_img(self, img):
        # hsv空间变换到gray空间
        img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 阈值处理
        _, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        # 做一些形态学操作,去一些小物体干扰
        img_morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, (3, 3))
        cv2.erode(img_morph, (3, 3), img_morph, iterations=2)
        cv2.dilate(img_morph, (3, 3), img_morph, iterations=2)
        return img_morph

    # 矩形四角点提取
    def key_points_tap(self, img):
        img_cp = img.copy()
        # 按结构树模式找所有轮廓
        cnts, _ = cv2.findContours(img_cp, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        # 按区域大小排序,找到第二大轮廓
        cnt_second = sorted(cnts, key=cv2.contourArea, reverse=True)[1]
        # 找轮廓的最小外接矩形((point), (w, h))
        box = cv2.minAreaRect(cnt_second)
        # ->(points)->(l_ints)
        return np.int0(cv2.cv.BoxPoints(box))

    # 画出关键轮廓的最校外接矩形
    def key_cnt_draw(self, points):
        mask = np.zeros(self.work_gray.shape, np.uint8)
        cv2.drawContours(mask, [points], -1, 255, 2)
        return mask

    # 目标框图像中心点提取
    def center_point_cal(self, points):
        pt1_x, pt1_y = points[0, 0], points[0, 1]
        pt3_x, pt3_y = points[2, 0], points[2, 1]
        center_x, center_y = (pt1_x + pt3_x) / 2, (pt1_y + pt3_y) / 2
        return center_x, center_y

    # 中心点比较,进行反馈
    def feedback(self, rect_center_point):
        # 获取矩形框中心
        rect_center_point_x, rect_center_point_y = rect_center_point[0], rect_center_point[1]
        # 得到图像中心
        rows, cols = self.work_img.shape[:2]
        img_center_x, img_center_y = cols / 2, rows / 2
        # 相对x、y
        delta_x = rect_center_point_x - img_center_x
        delta_y = rect_center_point_y - img_center_y
        # 条件判断
        print '-------------------'
        if delta_x > 0:
            print '->right'
        elif delta_x < 0:
            print 'left <-'
        else:
            print 'v_hold'

        if delta_y < 0:
            print '+up'
        elif delta_y > 0:
            print '-down'
        else:
            print 'h_hold'

    # 运行主函数
    def img_process_main(self):
        # 找到红色区域
        red = self.color_area()
        # 处理得到一个比较好的二值图
        img_morph = self.good_thresh_img(red)
        # 获取矩形框的四个关键点
        points = self.key_points_tap(img_morph)
        # 找到矩形中心点
        rect_center_point = self.center_point_cal(points)
        # 画出关键轮廓(调试用,并没有什么卯月)
        cnt_img = self.key_cnt_draw(points)
        # 反馈信息
        self.feedback(rect_center_point)

        # 显示图像
        cv2.imshow('ori', self.work_img)
        cv2.imshow('red', red)
        cv2.imshow('good_thresh', img_morph)
        cv2.imshow('cnts', cnt_img)
        cv2.waitKey(0)

        cv2.destroyAllWindows()


if __name__ == '__main__':
    root_path = './201655'
    img_index = 0
    while True:
        img_index += 1
        img_path = root_path + '/' + str(img_index) + '.bmp'
        d = Detect(img_path)
        d.img_process_main()

实际效果

    实验用的是等比例缩小做的模型。





 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python-opencv之目标定位 的相关文章

随机推荐

  • 【全站首发】最详细的jetbrains space使用方法

    目录 一 注册一个Jetbrains账号 如果有可以跳过 二 创建或加入一个space团队 包含下载软件 三 Jetbrains Space软件配置 四 软件的使用 一 注册一个Jetbrains账号 如果有可以跳过 打开Jetbrains
  • 测试工作总结

    1 软件测试定义 2 基本方法 3 流程规范 1 新需求 需求文档 原型图 蓝湖 文档分析 评审 测试计划 测试用例编写 冒烟测试用例编写 计划用例评审 跟项目组 项目组提交测试 程序员自测报告 验证自测报告 跟公司而定 有的是冒烟测试 开
  • 在 IBM Bluemix 开发及使用 Docker Images

    Node Js是云端平台开发App的主要工具 以下范例是将Bluehatter App以3中方式执行包含 1 以Node Js在localhost开发Bluehatter App后直接Deloy至IBM Bluemix云端平台执行 2 将前
  • yolov5量化部署(基于openvino和tensorrt)

    yolov5 openvino量化部署 首先 下载YOLOv5源码 安装YOLOv5和OpenVINO的python依赖 git clone https github com ultralytics yolov5 git pip insta
  • 常用的vue指令语法用法

    一 v text 相当于js的innerText 二 v bind 动态绑定属性 简写是冒号 三 v on 绑定事件 简写是 用于事件的绑定类似于js的onclick 四 v model 可以用 v model 指令在表单
  • 【Python-利用动态二维码传输文件(二)】实现文件二进制读取、利用base64编码把文件拆分成多张二维码、重组拆分后的文件并验证。

    为了使用二维码传输文件 上一篇文章已经实现了获取信息存入二维码并打印 由于单个二维码存储的信息量是有限的 而且文件一般也比较大 所以必须把文件先进行拆分 拆分后一块一块信息存入多张二维码中 最后通过图像识别 把所有二维码信息准确读取后再重新
  • 初级2 题目五 有关排序问题的补充

    1 归并排序的额外空间复杂度可以变成O 1 但是非常难 不需要掌握 可以搜 归并排序 内部缓存法 2 快速排序可以做到稳定性问题 但是非常难 不需要掌握 可以搜 01 stable sort 3 有一道题目 是奇数放在数组左边 偶数放在数组
  • 【老生谈算法】基于matlab指纹识别系统设计与算法原理详解(论文+程序源码)——指纹识别

    老生谈算法 基于matlab指纹识别系统设计与算法原理 论文 程序源码 大家好 今天给大家介绍基于matlab的指纹识别系统设计与算法原理 论文 程序源码 文章目录 老生谈算法 基于matlab指纹识别系统设计与算法原理 论文 程序源码 1
  • 服务器可以放置多少个网站?

    服务器能容纳的网站数量 是根据每个网站的大小 以及服务器的整体配置来确定的 那么影响服务器容纳网站数量的因素有哪些呢 一 网站大小 能影响一个网站大小的因素是比较多的 例如网站的设计 网站里的内容大小 通常网站尺寸比较大 动态页面比较多的
  • QtCreator 应用程序主窗口——菜单栏(QMenuBar)和工具栏(QToolBar)

    1 菜单栏 QMenuBar 和工具栏 QToolBar 1 1 将菜单项放在工具栏上面 将Action编辑器中的相应动作直接拖到工具栏上面 1 2 使用资源 添加资源文件 gt Qt资源文件 gt 添加前缀 gt 添加文件 gt 保存 使
  • JS for循环的3种使用

    1 1 for循环使用 1 for in 遍历存放对象的一维数组 var arr id 1 name 張山 id 2 name 李四 for var i in arr console log i 结果 仅仅会得到数组的索引会遍历数组的原型属
  • ARM接口编程—WDT(exynos 4412平台)

    WDT简介 Watch Dog Timer即看门狗定时器 其主要作用是当发生软件故障时可产生复位信号使SOC复位 其本质是一个计数器 WDT工作原理 WTD寄存器 wtd控制寄存器 用于设置一级分频 二级分频 使能 产生复位和中断信号 WT
  • 【redis】redis的 key的命名规则

    key的命名规则 定义为 MS TEN SESSION KEY IN LOGIN NAME fqh 使用 进行分割 这样存入redis的是有层次结构的 如下
  • Java程序员常常为这个字所困扰!Java

    Java程序员常常为这个字所困扰 Java Java是一种流行的编程语言 广泛应用于开发各种类型的应用程序 然而 有一个字在Java开发中经常让程序员感到困惑和挫败 这个字就是 异常 异常在Java中是一个重要的概念 用于处理程序运行过程中
  • Peewee的坑

    db create tables Student 当如上使用时可能会报表Student不存在的错误 官方实例如db create tables Student Pet 改成db create tables Student safe True
  • .NET概述

    1 NET技术体系结构 NET平台是Microsoft在20世纪末为了迎接互联网的挑战而推出的应用程序平台 经过近年来的发展 它如今几乎可以在任何硬件平台上发挥作用 服务器 台式机 移动设备 游戏机 虚拟现实 增强现实环境 手表 甚至诸如R
  • TestBench编写_激励产生

    TestBench编写 激励产生 TestBench编写 激励产生 基本背景 读取函数介绍 a fopen函数使用 b fread函数使用 c fclose函数使用 实际使用 TestBench编写 激励产生 基本背景 最近遇到项目中需要对
  • 采用Vivado 配置xilinx GTX的SATA设计

    从Vivado开始 配置GTX的时候 多了一个SATA协议支持 但有些小地方还需要自己另外设置 整理了一下 分享给大家 首先打开Transceivers wizard 打开页签 线速率和参考时钟选择 在协议里面选择SATA2或者SATA3
  • leetcode696题计数二进制子串

    696题计数二进制子串 给定一个字符串 s 计算具有相同数量0和1的非空 连续 子字符串的数量 并且这些子字符串中的所有0和所有1都是组合在一起的 重复出现的子串要计算它们出现的次数 示例 1 输入 00110011 输出 6 解释 有6个
  • Python-opencv之目标定位

    最近团队准备参加一个无人机比赛 大致的规则是这样的 固定翼飞机从跑道起飞 然后在空中转体360 通过GPS粗定位飞行至一个高13米左右 宽6米左右八字形框前 距离约50米左右 这时依靠计算机视觉的方法 让飞机准确的穿过去 之后还有其他的动作