Python 进行目标检测
一、前言
从学单片机开始鼓捣C语言,到现在为了学CV鼓捣Python,期间在CSDN、简书、博客园和github这些地方得到了很多帮助,所以也想把自己做的一些小东西分享给大家,希望能帮助到别人。记录人生的第一篇博客,mark。
二、图像检测步骤
1. 读取两张图片
第一张是需要检测的小物体,第二章图片是小物体放置在大场景中。代码与输出结果如下所示:
import numpy as np
import matplotlib.pyplot as plt
import cv2 def my_show(img):
plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
return # 读取图片
img_small=cv2.imread('small.jpg',1)
img_big=cv2.imread('big.jpg',1) # 显示图片
plt.figure(figsize=(10,10))
plt.subplot(121)
my_show(img_small)
plt.subplot(122)
my_show(img_big)
2. 提取图片中的特征点
这一步就像我们在区分不同的人的时候,一眼看到外貌就知道此人是谁,而外貌就是这个人的特征。我们希望提取该物体的特征点,以便在不同的场景中识别出来。图片是由像素点构成,但是像素点包含的信息太零散了,一般是识别物体的边缘或者角点作为特征信息。常用的特征描述算法如下:
SIFT:https://blog.csdn.net/zddblog/article/details/7521424
harris corner detection: https://www.jianshu.com/p/efc81fdb8afb
Hog: https://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf
SURF: https://www.vision.ee.ethz.ch/~surf/eccv06.pdf
BRISK: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.371.1343&rep=rep1&type=pdf
Orb: http://www.willowgarage.com/sites/default/files/orb_final.pdf
我们项目中用到的是SIFT算法,SIFT精确度高,对尺度、亮度以及旋转的鲁棒性强,不过计算时间长,所需的计算资源较多。SURF是SIFT的加速版本,有兴趣的小伙伴可以了解一下。SIFT算法运行后,可以得到的特征点的位置以及特征向量。(PS:SIFT算法申请了专利,所以在opencv3.4.2版本后不能使用了,需要用SIFT的请安装3.4.2的opencv)
import numpy as np
import matplotlib.pyplot as plt
import cv2 def my_show(img):
plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
return # 读取图片
img_small=cv2.imread('small.jpg',1)
img_big=cv2.imread('big.jpg',1) # 提取特征点
sift=cv2.xfeatures2d.SIFT_create()
kp1,des1=sift.detectAndCompute(img_small,None)
kp2,des2=sift.detectAndCompute(img_big,None) # 在图中显示特征点
img_small_sift=cv2.drawKeypoints(img_small,kp1,outImage=np.array([]),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
img_big_sift=cv2.drawKeypoints(img_big,kp2,outImage=np.array([]),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) plt.figure(figsize=(15,15))
plt.subplot(121)
my_show(img_small_sift)
plt.subplot(122)
my_show(img_big_sift)
3.特征点匹配
在分别提取了两张图的特征点后,就需要进行特征点匹配啦。这里需要注意的是,两张图的特征点数量一般情况下是不一样的,opencv算法里默认用第一张图的特征点来匹配,所以匹配矩阵的行数与第一张图特征点的行数一致。常用的匹配方法:
Brute-Force: 暴力搜索,用图1的特征点逐一与图二的特征点比较,找到欧式距离最小的点作为匹配点。不过这样匹配的错误点就会很多,所以常用交叉匹配法消除错误匹配。交叉匹配法指的是,反过来匹配一次,用匹配到图2的点反过来匹配图1的点,如果匹配结果与原来相同,则认为是正确匹配。
KNN: K近邻匹配,在匹配的时候选择K个和特征点最相似的点,如果这K个点之间的区别足够大,则选择最相似的那个点作为匹配点,通常选择K = 2。KNN匹配也会出现一些误匹配,这时候需要对比第一邻近与第二邻近之间的距离大小,假如 distance_1< (0.5~0.7)*distance_2, 则认为是正确匹配。
FLANN: FLANN是快速最近邻搜索包(Fast Library for Approximate Nearest Neighbors)的简称,是最近邻搜索的算法的集合。
一般我们会选择调用cv2.Brute-Force或者cv2.FlannBasedMatcher来进行特征点匹配,FLANN里边就包含的KNN、KD树还有其他的最近邻算法。
4.计算单应性矩阵
这里我们需要在大场景中用矩形框出匹配的小物体,所以就要计算单应性矩阵,然后做投影变换。RANSAC(Random Sample Consensus)随机抽样一致性算法是计算单应性矩阵的有效方法,并且在寻找单应性矩阵的过程中可以进一步剔除错误匹配点。RANSAC算法的步骤如下:
- 随机抽取四个匹配点对计算投影矩阵,需要检验四个点是否共线
- 图片1特征点坐标齐次变换后(3,1)乘上投影矩阵(3,3),然后计算变换后的特征点坐标与图片2特征点坐标的欧氏距离,小于设定的阈值则记录为内点,反之则为内点
- 判断此次内点的数量是否比以往记录的内点最大值多,如果是,则更新投影矩阵,如果不是,则不更新
- 判定循环次数是够达到设定次数或内点数占全部匹配点的比例达到设定比例,则跳出循环,否则跳到步骤1继续循环
寻找到最优的单应性矩阵后,将框住物体一的矩阵经投影变换后在图片二上画出来,完成目标检测框选。以下代码摘自Brook@CV的博客并修改,如有侵权,请通知删除
import numpy as np
import cv2
from matplotlib import pyplot as plt MIN_MATCH_COUNT = 10 img1 = cv2.imread('small.jpg',1)
img2 = cv2.imread('big.jpg',1) # 使用SIFT检测角点
sift = cv2.xfeatures2d.SIFT_create()
# 获取关键点和描述符
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None) # 定义FLANN匹配器
index_params = dict(algorithm = 1, trees = 5)
search_params = dict(checks = 50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 使用KNN算法匹配
matches = flann.knnMatch(des1,des2,k=2) # 去除错误匹配
good = []
for m,n in matches:
if m.distance <= 0.7*n.distance:
good.append(m) # 单应性
if len(good)>MIN_MATCH_COUNT:
# 改变数组的表现形式,不改变数据内容,数据内容是每个关键点的坐标位置
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
# findHomography 函数是计算变换矩阵
# 参数cv2.RANSAC是使用RANSAC算法寻找一个最佳单应性矩阵H,即返回值M
# 返回值:M 为变换矩阵,mask是掩模
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
# ravel方法将数据降维处理,最后并转换成列表格式
matchesMask = mask.ravel().tolist()
# 获取img1的图像尺寸
h,w,dim = img1.shape
# pts是图像img1的四个顶点
pts = np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2)
# 计算变换后的四个顶点坐标位置
dst = cv2.perspectiveTransform(pts,M) # 根据四个顶点坐标位置在img2图像画出变换后的边框
img2 = cv2.polylines(img2,[np.int32(dst)],True,(0,0,255),3, cv2.LINE_AA) else:
print("Not enough matches are found - %d/%d") % (len(good),MIN_MATCH_COUNT)
matchesMask = None # 显示匹配结果
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
plt.figure(figsize=(20,20))
plt.imshow(cv2.cvtColor(img3,cv2.COLOR_BGR2RGB))
plt.show()
最后给大家放上原图可以跑一下程序!
Python 进行目标检测的更多相关文章
- 深度学习 + OpenCV,Python实现实时视频目标检测
使用 OpenCV 和 Python 对实时视频流进行深度学习目标检测是非常简单的,我们只需要组合一些合适的代码,接入实时视频,随后加入原有的目标检测功能. 在本文中我们将学习如何扩展原有的目标检测项 ...
- 利用ImageAI库只需几行python代码超简实现目标检测
目录 什么是目标检测 目标检测算法 Two Stages One Stage python实现 依赖 安装 使用 附录 什么是目标检测 目标检测关注图像中特定的物体目标,需要同时解决解决定位(loca ...
- Python实现YOLO目标检测
作者:R语言和Python学堂 链接:https://www.jianshu.com/p/35cfc959b37c 1. 什么是目标检测? YOLO目标检测的一个示例 啥是目标检测? 拿上图 (用YO ...
- 10行Python代码实现目标检测
要知道图像中的目标是什么? 或者你想数一幅图里有多少个苹果? 在本文中,我将向你展示如何使用Python在不到10行代码中创建自己的目标检测程序. 如果尚未安装python库,你需要安装以下pytho ...
- 基于YOLO和PSPNet的目标检测与语义分割系统(python)
基于YOLO和PSPNet的目标检测与语义分割系统 源代码地址 概述 这是我的本科毕业设计 它的主要功能是通过YOLOv5进行目标检测,并使用PSPNet进行语义分割. 本项目YOLOv5部分代码基于 ...
- [目标检测]YOLO原理
1 YOLO 创新点: 端到端训练及推断 + 改革区域建议框式目标检测框架 + 实时目标检测 1.1 创新点 (1) 改革了区域建议框式检测框架: RCNN系列均需要生成建议框,在建议框上进行分类与回 ...
- TensorFlow + Keras 实战 YOLO v3 目标检测图文并茂教程
运行步骤 1.从 YOLO 官网下载 YOLOv3 权重 wget https://pjreddie.com/media/files/yolov3.weights 下载过程如图: 2.转换 Darkn ...
- 目标检测 IOU(交并比) 理解笔记
交并比(Intersection-over-Union,IoU): 目标检测中使用的一个概念 是产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率 ...
- 第十九节、基于传统图像处理的目标检测与识别(词袋模型BOW+SVM附代码)
在上一节.我们已经介绍了使用HOG和SVM实现目标检测和识别,这一节我们将介绍使用词袋模型BOW和SVM实现目标检测和识别. 一 词袋介绍 词袋模型(Bag-Of-Word)的概念最初不是针对计算机视 ...
随机推荐
- IDEA 2019.2及以下版本永久激活教程(亲测可用)
写在前面 由于最近jetbrains公司开始严厉打击盗版激活码,所以导致一大批激活码失效,我身边的小伙伴对于如此苦恼,但是由于考虑到正版费用还是比较高昂的前提下,所以鉴于此,遂将之前整理的jar包激活 ...
- Vector人工智能机器人SDK使用笔记
Cozmo是2016年推出的,2两年后的2018年Vector上市,具备语音助手和更多功能,元件数由300+升级到700+. Vector的SDK具体说明在:developer.anki.com/ve ...
- iOS多线程编程原理及实践
摘要:iOS开发中,开发者不仅要做好iOS的内存管理,而且如果你的iOS涉及多线程,那你也必须了解iOS编程中对多线程的限制,iOS主线程的堆栈大小为1M,其它线程均为512KB,且这个限制开发者是无 ...
- Sql Server执行一条Update语句很慢,插入数据失败
今天同事要我修改服务器数据库里面的2条数据,查看服务器上的SQL Server数据库的时候,发现这几天数据没有添加成功,然后发现磁盘很快就满了,执行Update语句时,执行半天都提示还在执行,查询语句 ...
- mysql索引创建和使用细节
最近困扰自己很久的膝盖积液手术终于做完,在家养伤,逛技术博客看到easyswoole开发组成员仙士可博客有关mysql索引方面的知识,自己打算重温下. 正常业务起步数据表数据量较少,不用考虑使用索引, ...
- 用Python爬取了考研吧1000条帖子,原来他们都在讨论这些!
写在前面 考研在即,想多了解考研er的想法,就是去找学长学姐或者去网上搜索,贴吧就是一个好地方.而借助强大的工具可以快速从网络鱼龙混杂的信息中得到有价值的信息.虽然网上有很多爬取百度贴吧的教程和例子, ...
- graphviz 的使用教程
node 节点属性如下 : Name Default Values color black node shape color comment any string (format-dependen ...
- Spring Boot2 系列教程 (五) | yaml 配置文件详解
自定义属性加载 首先构建 SpringBoot 项目,不会的看这篇旧文 使用 IDEA 构建 Spring Boot 工程. 首先在项目根目录 src >> resource >&g ...
- cogs 1588. [USACO Feb04]距离咨询 倍增LCA
1588. [USACO Feb04]距离咨询 ★★ 输入文件:dquery.in 输出文件:dquery.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 农夫 ...
- Office系列(2)---提取Office文件(Word、PPT)中的所有图片
回顾一下上文结尾的问题:如何给文档设置一个合适的封面图?其中一个解决方案就是,获取Office文件内部的图片作为封面.这里就详细介绍下获取图片的几种方式,以及他们各自的优缺点. PS:因为之前用VST ...