meanshift算法通俗讲解

article/2025/11/6 16:47:07

这几天学习《学习OpenCV》中的第十章运动跟踪,里面讲到了meanshift算法,根据书上所讲实在难以理解,meanshift在运动跟踪这个过程中到底起到什么作用,于是经过几天不断地看相关资料和别人的博客文章,慢慢思路清晰了,也终于知道了meanshift这个算法它到底是什么作用,起到什么样的角色,虽然为了弄明白这个算法花了几天的时间,但是通过这个过程学到了很多其他的知识。好了,接下来进入正题。

         首先要介绍一下meanshift这个算法,它的本质是一个迭代的过程,那么这个算法的最终效果是什么呢?或者说这个算法能做什么事情?它能够在一组数据的密度分布中寻找到局部极值,它比较稳定,而且是无参密度估计(它不需要事先知道样本数据的概率密度分布函数,完全依靠对样本点的计算),而且它在采样充分的情况下,一定会收敛,即可以对服从任意分布的数据进行密度估计。下面来根据几张图片来理解一下meanshift算法的最终效果:

         这里就不把meanshift的数学公式什么的都写出来了,只为了让大家知道meanshift是什么作用;高维的我们也先不考虑,以二维来说明可能更容易理解,下图中的很多的红点就是我们的样本特征点,meanshift就是在这些点中的任意一个点为圆心,然后以半径R画一个圆(在opencv中是一个矩形),然后落在这个圆中的所有点和圆心都会对应的一个向量,把所有这些向量相加(注意是向量相加),最终我们只得到一个向量,就是下图中用黄色箭头表示的向量,这个向量就是meanshift向量。

 

         然后再以这个meanshift向量的终点为圆心,继续上述过程,又可以得到一个meanshift向量,如下图:

 

         然后不断地继续这样的过程,我们可以得到很多连续的meanshift向量,这些向量首尾相连,最终得到会在一个地方停下来(即我们说的meanshift算法会收敛),最后的那个meanshift向量的终点就是最终得到的结果(一个点),如下图:

 

         从上述的过程我们可以看出,meanshift算法的过程最终的效果就是:从起点开始,最终会一步一步到达样本特征点最密集的点那里(当然在哪个点就是终点这个要取决于我们设定的阈值)。

         注:如果还是不明白为什么会向密集的地方走去,可以利用向量的加法规则自己画个简单的图去理解一下。

         到这里可能只知道meanshift算法的作用是向数据密集的地方走的一个效果,但是还是不明白它是怎么在运动跟踪中发挥作用的,尤其是不理解它这个样本特征点(就是上图中的红点点)到底和我们图像中的什么对应的。

       对于上面这个问题,我们需要先了解一下运动跟踪算法是一个什么样的过程,知道了这个过程之后就可以知道meanshift算法在这个过程中发挥什么角色了。运动跟踪说到底就是在一开始告诉程序一个跟踪目标,即我想跟踪什么,然后程序就在接下来的视频帧中去寻找这个目标了。给定跟踪目标很简单,直接在图像中给一个ROI给程序就可以了,那么程序接下来要做的就是在下一帧图像中去找这个ROI,但这个ROI是移动了的,已经不在之前的那个位置了,那么这个时候程序要怎么来找到这个ROI呢?那么在计算机视觉中我们是这么来解决的:首先对跟踪目标进行描述,这个描述是将跟踪目标区域转换为颜色HSV空间,然后得到H的这个通道的分布直方图,有了这个描述之后,我们就是要在下一个视频帧中找到和这个描述的一样的区域,但是我们知道要找到完全一样的区域很难,所以我们就用了一个相似函数来衡量我们找到的区域和我们的目标区域的相似度,通过这个相似函数,相似函数值越大说明我们找打的区域和目标区域越相似,所以我们的目标就是要找这个对应最大相似值的区域,那么怎么来找呢?这个时候meanshift就排上用场了,它可以通过不断地迭代得到有最大相似值的区域(具体里面的是怎么算的,可以参考博文地底下的参考博客),meanshift的作用可以让我们的搜索窗口不断向两个模型相比颜色变化最大的方向不断移动,直到最后两次移动距离小于阈值,即找到当前帧的位置,并以此作为下一帧的起始搜索窗口中心,如此重复,这个过程每两帧之间都会产生一个meanshift向量,整个过程的meanshift向量连起来就是目标的运动路径。所以讲到这里了,我们已经知道了meanshift算法在整个运动跟踪过程中扮演什么角色了。

         整个运动跟踪过程就是如下图所示:

 

