我们利用python与和opencv库中的算法,实现了一个红的物体的检测与跟踪。
流程图如如下:
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。目前opecv4.0已上线。
orb算法(Oriented FASTand Rotated BRIEF),这个算法时基于FAST算法进行快速的特征值获取,简单说就是比较某一个点的灰度值与其周围点灰度值的差值,如果这个点与周围点都不同,则说明这个点是特征点。但是FAST算法没有旋转不变性。opencv中orb算法利用图像金字塔解决尺度变化问题,利用 BRIEF解决旋转不变的问题。
详细见ORB算法详解
BF算法(Brute Force)是一种匹配算法,他会匹所有的特征点,然后计算汉明距离。
完整的参数设置见官方文档ORB与BFopencv文档
以下是一个实例
#导入模块
import numpy as np
import cv2
import matplotlib as plt
#导如图片
img1=cv2.imread('TX.jpg',0)
img2=cv2.imread('TXX.jpg',0)
#初始化orb
orb=cv2.ORB_create()
#获取特征点
kp1=orb.detect(img1,None)
kps1,des1=orb.compute(img1,kp1)
kp2=orb.detect(img2,None)
kps2,des2=orb.compute(img2,kp2)
#初始化BF
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
#匹配
mmatches1= bf.match(des1H, des2H)
#将匹配距离按从小到大排序。
matches=sorted(matches1,key=lambda x:x.distance)
#获取匹配到的特征点
if len(matches)>20:
scr_pts=np.float32([kps1[m.queryIdx].pt for m in matches]).reshape(-1,1,2)
dst_pts=np.float32([kps2[m.trainIdx].pt for m in matches]).reshape(-1,1,2)
M,mask=cv2.findHomography(scr_pts,dst_pts,cv2.RANSAC,5.0)
matthmask=mask.ravel().tolist()
h,w=img1.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)
hull=cv2.convexHull(np.int32(scr_pts[:10]))
img9=cv2.drawContours(img1,np.int32(scr_pts[:200]),-1,255,3)
x,y,w,h=cv2.boundingRect(np.int32(scr_pts[:200]))
img8=cv2.rectangle(img9,(x,y),(x+w,y+h),(255,0,0),2)
else:
matthmask=None
#绘制匹配对
img5=cv2.drawMatches(img1,kps1,img2,kps2,matches[:10],None,flags=2)
cv2.imwrite('match.jpg',img5)
cv2.imwrite('new.jpg',img8)
camshif算法是一种连续自适应的均值偏移算法,它能够跟踪目标窗口内的物体移动。
详细见camshift详解
相关代码见我的上一篇opencv+python图像颜色跟踪
利用余弦定理来判断模板与跟踪目标的相似度。并设定一个阈值,如果余弦值小于这个阈值则重新匹配。
原理详见余弦定理计算相似度
import numpy as np
m = np.array([[1],[1],[2],[1]])
m = np.reshape(m, (1, -1))
n = np.array([[3],[1],[1],[1]])
mun = np.dot(m, n)
# heni nger = np.sqrt(sum)
dis = np.linalg.norm(m) * np.linalg.norm(n)
cos = mun / dis
#归一化0.5~1
sim = 0.5 + (0.5 * cos)
print(sim)
完整的代码托管在码云代码