基于均值迁移的对象移动分析(Meanshift)

✏️ ⛳️

概述

本质:

✔️ Mean Shift均值漂移算法是无参密度估计理论的一种,无参密度估计不需要事先知道对象的任何先验知识,完全依靠训练数据进行估计,并且可以用于任意形状的密度估计,在某一连续点处的密度函数值可由该点邻域中的若干样本点估计得出。

直观的理解:

✔️ 一堆点集,一个圆形的窗口在不断的移动,移动的方向是沿着点的密度最大的区域移动,图示如下:

均值迁移

函数在OpenCV里使用均值平移,首先需要设置目标,找到它的直方图,这样我们可以为了计算均值平移向后投影目标到每一帧上,同时也需要提供窗口的初始位置。

对于直方图,只考虑色调(H),要避免低光线带来的错误值,低光线的值使用 cv2.inRange() 函数来丢弃掉。

ret, track_window = cv2.meanShift(probImage, window, criteria )输入值probImage --> 输入图像,是直方图反向投影的结果

window --> 搜索窗口,ROI对象区域

criteria --> 均值迁移停止条件返回值ret --> 返回迭代次数

track_window --> 返回迭代后的窗口

示例代码

import cv2 as cv

cap = cv.VideoCapture('test.mp4')

# 读取第一帧

ret,frame = cap.read()

cv.namedWindow("Demo", cv.WINDOW_AUTOSIZE)

# 可以在图片上选择roi区域

x, y, w, h = cv.selectROI("Demo", frame, True, False)

track_window = (x, y, w, h)

# 获取ROI直方图

roi = frame[y:y+h, x:x+w]

hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)

# inRange函数设置亮度阈值

# 去除低亮度的像素点的影响

# 将低于和高于阈值的值设为0

mask = cv.inRange(hsv_roi, (26, 43, 46), (34, 255, 255))

# 计算直方图,参数为 图片(可多),通道数,蒙板区域,直方图长度,范围

roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])

# 归一化,像素值区间[0,255]

cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)

# 设置迭代的终止标准,最多十次迭代

term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )

while True:

ret, frame = cap.read()

if ret is False:

break;

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

# 直方图反向投影

dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)

# 均值迁移,搜索更新roi区域

ret, track_window = cv.meanShift(dst, track_window, term_crit)

# 绘制窗口

x,y,w,h = track_window

cv.rectangle(frame, (x,y), (x+w,y+h), 255,2)

cv.imshow('Demo',frame)

k = cv.waitKey(60) & 0xff

if k == 27:

break

else:

cv.imwrite(chr(k)+".jpg",frame)

cv.destroyAllWindows()

cap.release()Meanshift

基于连续自适应均值迁移的对象移动分析(Camshift)

概述

✔️ 由于mean-shift算法的窗口是固定大小的,而我们需要让窗口大小和目标的大小以及旋转相适应,因此提出了Camshift。

✔️ CAM是连续自适应的均值迁移跟踪算法,它跟均值迁移相比较有两个改进 - 会根据跟踪对象大小变化自动调整搜索窗口大小 - 返回位置信息更加完整,包含了位置与角度信息。

✔️ CAM先采用均值平移,当平移覆盖后,更新窗口大小,公式如下:

它也计算最适合的椭圆的方向,然后它在使用新的大小的窗口在之前的位置开始进行均值平移,过程不断继续直到到达指定的准确率。

函数

ret, track_box = cv2.CamShift(

InputArray probImage,

Rect & window,

TermCriteria criteria )输入probImage --> 输入图像,是直方图反向投影的结果

window --> 搜索窗口,ROI对象区域

criteria --> 均值迁移停止条件输出ret --> 返回可变角度的最优外接椭圆

track_box --> 返回新的窗口

示例代码

import cv2 as cv

import numpy as np

cap = cv.VideoCapture('test.mp4')

# 读取第一帧

ret,frame = cap.read()

cv.namedWindow("Demo", cv.WINDOW_AUTOSIZE)

