当前位置: 首页 > article >正文

OpenCV视觉分析之目标跟踪(8)目标跟踪函数CamShift()使用

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

算法描述

找到物体的中心、大小和方向。

CamShift(Continuously Adaptive Mean Shift)是 OpenCV 中的一种目标跟踪算法,广泛应用于视频中对象的跟踪。CamShift 算法结合了 Mean Shift 算法和颜色直方图,通过迭代寻找目标区域的颜色分布中心,从而实现目标的跟踪。

基本原理

  • 颜色直方图:首先,根据目标区域的颜色信息构建颜色直方图。颜色直方图描述了目标区域中各颜色的分布情况。
  • Mean Shift:Mean Shift 算法通过迭代寻找目标区域的颜色分布中心,逐步调整目标区域的位置和大小。
  • 适应性调整:CamShift 算法不仅调整目标区域的位置,还根据目标区域的颜色分布调整其大小和方向,从而实现更精确的跟踪。

代码示例



#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

Rect selection;
bool selecting   = false;
bool trackObject = false;
Point origin;
Mat frame;  // 声明一个全局变量来存储当前帧

void onMouse( int event, int x, int y, int, void* )
{
    if ( selecting )
    {
        selection.x      = MIN( x, origin.x );
        selection.y      = MIN( y, origin.y );
        selection.width  = abs( x - origin.x );
        selection.height = abs( y - origin.y );
        selection &= Rect( 0, 0, frame.cols, frame.rows );  // 使用全局变量 frame
    }

    switch ( event )
    {
    case EVENT_LBUTTONDOWN:
        selecting = true;
        origin    = Point( x, y );
        selection = Rect( x, y, 0, 0 );
        break;
    case EVENT_LBUTTONUP:
        selecting = false;
        if ( selection.width > 0 && selection.height > 0 )
        {
            trackObject = true;
        }
        break;
    }
}

int main()
{
    VideoCapture cap(0);
    if ( !cap.isOpened() )
    {
        cerr << "Error opening video file" << endl;
        return -1;
    }

    namedWindow( "CamShift Tracker", WINDOW_NORMAL );
    setMouseCallback( "CamShift Tracker", onMouse );

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

        Mat hsv_frame, hue_frame, mask, backproj;
        cvtColor( frame, hsv_frame, COLOR_BGR2HSV );

        if ( trackObject )
        {
            // 提取 H(色调)通道
            vector< Mat > hsv_channels;
            split( hsv_frame, hsv_channels );
            Mat hue_channel = hsv_channels[ 0 ];

            // 计算颜色直方图
            Mat roi = hue_channel( selection );
            Mat hsv_hist;
            int histSize[]        = { 32 };
            float hranges[]       = { 0, 180 };
            const float* ranges[] = { hranges };
            calcHist( &roi, 1, 0, Mat(), hsv_hist, 1, histSize, ranges, true, false );
            normalize( hsv_hist, hsv_hist, 0, 255, NORM_MINMAX );

            // 计算反投影
            calcBackProject( &hue_channel, 1, 0, hsv_hist, backproj, ranges, 1, true );

            // 使用 CamShift 进行跟踪
            TermCriteria term_crit( TermCriteria::COUNT | TermCriteria::EPS, 10, 1 );
            RotatedRect track_box = CamShift( backproj, selection, term_crit );

            // 绘制跟踪结果
            ellipse( frame, track_box, Scalar( 0, 255, 0 ), 2 );
        }

        // 绘制选择区域
        if ( selecting )
        {
            rectangle( frame, selection, Scalar( 255, 0, 0 ), 2 );
        }

        imshow( "CamShift Tracker", frame );

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

    cap.release();
    destroyAllWindows();

    return 0;
}

运行结果

在这里插入图片描述


http://www.kler.cn/a/383506.html

相关文章:

  • MyBatis 返回 Map 或 List<Map>时,时间类型数据,默认为LocalDateTime,响应给前端默认含有‘T‘字符
  • CSS弹性布局:灵活布局的终极指南
  • Java:二维数组
  • Ubuntu 安装 RTL8811cu 网卡驱动
  • 工业以太网PLC无线网桥,解决用户布线难题!
  • TCP:确认机制、重传以及选择性确认(SACK)
  • 【RESP问题】RESP.app GUI for Redis 连接不上redis服务器
  • AI - 使用LangChain请求LLM结构化生成内容
  • Unet++改进3:添加NAMAttention注意力机制
  • 重新回顾反向传播与梯度下降:训练神经网络的基石
  • Redis安装配置及基本使用(保姆级安装教程非常耐用)
  • 【云原生开发】K8S多集群资源管理平台架构设计
  • 【静态页面】尚品汇 1、设计稿分析及资源准备
  • Nginx 在中小企业的初级应用实操指南
  • 【HCIP园区网综合拓扑实验】配置步骤与详解(未施工完,持续更新中)
  • git撤销commit和add
  • 【YOLO学习】YOLOv8改进举例
  • 深入理解Java虚拟机(JVM):从基础到实战
  • 【p2p、分布式,区块链笔记 Torrent】WebTorrent bittorrent-dht DHT的构造+lookup+announce
  • 领克双十一营销设计:视觉与策略的完美融合
  • Flutter 鸿蒙next中的 Stack 和 Positioned 用法详解
  • 算法练习:1004. 最大连续1的个数 III
  • 基于SSM+VUE守护萌宠宠物网站JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解
  • ORACLE 19C 安装数据库补丁的详细过程
  • 利用全排列解决LeetCode第3343题“统计平衡排列的数目”问题
  • 【Java SE语法】抽象类(abstract class)和接口(interface)有什么异同?