python目标跟踪精度曲线图_Python+opencv3.4+Kalman滤波在视频中跟踪绘制运动目标,Pythonopencv34kalman,卡尔曼滤波,实现,物体,追踪,和,轨迹...

实验环境:

Python3.6+OpenCV3.4+pycharm2019

代码实现:

首先是一个

简单的不用kalman滤波的运动目标追踪代码

这里可以根据需要进行摄像头运动目标识别,只要把

camera = cv2.VideoCapture('./video/yellow_ball.mp4')

# 改成camera = cv2.VideoCapture(0) 就是摄像头内识别

完整代码:

from collections import deque

import numpy as np

import cv2

# imutils

import time

#设定阈值,HSV空间

redLower = np.array([11, 100, 100])

redUpper = np.array([20, 255, 255])

#初始化追踪点的列表

mybuffer = 64

pts = deque(maxlen=mybuffer)

#打开摄像头

camera = cv2.VideoCapture('./video/yellow_ball.mp4')

fourcc = cv2.VideoWriter_fourcc(*'XVID') # 保存文件为avi格式

fps = camera.get(cv2.CAP_PROP_FPS)

size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)), int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))) # 输出视频尺寸,长和宽

out = cv2.VideoWriter('new_yellow_ball.avi', fourcc, fps, size) # 输出视频

#等待两秒

time.sleep(2)

#遍历每一帧,检测红色瓶盖

while True:

#读取帧

(ret, frame) = camera.read()

if ret == False:

break

#判断是否成功打开摄像头

# if not ret:

# print('No Camera')

# break

#frame = imutils.resize(frame, width=600)

#转到HSV空间

hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

#根据阈值构建掩膜

mask = cv2.inRange(hsv, redLower, redUpper)

#腐蚀操作

mask = cv2.erode(mask, None, iterations=2)

#膨胀操作,其实先腐蚀再膨胀的效果是开运算,去除噪点

mask = cv2.dilate(mask, None, iterations=2)

#轮廓检测

cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]

#初始化瓶盖圆形轮廓质心

center = None

#如果存在轮廓

if len(cnts) > 0:

#找到面积最大的轮廓

c = max(cnts, key = cv2.contourArea)

#确定面积最大的轮廓的外接圆

((x, y), radius) = cv2.minEnclosingCircle(c)

#计算轮廓的矩

M = cv2.moments(c)

#计算质心

center = (int(M["m10"]/M["m00"]), int(M["m01"]/M["m00"]))

#只有当半径大于10时,才执行画图

if radius > 10:

cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2)

cv2.circle(frame, center, 5, (0, 0, 255), -1)

#把质心添加到pts中,并且是添加到列表左侧

pts.appendleft(center)

#遍历追踪点,分段画出轨迹

for i in range(1, len(pts)):

if pts[i - 1] is None or pts[i] is None:

continue

#计算所画小线段的粗细

thickness = int(np.sqrt(mybuffer / float(i + 1)) * 2.5)

#画出小线段

cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)

#res = cv2.bitwise_and(frame, frame, mask=mask)

cv2.imshow('Frame', frame)

out.write(frame)

#键盘检测,检测到esc键退出

k = cv2.waitKey(5)&0xFF

if k == 27:

break

#摄像头释放

camera.release()

#销毁所有窗口

cv2.destroyAllWindows()

这里是

基于kalman滤波的运动目标识别与轨迹绘制

import cv2

import numpy as np

# hsv阈值,便于进行轮廓判断及轨迹绘制,需要根据运动目标的颜色自己进行调整

min_hsv_bound = (35, 100, 100)

max_hsv_bound = (77, 255, 255)

#状态向量

stateSize = 6

#观测向量

measSize = 4

coutrSize = 0

kf = cv2.KalmanFilter(stateSize,measSize,coutrSize)

state = np.zeros(stateSize, np.float32)#[x,y,v_x,v_y,w,h],簇心位置,速度,高宽

meas = np.zeros(measSize, np.float32)#[z_x,z_y,z_w,z_h]

procNoise = np.zeros(stateSize, np.float32)

#状态转移矩阵

cv2.setIdentity(kf.transitionMatrix)#生成单位矩阵

# [1 0 dT 0 0 0]

# [0 1 0 dT 0 0]

# [0 0 1 0 0 0]

# [0 0 0 1 0 0]

# [0 0 0 0 1 0]

# [0 0 0 0 0 1]

#观测矩阵

# [1 0 0 0 0 0]

# [0 1 0 0 0 0]

# [0 0 0 0 1 0]