参考博客:

http://blog.csdn.NET/jinshengtao/article/details/30258833

http://www.cnblogs.com/liqizhou/archive/2012/05/12/2497220.html


http://chatgpt.dhexx.cn/article/A0sVVWZA.shtml

相关文章

机器学习实验 - MeanShift聚类

目录 一、报告摘要1.1 实验要求1.2 实验思路1.3 实验结论 二、实验内容2.1 方法介绍2.2 实验细节2.2.1 实验环境2.2.2 实验过程2.2.3 实验与理论内容的不同点 2.3 实验数据介绍2.4 评价指标介绍2.5 实验结果分析 三、总结及问题说明四、参考文献附录:实验代码 报告内…

聚类 之 MeanShift

文章目录 Meanshift 聚类基本原理Meanshift 聚类流程简述实例演示MeanShift聚类简易应用示例总结拓展阅读 上篇博客介绍了基于距离的K-Means聚类,这次给大家推荐一个基于密度的聚类算法:Meanshift(均值漂移)。 Meanshift 聚类基本…

Muduo源码剖析

1、总体流程 1. acceptor 进行listen阶段后, 往channel中注册可读事件。 2. acceptor可读处理中生成TcpConnection指针,通过EventloopThreadPool 轮询出其中一个线程的eventloop, 并将此TcpConnection的可读、可写等事件注册到自己Channel(ev…

Muduo - Reactor模式

Muduo - Reactor模式 一、Reactor 是什么 wiki的中文定义:Reactor模式是事件驱动的,有一个或多个并发输入源,有一个Service Handler,有多个Request Handler,这个Service Handler会同步的将输入的请求(Even…

muduo网络库——ThreadPool

模型 源码分析 1&#xff09;接口 class ThreadPool : noncopyable {public:typedef std::function<void ()> Task;explicit ThreadPool(const string& nameArg string("ThreadPool"));~ThreadPool();void setMaxQueueSize(int maxSize) { maxQueueSize…

muduo网络库——Channel

模型 实现流程&#xff1a; 前面已经介绍了EPoller类&#xff0c;EPoller主要监听的是Channel对象&#xff0c;每一个Channel对象会绑定一个文件描述符&#xff08;fd_&#xff09;&#xff0c;fd_上绑定要监听的事件。当epoll监听到就绪事件时&#xff0c;会将就绪事件添加到…

muduo源码分析之Buffer

这一次我们来分析下muduo中Buffer的作用&#xff0c;我们知道&#xff0c;当我们客户端向服务器发送数据时候&#xff0c;服务器就会读取我们发送的数据&#xff0c;然后进行一系列处理&#xff0c;然后再发送到其他地方&#xff0c;在这里我们想象一下最简单的EchoServer服务器…

从实例看muduo网络库各模块交互过程

文章目录 muduo网络库的核心代码模块各模块功能解释ChannelPollerEpollPoller EventLoopEventLoopThreadEventLoopThreadPoolTcpServerTcpConnection 从实际应用出发 muduo网络库的核心代码模块 1、channel 2、Poller 和它的子类 EpollPoller 3、EventLoop 4、Thread、EventLo…

muduo总结

本文重点在muduo TcpServer的启动&#xff0c;I/O线程池的启动&#xff0c;以及各种回调 文章目录 baseAsyncLogging.{h,cc}Atomic.hBlockinQueue.hBoundedBlockinQueue.hCondition.hcopyable.hCountDownLatch.{h,cc}Date.{h,cc}Exception.{h,cc}Logging.{h,cc}Mutex.hProcess…

muduo网络库——日志处理

测试程序 #include "muduo/base/AsyncLogging.h" #include "muduo/base/Logging.h" #include "muduo/base/Timestamp.h"#include <stdio.h> #include <sys/resource.h> #include <unistd.h>off_t kRollSize 500*1000*1000;m…

Muduo日志模块详解

Muduo日志模块解析 图片取自muduo网络库源码解析(1):多线程异步日志库(上)_李兆龙的技术博客_51CTO博客也是很好的日志讲解博客,这篇讲解流程基本上和它差不多,并且写的比我条理清楚很多 AppendFile::append() 这个函数是日志写入文件的最终函数,并且AppendFile这个类里面也是…

Muduo 定时器

TimeQueue定时器 图片转载自:muduo网络库源码解析(4):TimerQueue定时机制_李兆龙的技术博客_51CTO博客 添加新的定时器 TimerId TimerQueue::addTimer(TimerCallback cb, //用户自定义回调Timestamp when, //定时器的超时时刻double interval) //重复触发间隔,小于0则不重…

《muduo网络库》学习笔记——muduo学习总结

muduo是基于非阻塞的IO和事件驱动的网络库&#xff08;Reactor模式&#xff09;&#xff0c;其核心是一个事件循环EventLoop&#xff0c;用于响应计时器和IO事件。muduo采用基于对象&#xff08;object-based&#xff09;而非面向对象&#xff08;object-oriented&#xff09;的…

Ubuntu安装muduo库

1. 首先安装boost库&#xff1b; sudo apt-get update sudo apt-get install libboost-all-dev 2. 下载muduo库&#xff0c; https://github.com/chenshuo/muduo 3. 解压后进入解压目录&#xff0c;vim CMakeLists.txt&#xff0c;注释掉略过unit_test测试用例代码的编译&#…

linux muduo 编译安装,muduo记录

1.muduo编译安装 编译muduo遇见的报错可以在github上的issue上面查找。一般都能顺利解决,我遇到的就是没有安装boost-dev. centos7系统 执行: sudo yum install boost-dev 2.截取流程图 图片截取自《Linux多线程服务端编程&#xff1a;使用muduo C网络库》 3.源码摘录 摘录一个…

muduo源码分析之TcpServer模块

这次我们开始muduo源代码的实际编写&#xff0c;首先我们知道muduo是LT模式&#xff0c;Reactor模式&#xff0c;下图为Reactor模式的流程图[来源1] 然后我们来看下muduo的整体架构[来源1] 首先muduo有一个主反应堆mainReactor以及几个子反应堆subReactor&#xff0c;其中子反应…

muduo网络库学习(1)

muduo网络库学习&#xff08;1&#xff09; 文章目录 muduo网络库学习&#xff08;1&#xff09;前言一、muduo是什么&#xff1f;二、代码结构1.base库2.net库3.附属库 二、网络库结构总结 前言 本章节主要介绍muduo网络库的整体架构&#xff01;一、muduo是什么&#xff1f;…

muduo

muduo 概述 muduo是基于Reactor模式的网络库&#xff0c;用于响应计时器和IO事件。 muduo采用基于对象而非面向对象的设计风格&#xff0c;其事件回调采用functionbind&#xff0c;用户在使用muduo的时候不需要继承其中的class 架构 Multiple Reactor Reactor模式&#xff1a…

muduo日志库原理以及源码分析

muduo日志库特点 日志批量写入批量唤醒写线程写日志用notifywait_timeout 方式触发日志的写入锁的粒度&#xff0c;双缓冲&#xff0c;双队列buffer默认 4M 缓冲区&#xff0c; buffers 是 buffer 队列&#xff0c; push 、 pop 时使用 move 语义 减少内存拷贝 muduo的这些特点…

muduo网络库与服务模型介绍

目录 一、muduo网络库简介 1、特点 2、代码结构 &#xff08;1&#xff09;公共接口 &#xff08;2&#xff09;内部实现 二、muduo线程模型 1、单线程Reactor 2、Reactor线程池 3、one loop per thread 4、one loop per thread 线程池 muduo是陈硕个人使用C开发的一…