一直想基于传统图像匹配方式做一个融合Demo,也算是对上个阶段学习的一个总结。

由此,便采购了一个摄像头,在此基础上做了实时检测平面目标的特征匹配算法。

代码如下:

# coding: utf-8
'''
@author: linxu
@contact: 17746071609@163.com
@time: 2021-07-26 上午11:54
@desc: 基于特征匹配的实时平面目标检测算法
@Ref: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.htm
''' import numpy as np
import cv2 class ObjectDetector:
""" 基于特征匹配的实时平面目标检测算法 """
def __init__(self):
# 特征点检测-选择不同的特征描述子
self.feature_detector = cv2.AKAZE_create() # Use AKAZE
# self.feature_detector = cv2.ORB_create() # Use ORB
# self.feature_detector = cv2.KAZE_create()# Use KAZE
# self.feature_detector = cv2.SIFT_create()# Use SIFT
# self.feature_detector = cv2.BRISK_create()# Use BRISK # 摄像头相机参数设置VideoCapture
self.vidcap = cv2.VideoCapture(0)
self.vidcap.set(3, 640) # 宽度
self.vidcap.set(4, 480) # 高度
self.vidcap.set(5, 15) # 帧率 # 通过ROI(感兴趣区域)来注册目标对象
self.sub_topleft = [100, 220] # [0, 0] # [y,x]100 220
self.sub_width = 200 #640 200
self.sub_height = 200 #480 200
self.sub_bottomright = [self.sub_topleft[0] + self.sub_height - 1,\
self.sub_topleft[1] + self.sub_width - 1]
# rect矩形框体
self.rect_color = (0, 255, 0) # green
self.rect_thickness = 3
self.rect_tl_outer_xy = (self.sub_topleft[1] - self.rect_thickness, self.sub_topleft[0] - self.rect_thickness)
self.rect_br_outer_xy = (self.sub_bottomright[1] + self.rect_thickness, self.sub_bottomright[0] + self.rect_thickness) # 特征(描述符)向量距离的阈值
self.ratio = 0.75
self.registered = False
self.min_match_count = 5
self.show_rectangle = True def register(self):
"""注册目标对象"""
print("\n将目标物体靠近相机.")
print("确保对象完全覆盖矩形内部(背景不可见).")
print("然后,按“r”注册对象.\n") while self.vidcap.isOpened():
ret, frame = self.vidcap.read()
cv2.rectangle(frame, self.rect_tl_outer_xy, self.rect_br_outer_xy,\
self.rect_color, self.rect_thickness)
cv2.imshow("Registration (press 'r' to register)", frame)
if cv2.waitKey(1) & 0xFF == ord('r'):
# 图像切片
subimg = frame[self.sub_topleft[0]:(self.sub_topleft[0] + self.sub_height),
self.sub_topleft[1]:(self.sub_topleft[1] + self.sub_width)]
self.kp0, self.des0 = self.feature_detector.detectAndCompute(subimg, None)
self.queryimg = subimg
self.registered = True
break def detect(self):
""" 使用特征点查找对象 """
global mask
if not self.registered:
print("Call 'register()' first.")
return print("Start detection...")
print("按“q”退出.")
print("按“h”隐藏绿色矩形.\n") # 声明一个暴力匹配器Blute-Force (BF) matcher
bf = cv2.BFMatcher() while self.vidcap.isOpened():
ret, frame = self.vidcap.read() # 关键点(kp)检测和计算描述符(des)
kp, des = self.feature_detector.detectAndCompute(frame, None) # 在关键点之间应用knn匹配
matches = bf.knnMatch(self.des0, des, k=2) # 根据阈值筛选关键特征点
# good = [[m] for m, n in matches if m.distance < self.ratio * n.distance]
good = []
for m, n in matches:
if m.distance < self.ratio * n.distance:
good.append([m])
print('len',len(good)) contours = []
# 查找单应性矩阵
if (len(good) > self.min_match_count) and self.show_rectangle:
# 建立坐标矩阵
src_pts = np.float32([self.kp0[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([kp[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2) # 计算多个二维点对之间的最优单映射变换矩阵 H
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
# Assume color camera
# cv2.imshow('queryimg',self.queryimg)
h, w, c = self.queryimg.shape
pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, M)
# cv2.circle(frame,tuple(dst_pts[0][0]),5, (255,0,0))
# cv2.circle(frame, tuple(dst_pts[1][0]), 5, (0, 255, 0))
# cv2.circle(frame, tuple(dst_pts[2][0]), 5, (0, 0, 255))
# cv2.circle(frame, tuple(dst_pts[3][0]), 5, (255, 255, 0))
# cv2.imshow('circle', frame)
frame = cv2.polylines(frame, [np.int32(dst)], True, (0, 255, 0), 2, cv2.LINE_AA) # 可视化匹配过程
# 绘画参数
# draw_params = dict(flags=2)
draw_params = dict(matchColor=(0, 255, 0), singlePointColor=(0, 0, 255),flags=0)
img = cv2.drawMatchesKnn(self.queryimg, self.kp0, frame, kp, good, None, **draw_params)
cv2.imshow("Detection (press 'q' to quit)", img) key_pressed = cv2.waitKey(1)
if key_pressed & 0xFF == ord('q'):
break if key_pressed & 0xFF == ord('h'):
self.show_rectangle = False def close(self):
""" 释放VideoCapture并销毁windows """
self.vidcap.release()
cv2.destroyAllWindows() if __name__ == '__main__':
obj_detector = ObjectDetector()
obj_detector.register()
obj_detector.detect()
obj_detector.close()

测试效果,如下:


[OpenCV]基于特征匹配的实时平面目标检测算法的更多相关文章

  1. 基于候选区域的深度学习目标检测算法R-CNN,Fast R-CNN,Faster R-CNN

    参考文献 [1]Rich feature hierarchies for accurate object detection and semantic segmentation [2]Fast R-C ...

  2. 使用Harr特征的级联分类器实现目标检测

    前言  最近在学习人脸的目标检测任务时,用了Haar人脸检测算法,这个算法实现起来太简洁了,读入个.xml,调用函数就能用.但是深入了解我发现这个算法原理很复杂,也很优秀.究其根源,于是我找了好些篇相 ...

  3. 转载:点云上实时三维目标检测的欧拉区域方案 ----Complex-YOLO

    感觉是机器翻译,好多地方不通顺,凑合看看 原文名称:Complex-YOLO: An Euler-Region-Proposal for  Real-time 3D Object Detection ...

  4. 基于模糊Choquet积分的目标检测算法

    本文根据论文:Fuzzy Integral for Moving Object Detection-FUZZ-IEEE_2008的内容及自己的理解而成,如果想了解更多细节,请参考原文.在背景建模中,我 ...

  5. 基于深度学习的目标检测算法:SSD——常见的目标检测算法

    from:https://blog.csdn.net/u013989576/article/details/73439202 问题引入: 目前,常见的目标检测算法,如Faster R-CNN,存在着速 ...

  6. CVPR2020|3D-VID:基于LiDar Video信息的3D目标检测框架

    作者:蒋天园 Date:2020-04-18 来源:3D-VID:基于LiDar Video信息的3D目标检测框架|CVPR2020 Brief paper地址:https://arxiv.org/p ...

  7. 29 基于PCL的点云平面分割拟合算法技术路线(针对有噪声的点云数据)

    0 引言 最近项目中用到了基于PCL开发的基于平面的点云和CAD模型的配准算法,点云平面提取采用的算法如下. 1 基于PCL的点云平面分割拟合算法 2 参数及其意义介绍 (1)点云下采样 1. 参数: ...

  8. 基于COCO数据集验证的目标检测算法天梯排行榜

    基于COCO数据集验证的目标检测算法天梯排行榜 AP50 Rank Model box AP AP50 Paper Code Result Year Tags 1 SwinV2-G (HTC++) 6 ...

  9. 目标检测算法的总结(R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD、FNP、ALEXnet、RetianNet、VGG Net-16)

    目标检测解决的是计算机视觉任务的基本问题:即What objects are where?图像中有什么目标,在哪里?这意味着,我们不仅要用算法判断图片中是不是要检测的目标, 还要在图片中标记出它的位置 ...

随机推荐

  1. Spark中的分区方法详解

    转自:https://blog.csdn.net/dmy1115143060/article/details/82620715 一.Spark数据分区方式简要 在Spark中,RDD(Resilien ...

  2. 【STM32】晶振,主时钟,外设频率介绍

    首先,我用的是STM32F407,下方所有图片都是出自这芯片的文档,如果型号和我不同,需要找到对应的芯片说明文档,也许会有出入 先看一张时钟图 这里会着重说明高速的部分,低速(不管内部还是外部)只给R ...

  3. CountDownLatch原理

    正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.在Java并发中,countdownlatch的概念是一 ...

  4. Mycat的事务异常:Caused by: java.sql.SQLException: Transaction error, need to rollback.Distributed transaction is disabled!

    工作中踩到的一个坑 ,一个报错,导致整个服务不能用.工程部署四个节点,请求是按轮询机制分发的,所以请求四次报错,整个系统瘫痪.记录下 . 项目环境:spring +Mybaties +mycat +D ...

  5. ABP VNext框架基础知识介绍(2)--微服务的网关

    ABP VNext框架如果不考虑在微服务上的应用,也就是开发单体应用解决方案,虽然也是模块化开发,但其集成使用的难度会降低一个层级,不过ABP VNext和ABP框架一样,基础内容都会设计很多内容,如 ...

  6. 开源企业平台Odoo 15社区版之项目管理应用模块功能简介

    项目管理无论是各类证书的认证,如PMP.软考高级的信息系统项目管理师.中级的系统集成项目管理工程师等,还是企业实践都有着广泛的实际应用中,至今还是处于热门的行业,合格的或优化的项目经理还是偏少,对于I ...

  7. Table.SplitColumn拆分…Split…(Power Query 之 M 语言)

    数据源: 一列若干行数据. 目标: 根据特定条件拆分 操作过程: 选取"品名"列>[主页](或[转换])>[拆分列] 选取"品名"列>[主页] ...

  8. CF1093B Letters Rearranging 题解

    Content 有 \(t\) 次询问,每次询问给定一个字符串 \(s\).定义一个"好的字符串"为不是回文串的字符串.对于每一次询问,求出任意一个重新排列能够得到的"好 ...

  9. 使用.NET 6开发TodoList应用(5)——领域实体创建

    需求 上一篇文章中我们完成了数据存储服务的接入,从这一篇开始将正式进入业务逻辑部分的开发. 首先要定义和解决的问题是,根据TodoList项目的需求,我们应该设计怎样的数据实体,如何去进行操作? 长文 ...

  10. jquery绑定事件时如何向事件函数里传参数

    jquery绑定事件时如何向事件函数里传参数 jquery绑定事件时如何向事件函数里传参数 举例子说明: 步骤1: var button=$('<button type="button ...