# 选择ROI区域

x, y, w, h = cv.selectROI("Demo", frame, True, False)

track_window = (x, y, w, h)

# 获取ROI直方图

roi = frame[y:y+h, x:x+w]

hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)

mask = cv.inRange(hsv_roi, (26, 43, 46), (34, 255, 255))

roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])

cv.normalize(roi_hist,roi_hist,0,255,cv.NORM_MINMAX)

# 设置迭代的终止标准,最多十次迭代

term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )

while True:

ret, frame = cap.read()

if ret is False:

break;

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

dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)

# 搜索更新roi区域

ret, track_box = cv.CamShift(dst, track_window, term_crit)

# 可变角度的矩形框

pts = cv.boxPoints(ret)

pts = np.int0(pts)

cv.polylines(frame, [pts], True, (0, 255, 0), 2)

# 更新窗口

track_window = track_box

#print(track_box)

# 绘制窗口CAM,目标椭圆图

cv.ellipse(frame, ret, (0, 0, 255), 3, 8)

cv.imshow('Demo',frame)

k = cv.waitKey(50) & 0xff

if k == 27:

break

else:

cv.imwrite(chr(k)+".jpg",frame)

cv.destroyAllWindows()

cap.release()Camshift

对象移动轨迹绘制

✔️ 移动对象分析,我们可以绘制对象运行轨迹曲线,这个主要是根据移动对象窗口轮廓,获取中心位置,然后使用中心位置进行绘制即可得到。

✔️ 大致的程序步骤如下:

1. 初始化路径点数组

2. 对每帧的预测轮廓提取中心位置添加到路径数组

3. 绘制路径曲线

代码

✔️ 我们只需要在上一节Camshift的代码中添加一个数组存储中心位置,然后使用cv2.line()画出即可。

修改部分:

tracking_path = []

while True:

ret, frame = cap.read()

if ret is False:

break;

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

dst = cv.calcBackProject([hsv],[0],roi_hist,[0,180],1)

# ,搜索更新roi区域, 保持运行轨迹

ret, track_box = cv.CamShift(dst, track_window, term_crit)

track_window = track_box

# 椭圆中心

pt = np.int32(ret[0])

if pt[0] > 0 and pt[1] > 0:

tracking_path.append(pt)

# 绘制跟踪对象位置窗口与对象运行轨迹

#cv.ellipse(frame, ret, (0, 0, 255), 3, 8)

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

cv.line(frame, (tracking_path[i - 1][0], tracking_path[i - 1][1]),

(tracking_path[i][0], tracking_path[i][1]), (0, 255, 0), 2, 6, 0)

cv.imshow('Demo',frame)

k = cv.waitKey(50) & 0xff

if k == 27:

break

else:

cv.imwrite(chr(k)+".jpg",frame)轨迹绘制

------------------------------------------可爱の分割线------------------------------------------

更多Opencv教程可以 Follow github的opencv教程,中文&English 欢迎Star❤️❤️❤️JimmyHHua/opencv_tutorials​github.com

参考