# [0 0 0 0 0 1]

kf.measurementMatrix = np.zeros((measSize,stateSize),np.float32)

kf.measurementMatrix[0,0]=1.0

kf.measurementMatrix[1,1]=1.0

kf.measurementMatrix[2,4]=1.0

kf.measurementMatrix[3,5]=1.0

#预测噪声

# [Ex 0 0 0 0 0]

# [0 Ey 0 0 0 0]

# [0 0 Ev_x 0 0 0]

# [0 0 0 Ev_y 0 0]

# [0 0 0 0 Ew 0]

# [0 0 0 0 0 Eh]

cv2.setIdentity(kf.processNoiseCov)

kf.processNoiseCov[0,0] = 1e-2

kf.processNoiseCov[1,1] = 1e-2

kf.processNoiseCov[2,2] = 5.0

kf.processNoiseCov[3,3] = 5.0

kf.processNoiseCov[4,4] = 1e-2

kf.processNoiseCov[5,5] = 1e-2

#测量噪声

cv2.setIdentity(kf.measurementNoiseCov)

# for i in range(len(kf.measurementNoiseCov)):

# kf.measurementNoiseCov[i,i] = 1e-1

video_cap = cv2.VideoCapture('./video/green_ball.mp4')

# 视频输出

fps = video_cap.get(cv2.CAP_PROP_FPS) #获得视频帧率,即每秒多少帧

