OpenCV视觉分析之目标跟踪(12)找到局部的最大值函数meanShift()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

在反向投影图像上找到一个对象。

meanShift 是一种用于图像处理和计算机视觉领域的算法,特别适用于目标跟踪、图像分割等任务。该算法基于一个简单的概念:通过迭代地移动窗口到更高密度的区域,直到找到局部的最大值(即密度最高的点)。在图像处理中,这个"密度"通常指的是像素颜色或特征空间中的分布。

基本原理

  • 颜色空间中的应用:在颜色空间中,每个像素可以被视为一个点,这些点具有特定的颜色值。对于给定的目标(如一个特定颜色的物体),可以通过计算目标区域内所有像素的颜色直方图来定义其特征。meanShift 算法通过迭代地寻找颜色直方图中概率密度最大的点来跟踪目标的位置变化。
  • 迭代过程:在每次迭代中,算法会计算当前窗口内所有点的加权平均位置(权重通常是基于距离的核函数),并将窗口中心移动到这个新位置。这一过程会重复进行,直到窗口中心的变化小于某个阈值或达到最大迭代次数为止。

函数原型

cpp 复制代码
int cv::meanShift	
(
	InputArray 	probImage,
	Rect & 	window,
	TermCriteria 	criteria 
)		

参数

  • 参数probImage 对象直方图的反向投影。详情见 calcBackProject。
  • 参数window 初始搜索窗口。
  • 参数criteria 迭代搜索算法的停止准则。返回值:CAMSHIFT 收敛所需的迭代次数。该函数实现了迭代对象搜索算法。它接受对象的输入反向投影和初始位置。计算反向投影图像中窗口的质量中心,并将搜索窗口中心移动到质量中心。该过程重复进行,直到达到指定的迭代次数 criteria.maxCount 或者窗口中心移动的距离小于 criteria.epsilon。该算法在 CamShift 内部使用,与 CamShift 不同的是,在搜索过程中搜索窗口的大小或方向不会改变。您可以直接将 calcBackProject 的输出传递给此函数。但是,如果先对反向投影进行预过滤并去除噪声,可以获得更好的结果。例如,您可以通过 findContours 获取连通组件,丢弃面积较小的轮廓(contourArea),并使用 drawContours 绘制剩余的轮廓。

代码示例

cpp 复制代码
#include <iostream>
#include <opencv2/opencv.hpp>

int main()
{
    // 读取视频
    cv::VideoCapture cap( 0 );
    if ( !cap.isOpened() )
    {
        std::cout << "Error opening video file" << std::endl;
        return -1;
    }

    cv::Mat frame, hsv, mask, hist, backproj;
    cv::Rect trackWindow;

    // 从第一帧选择ROI
    cap >> frame;
    cv::imshow( "Select ROI", frame );
    trackWindow = cv::selectROI( "Select ROI", frame );
    cv::destroyWindow( "Select ROI" );

    // 转换到HSV色彩空间
    cv::cvtColor( frame, hsv, cv::COLOR_BGR2HSV );

    // 创建掩码
    cv::inRange( hsv, cv::Scalar( 0, 60, 32 ), cv::Scalar( 180, 255, 255 ), mask );

    // 定义直方图的范围
    const int channels[]  = { 0 };    // 仅使用H通道
    const int histSize[]  = { 180 };  // H通道有180个bin
    float hranges[]       = { 0, 180 };
    const float* ranges[] = { hranges };

    // 计算ROI的直方图
    cv::calcHist( &hsv, 1, channels, mask, hist, 1, histSize, ranges );

    // 归一化直方图
    cv::normalize( hist, hist, 0, 255, cv::NORM_MINMAX );

    while ( true )
    {
        cap >> frame;
        if ( frame.empty() )
            break;

        // 计算反向投影
        cv::cvtColor( frame, hsv, cv::COLOR_BGR2HSV );
        cv::calcBackProject( &hsv, 1, channels, hist, backproj, ranges );

        // 执行meanShift
        cv::meanShift( backproj, trackWindow, cv::TermCriteria( cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 10, 1 ) );

        // 在图像上画出跟踪框
        cv::rectangle( frame, trackWindow, cv::Scalar( 255, 0, 0 ), 2, 1 );

        // 显示结果
        cv::imshow( "Mean Shift Tracking", frame );

        char c = ( char )cv::waitKey( 30 );
        if ( c == 27 )
            break;  // 按ESC键退出
    }

    cap.release();
    cv::destroyAllWindows();

    return 0;
}

运行结果

相关推荐
向哆哆11 分钟前
卷积与动态特征选择:重塑YOLOv8的多尺度目标检测能力
yolo·目标检测·目标跟踪·yolov8
AL.千灯学长34 分钟前
DeepSeek接入Siri(已升级支持苹果手表)完整版硅基流动DeepSeek-R1部署
人工智能·gpt·ios·ai·苹果vision pro
LCG元1 小时前
大模型驱动的围术期质控系统全面解析与应用探索
人工智能
lihuayong1 小时前
计算机视觉:主流数据集整理
人工智能·计算机视觉·mnist数据集·coco数据集·图像数据集·cifar-10数据集·imagenet数据集
政安晨1 小时前
政安晨【零基础玩转各类开源AI项目】DeepSeek 多模态大模型Janus-Pro-7B,本地部署!支持图像识别和图像生成
人工智能·大模型·多模态·deepseek·janus-pro-7b
一ge科研小菜鸡2 小时前
DeepSeek 与后端开发:AI 赋能云端架构与智能化服务
人工智能·云原生
冰 河2 小时前
‌最新版DeepSeek保姆级安装教程:本地部署+避坑指南
人工智能·程序员·openai·deepseek·冰河大模型
维维180-3121-14552 小时前
AI赋能生态学暨“ChatGPT+”多技术融合在生态系统服务中的实践技术应用与论文撰写
人工智能·chatgpt
終不似少年遊*2 小时前
词向量与词嵌入
人工智能·深度学习·nlp·机器翻译·词嵌入
杜大哥2 小时前
如何在WPS打开的word、excel文件中,使用AI?
人工智能·word·excel·wps