opencv 图像上画出目标运动的轨迹_OpenCV视频分析-Meanshift、Camshift运动轨迹绘制...相关推荐

  1. opencv 图像上画出目标运动的轨迹_基于opencv的单目和双目标定平台手眼标定

      背景介绍 基于机器视觉引导的智能机器人,在现代社会各个领域已经得到了广泛的应用,尤其是大型工厂的自动化生产线上,视觉机器人可以和基于示教器按照预定轨迹进行作业的机器人互为补充,来共同提高生产的自动 ...

  2. 在yuv上画线_利用布雷森汉姆算法绘制在YUV图像上画直线

    最近,因工作需要,在YUV图像上画直线: 算法1步骤: 1.已知直线的起点和终点: 2. 利用布雷森汉姆算法在两点间画直线: 3. 将该直线上的点的颜色在YUV图像上画出. 布雷森汉姆算法原理参考wi ...

  3. 用python的opencv库在图片上画出蓝底黑字的文本框

    以下是使用Python的OpenCV库实现在图片上绘制的示例代码: import cv2# 读入图片 img = cv2.imread('example.jpg')# 在图片上绘制红色矩形框 cv2. ...

  4. opencv3_java 在已有的图像上画圆圈 CircleOnImg

    在已有的图像上画圆圈 CircleOnImg package opencv_java_demo;import org.opencv.core.*; import org.opencv.imgcodec ...

  5. 【目标检测】在图像上画bounding box框,生成带真实标签gt的图片

    [目标检测]在图像上画bounding box框,生成带真实标签gt的图片 问题/Motivation 数据格式 用到的库 实际代码` 结果展示 问题/Motivation 在制作完数据集后,想看一下 ...

  6. cufon,在网页上画出特殊字体

    为什么80%的码农都做不了架构师?>>>    设计师们有时会使用特殊字体让网页更好看,但浏览器通常只支持Arial.Helvetica等通用字体.那么通常的解决办法就是将特殊字体做 ...

  7. 编写一个APPlet,再随机的位置上画出几个随机大小的矩形。

    编写一个APPlet,再随机的位置上画出几个随机大小的矩形.如果一个矩形的宽度小于高度,则矩形填充成亮紫色:如果矩形的宽度大于高度,则矩形填充为浅黄色:如果矩形的宽度和高度相等,则只用红色线画出矩形的 ...

  8. 怎样固定计算机画图曲线,如何在电脑上画出固定长度的线段

    公告: 为响应国家净网行动,部分内容已经删除,感谢读者理解. 话题:如何在电脑上画出固定长度的线段回答:这个要看你采用什么软件来画线段了 既然你是用word的话,稍微有点烦:方法为:在word里搞出绘 ...

  9. 使用JavaScript在Canvas上画出一片星空

    随着Html5的迅猛发展,画布也变得越来越重要.下面我就写一个关于在canvas上画出一片星空的简单的代码的示例. 理论基础 初始化一个canvas,获得一个用于绘制图形的上下文环境context.并 ...

最新文章

  1. GO语言基础之reflect反射
  2. linux 命令行简介
  3. suse 安装mysql5.6_SuSE11安装MySQL5.6.40:RPM安装方式
  4. socket inet_pton
  5. 衡量发动机性能的重要指标—升功率
  6. JS 与Flex交互:html中的js 与flex中的actionScript通信
  7. C语言1094题目,基于visual Studio2013解决C语言竞赛题之1094纵横图
  8. java--tomcat
  9. UVA10293 Word Length and Frequency【单词长度频度+strtok】
  10. Git服务器的搭建和使用
  11. 067、如何部署Calico网络 (2019-04-10 周三)
  12. 51nod1649齐头并进-Dijkstra
  13. 北斗导航 | RTCM 3.3学习(10403.3)
  14. Jmeter 中的BeanShell使用
  15. 抖音上热门的7大小技巧
  16. 手机怎样和宽带连接无线路由器设置路由器连接服务器,手机如何设置路由器?...
  17. Python 模块—计算三角形的斜边长
  18. 缅怀过往_飘云羽逸_新浪博客
  19. android 文件扫描MediaStore
  20. java工单管理系统_企业工单管理系统--使用mybatis

热门文章

  1. 华为服务器查看阵列信息,查看服务器磁盘阵列
  2. phpoffice/phpword 表格合并和表格绝对居中
  3. 做好自己安全第一责任人 嘀嗒全面上线安全带智能语音提醒
  4. centos(11)-ps进程管理
  5. 学python必须得英语精通吗_Python无用武之地?只能说你是真的没有精通Python语言(附教程)...
  6. 财务分析比赛学习(1)大数据部分
  7. 实现斗地主牌的大小顺序,实现分发牌的顺序,每个人手中的牌按照大小排序
  8. cp2102 vcp驱动
  9. Imperva incapsula逆向分析
  10. 2022年第四届河南省CCPC大学生程序设计竞赛代码+简单思路(退役战了算是,还好金了)