size = (int(video_cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(video_cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

videoWriter = cv2.VideoWriter('./video/new_green.mp4' ,cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), fps, size)

ticks = 0

i=0

found = False

notFoundCount = 0

prePointCen = [] #存储小球中心点位置

meaPointCen = []

while(True):

ret, frame = video_cap.read()

if ret is False:

break

cv2.imshow('frame',frame)

cv2.waitKey(1)

precTick = ticks

ticks = float(cv2.getTickCount())

res = frame.copy()

# dT = float(1/fps)

dT = float((ticks - precTick)/cv2.getTickFrequency())

if(found):

#预测得到的小球位置

kf.transitionMatrix[0,2] = dT

kf.transitionMatrix[1,3] = dT

state = kf.predict()

width = state[4]

height = state[5]

x_left = state[0] - width/2 #左上角横坐标

y_left = state[1] - height/2 #左上角纵坐标

x_right = state[0] + width/2

y_right = state[1] + height/2

center_x = state[0]

center_y = state[1]

prePointCen.append((int(center_x),int(center_y)))

cv2.circle(res, (int(center_x),int(center_y)),2,(255,0,0),-1)

cv2.rectangle(res,(x_left,y_left),(x_right,y_right),(255,0,0),2)

#根据颜色二值化得到的小球位置

frame = cv2.GaussianBlur(frame, (5,5), 3.0, 3.0)

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

rangeRes = cv2.inRange(frame, min_hsv_bound,max_hsv_bound)

kernel = np.ones((3, 3), np.uint8)

# 腐蚀膨胀

rangeRes = cv2.erode(rangeRes, kernel, iterations=2)

rangeRes = cv2.dilate(rangeRes, kernel, iterations=2)

# cv2.imshow("Threshold", rangeRes)

cv2.waitKey(1)

contours = cv2.findContours(rangeRes.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[-2]

#检测轮廓,只检测最外围轮廓,保存物体边界上所有连续的轮廓点到contours向量内

balls = []

ballsBox = []

for i in range(len(contours)):

x, y, w, h = cv2.boundingRect(np.array(contours[i]))

ratio = float(w/h)

if(ratio > 1.0):

ratio = 1.0 / ratio

if(ratio > 0.75 and w*h>=400):

balls.append(contours[i])

ballsBox.append([x, y, w, h])

print( "Balls found:", len(ballsBox))

print("\n")

for i in range(len(balls)):

# 绘制小球轮廓

cv2.drawContours(res, balls, i, (20,150,20),1)

cv2.rectangle(res,(ballsBox[i][0],ballsBox[i][1]),(ballsBox[i][0]+ballsBox[i][2],ballsBox[i][1]+ballsBox[i][3]),(0,255,0),2) #二值化得到小球边界

center_x = ballsBox[i][0] + ballsBox[i][2] / 2

center_y = ballsBox[i][1] + ballsBox[i][3] / 2

meaPointCen.append((int(center_x),int(center_y)))

cv2.circle(res,(int(center_x),int(center_y)), 2, (20,150,20) ,-1)

name = "(" + str(center_x) + "," + str(center_y) + ")"

cv2.putText(res, name, (int(center_x) + 3, int(center_y) - 3), cv2.FONT_HERSHEY_COMPLEX, 0.5, (20,150,20), 2)

n = len(prePointCen)

for i in range(1, n):

print(i)

if prePointCen[i-1] is None or prePointCen[i] is None:

continue

# 注释掉的这块是为了绘制能够随时间先后慢慢消失的追踪轨迹,但是有一些小错误

# 计算所画小线段的粗细

# thickness = int(np.sqrt(64 / float(n - i + 1))*2.5)

# print(thickness)

# 画出小线段

# cv2.line(res, prePointCen[i-1], prePointCen[i], (0, 0, 255), thickness)

cv2.line(res, prePointCen[i-1], prePointCen[i], (0,0,255), 1, 4)

if(len(balls) == 0):

notFoundCount += 1

print("notFoundCount",notFoundCount)

print("\n")

if notFoundCount >= 100:

found = False

else:

#测量得到的物体位置

notFoundCount = 0

meas[0] = ballsBox[0][0] + ballsBox[0][2] / 2

meas[1] = ballsBox[0][1] + ballsBox[0][3] / 2

meas[2] = float(ballsBox[0][2])

meas[3] = float(ballsBox[0][3])

#第一次检测

if not found:

for i in range(len(kf.errorCovPre)):

kf.errorCovPre[i,i] = 1

state[0] = meas[0]

state[1] = meas[1]

state[2] = 0

state[3] = 0

state[4] = meas[2]

state[5] = meas[3]

kf.statePost = state

found = True

else:

kf.correct(meas) #Kalman修正

print('rr',res.shape)

print("Measure matrix:", meas)

cv2.imshow("Tracking", res)

cv2.waitKey(1)

videoWriter.write(res)

大概就是这样了,如果追踪效果不好就自己调整一下阈值范围吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++this指针的用途

this指针的用途: 1.当形参和成员变量同名时,可用this指针来区分。 2.在类的非静态成员函数中返回对象本身,可使用return *this 每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码,那…

【实战 Ids4】小技巧篇:自定义登录页操作

今天的内容很简单,1分钟就能看完,5分钟就能学会,但是却是在我们平时开发中必须要学会的一个小知识点,我就不让大家走弯路了,直接看操作。在平时的IdentityServer4开发中呢,我们都是根据官方的Demo来操作一遍…

mysql_result函数用不了_mysql_result()函数怎么在PHP中使用

mysql_result()函数怎么在PHP中使用发布时间:2020-12-21 16:30:03来源:亿速云阅读:69作者:Leah这篇文章给大家介绍mysql_result()函数怎么在PHP中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴&#xff…

Asp.Net Core下的开源任务调度平台ScheduleMaster

从何说起2017年初的时候,由于当时项目需要做了一个乞丐版定时调度系统,那时候只在单机上实现了核心的调度功能。做这个玩意之前也调研了社区中开源的解决方案,找了几个实地部署试跑了一下,其实都很不错。但那时候我们有个问题就是…

python如何加密字符串_Python实现对字符串的加密解密方法示例

本文实例讲述了Python实现对字符串的加密解密方法。分享给大家供大家参考,具体如下:需求是是要将密码存在数据库里,所以要加密解密是可逆的,在数据库里不要有特殊字符,防止数据库备份和恢复中出错。安装PyCrypto&#…

C++友元

友元的目的就是让一个函数或者类访问另一个类中私有成员 友元的关键字&#xff1a;friend 友元的三种实现&#xff1a; 1.全局函数做友元 2.类做友元 3.成员函数做友元 一.全局函数做友元 #include <iostream> using namespace std; #include <cstring>class Bu…

C#录制视频

这是一个使用C#语言制作的录制框架&#xff0c;支持录制桌面&#xff0c;多屏&#xff0c;声音&#xff0c;摄像头&#xff0c;某个应用程序的界面1.安装使用此框架需要安装扩展包Kogel.Record,可以Nuget上搜索或者使用Nuget命令Install-Package Kogel.Record安装完成包后会出现…

C++加号运算符重载

运算符重载概念&#xff1a; 对已有的运算符重新定义&#xff0c;赋予其另一种功能&#xff0c;以适应不同的数据类型 加号运算符重载&#xff1a; 1.成员函数重载加号&#xff1a; #include <iostream> using namespace std;//加号运算符重载//1.成员函数重载号class …

python编程小案例_用Python3编程写第一个小案例!-Go语言中文社区

用Python3编程第一步&#xff01;今天博主跟大家聊一聊如何使用Python3编程第一步&#xff01;&#xff01;不喜勿喷&#xff0c;如有建议欢迎补充、讨论&#xff01;Come on&#xff01;在前面的几篇文章中我们已经学习了一些Python3 的基本语法知识&#xff0c;我们尝试来写一…

UnitTest in .NET(Part 5)

Photo &#xff1a;UnitTesting文 | Edison Zhou上一篇我们学习了单元测试的核心技术&#xff1a;存根、模拟对象和隔离框架&#xff0c;它们是我们进行高质量单元测试的技术基础。本篇会集中在管理和组织单元测试的技术&#xff0c;以及如何确保在真实项目中进行高质量的单元测…

C++左移运算符重载

作用&#xff1a;可以输出自定义数据类型 代码如下&#xff1a; #include <iostream> using namespace std; //左移运算符重载class Person {public:int m_A;int m_B;};ostream &operator<<(ostream &cout, Person &p) { //本质 operator<<(cou…

java 大小写_java中如何进行大小写字母转换?

展开全部1.创建工程&#xff0c;或使用已有工程&#xff0c;在工程下创建包&#xff0c;包内新建一个类&#xff0c;我e69da5e887aa3231313335323631343130323136353331333365653262命名为Cases类&#xff0c;大家根据自己喜好随便命名&#xff0c;但请保持类名与文件名一致。2…

大量SQL的解决方案——sdmap

大量SQL的解决方案——sdmap最近看到群里面经常讨论大型应用中 SQL的管理办法&#xff0c;有人说用 EF/ EFCore&#xff0c;但很多人不信任它生成 SQL的语句&#xff1b;有人说用 Dapper&#xff0c;但将 SQL写到代码中有些人觉得不合适&#xff1b;有人提出用存储过程&#xf…

C++递增运算符重载

作用&#xff1a;通过重载递增运算符&#xff0c;实现自己定义的数据类型 代码如下&#xff1a; #include <iostream> using namespace std;//重载递增运算符//自定义类型 class MyInteger {friend ostream &operator<<(ostream &cout, MyInteger myint)…

java 最小堆_堆排序 最大堆 最小堆 Java 实现

堆一点疑惑&#xff0c;堆排序是就地排序&#xff0c;所以空间复杂度是 O(1)。但是&#xff0c;比如我有一个数组&#xff0c;建立一个最小堆&#xff0c;然后每次取出最小堆的顶点。建立最小堆需要额外空间&#xff1f;不深究了&#xff0c;归并排序需要额外空间。堆是完全二叉…

过去10年技术人员有哪些状态改变?

现在已经是2020年&#xff0c;我们已经进入了下一个10年&#xff0c;我们都应该回顾、复盘一下过去十年技术的发展&#xff0c;以及未来技术能做什么&#xff1f;如何更好的应用技术&#xff1f;我个人也是一个从事技术10年以上的老兵了&#xff0c;对技术人员来说其实不外乎要…

java解压中文乱码_java使用解压zip文件,文件名乱码解决方案

File outFileDir new File(outDir);if (!outFileDir.exists()) {boolean isMakDir outFileDir.mkdirs();if (isMakDir) {log.info("创建压缩目录成功");}}ZipFile zip new ZipFile(zipFile, "gbk");for (Enumeration enumeration zip.getEntries(); en…

提高文档翻译效率神器:VS Code 插件之 Translator Helper

微软 Docs 网站上线之后&#xff0c;我发现很多中文内容是由机器翻译的&#xff0c;可读性比较差。2017 年开始我参与了中文文档的本地化工作&#xff0c;对机器翻译的文本进行校对。Docs 的内容全部托管在 GitHub 上&#xff0c;参与者可以 fork 仓库后进行修改&#xff0c;然…

C++关系运算符重载

作用&#xff1a;重载关系运算符&#xff0c;可以让两个自定义类型对象进行对比操作 代码如下&#xff1a; #include <iostream> using namespace std; #include <cstring> //重载关系运算符class Person {public:Person(string name, int age) {m_Name name;m_…

java 导入导出 插件_Java最优的Excel导入/导出工具开发,你用过吗?

关注程序员7歌&#xff0c;一起用技术改变世界在我们实际开发中经常会遇到Excel的导入与导出功能&#xff0c;而目前Excel操作工具也是数不甚数啊&#xff0c;但是7歌用过很多&#xff0c;还是觉得最近发现的tool-excel好用&#xff0c;让你实现一语句代码就能完成Excel功能。首…