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

opencv光流法推测物体的运动

        光流法是计算机视觉中的一种技术,用于估计图像中相邻帧之间的像素位移或运动。它是一种用于追踪图像中物体运动的技术,可以在视频中检测并测量物体的运动轨迹。基本上,光流意味着计算像素的移动向量作为物体在两个相邻图像之间的位移差。光流的主要思想是估计物体运动或摄像机运动引起的物体的位移矢量。

光流法基于以下两个主要假设:

        灰度恒定假设(Brightness Constancy Assumption): 在短时间内,相邻帧中的像素灰度值保持不变。这意味着在相邻帧中,同一物体的灰度值应该是相似的。

        空间一致性假设(Spatial Coherence Assumption): 邻近像素点的运动是相似的。这意味着在一个小的局部区域内,像素点的运动可以通过一个共同的运动向量来描述。

        基于上述两个假设,光流法的目标是计算场景中每个像素点在图像平面上的运动矢量。这些运动矢量描述了像素从一帧到下一帧的位移。

        在光流法的实现中,有几种不同的方法,其中最常见的是Lucas-Kanade方法和Horn-Schunck方法。

        Lucas-Kanade方法: 该方法基于灰度恒定和空间一致性假设,通过在图像上的局部区域内求解一个线性方程组来计算运动矢量。它假设邻近像素点的运动是相似的,因此在局部区域内使用最小二乘法来估计运动。

        Horn-Schunck方法: 该方法通过最小化整个图像上的一个全局能量函数来计算光流场。它对整个图像施加了平滑性的约束,因此在处理相对较大的运动时效果较好。

        总体而言,光流法是一种有用的技术,尤其在分析视频中物体的运动、跟踪目标或检测异常事件时。

光流法检测中稠密光流函数说明:

        calcOpticalFlowPyrLK(Lucas-Kanade光流算法)函数是OpenCV库中的一个函数,用于计算图像序列中的稠密光流。‌ 该函数基于Gunnar Farneback的算法,能够估计图像序列中每一点的运动向量。

函数原型和参数说明

void calcOpticalFlowFarneback(InputArray prev, InputArray next, OutputArray flow, double pyr_scale, int levels, int winsize, int iterations, int poly_n, double poly_sigma, int flags);

参数说明:

  • prev:第一帧输入图像。
  • next:第二帧输入图像,与第一帧图像大小和类型相同。
  • flow:计算得到的光流图像,大小与prev相同,类型为CV_32FC2
  • pyr_scale:构建金字塔的图像尺度参数,通常设置为0.5
  • levels:金字塔的层数。
  • winsize:均值窗口的大小,影响去噪效果和运动检测的灵敏度。
  • iterations:迭代次数。
  • poly_n:多项式展开的阶数,通常为57
  • poly_sigma:高斯函数的标准差。
  • flags:计算方法标志,可以包括OPTFLOW_USE_INITIAL_FLOWOPTFLOW_FARNEBACK_GAUSSIAN等。

具体使用示例函数:

//检测前后两帧图像是否有物体移动

bool MoveDetect(cv::Mat background, cv::Mat frame)

{

         bool ret = false;

        

    //1.将background和frame转为灰度图

    cv::Mat gray1, gray2;

    cv::cvtColor(background, gray1, cv::COLOR_BGR2GRAY);

    cv::cvtColor(frame, gray2, cv::COLOR_BGR2GRAY);

    //2.将background和frame做差

    cv::Mat m_different;

    cv::absdiff(gray1, gray2, m_different);

    //3.对差值图diff_thresh进行阈值化处理

    cv::Mat Dif_Thresh;

    cv::threshold(m_different, Dif_Thresh, 50, 255, cv::THRESH_BINARY);

    //4.腐蚀

    cv::Mat kernel_erode = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    cv::Mat kernel_dilate = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15));

    cv::erode(Dif_Thresh, Dif_Thresh, kernel_erode);

    //5.膨胀

    cv::dilate(Dif_Thresh, Dif_Thresh, kernel_dilate);

    //6.查找轮廓

    std::vector<std::vector<cv::Point>> contours;

    cv::findContours(Dif_Thresh, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

         if(contours.size())

                  ret = true;

        

    return ret;

}

//检测前后两帧图像物体移动的方向

Int MoveDirect(cv::Mat background, cv::Mat frame)

{

         int m_direct = 0;

         cv::Mat flow;

    //1.将background和frame转为灰度图

    cv::Mat gray1, gray2;

    cv::cvtColor(background, gray1, cv::COLOR_BGR2GRAY);

    cv::cvtColor(frame, gray2, cv::COLOR_BGR2GRAY);

         // 计算稠密光流

    cv::calcOpticalFlowFarneback(gray1, gray2, flow, 0.5, 3, 15, 3, 5, 1.2, 0);

    // 判断物体运动方向

    double sumX = 0, sumY = 0;

    int count = 0;

    for (int y = 0; y < flow.rows; y += 8) {

        for (int x = 0; x < flow.cols; x += 8) {

            const cv::Point2f &fxy = flow.at<cv::Point2f>(y, x);

            sumX += fxy.x;

            sumY += fxy.y;

            count++;

        }

    }

    double avgX = sumX / count;

    double avgY = sumY / count;

         std::cout << " MoveDirect,avgX=" << avgX <<",avgY=" << avgY << std::endl;

    if (avgX > 0 && avgY > 0)

         {

        m_direct = 1;

    }

         else if (avgX < 0 && avgY < 0)

         {

        m_direct = -1;

    }

                                  

    return m_direct;

}


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

相关文章:

  • Java基础知识总结(三十二)--API--- java.lang.Runtime
  • 【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测
  • 算法的时间复杂度
  • 【llm对话系统】大模型 RAG 之回答生成:融合检索信息,生成精准答案
  • 设计模式-建造者模式、原型模式
  • FreeRTOS学习 --- 动态任务创建和删除的详细过程
  • Spring Boot日志:从Logger到@Slf4j的探秘
  • ChatGPT 最新推出的 Pro 订阅计划,具备哪些能力 ?
  • uniapp 微信小程序webview 和 h5数据通信
  • 【AWS re:Invent 2024】一文了解EKS新功能:Amazon EKS Auto Mode
  • Python实现BBS论坛自动签到【steamtools论坛】
  • Python 入门教程(2)搭建环境 | 2.4、VSCode配置Node.js运行环境
  • 如何利用DBeaver配置连接MongoDB和人大金仓数据库
  • django 实战(python 3.x/django 3/sqlite)
  • AI by Hand:手搓 AI 模型
  • git遇见冲突怎么解决?
  • Dell电脑安装Centos7问题处理
  • Python Virtualenv 虚拟环境迁移, 换新电脑后 Python 环境快速迁移 Virtualenv 环境配置管理,实测篇
  • 黑马程序员Java项目实战《苍穹外卖》Day12
  • 十六、大数据之Shell 编程
  • 第四十一天 ASP应用 HTTP.sys 漏洞 iis6文件解析漏洞和短文件漏洞 access数据库泄露漏洞
  • L-BFGS 方法实现
  • Hive 中 Order By、Sort By、Cluster By 和 Distribute By 的详细解析
  • 流量转发利器之Burpsuite概述(1)
  • 监控易管理平台7.0助力打造智慧运维体系
  • DataEase 是开源的 BI 工具