前景物体提取

参考:精选课:C++完整的实现双目摄像头图像采集、双目摄像头畸变矫正、前景物体提取、生成视差图、深度图、PCL点云图

前景物体提取是计算机视觉中的一个重要技术,可以用于视频监控、虚拟现实和计算机视觉等领域。

1.前景物体提取的原理

前景物体提取是将摄像机拍摄到的图像中的前景物体(如移动的人、车辆等)从背景中分离出来的过程。其原理是利用帧间差分和背景建模两个步骤。帧间差分是通过相邻帧之间像素点灰度值的差异来检测出运动目标,背景建模是通过不断更新背景图像来适应场景的变化。

2.实现步骤

步骤1:读取摄像机视频并初始化,使用OpenCV库来读取摄像机视频:

cv::VideoCapture cap(0);
if (!cap.isOpened()) {
   std::cout << "Cannot open camera" << std::endl;
   return -1;
}

cv::Mat frame;
cap.read(frame);

步骤2:背景建模,定义一个背景图像和一个学习率,初始值为0.01。在每一帧中,将当前帧与背景图像相减,得到一个差分图像。

cv::Mat background;
double learning_rate = 0.01;

// 第一帧作为背景图像
background = frame.clone();

// 对于后面的帧,逐像素地计算背景图像
while (true) {

    cap.read(frame);

    // 将当前帧与背景图像相减,得到一个差分图像
    cv::Mat diff;
    cv::absdiff(frame, background, diff);

    // 根据差分图像更新背景图像
    for (int i = 0; i < diff.rows; i++) {
        for (int j = 0; j < diff.cols; j++) {
            cv::Vec3b pixel = diff.at<cv::Vec3b>(i, j);
            if (pixel[0] > 50 || pixel[1] > 50 || pixel[2] > 50) {
                // 更新背景像素
                cv::Vec3b background_pixel = background.at<cv::Vec3b>(i, j);
                cv::Vec3b frame_pixel = frame.at<cv::Vec3b>(i, j);
                background_pixel[0] = (1 - learning_rate) * background_pixel[0] + learning_rate * frame_pixel[0];
                background_pixel[1] = (1 - learning_rate) * background_pixel[1] + learning_rate * frame_pixel[1];
                background_pixel[2] = (1 - learning_rate) * background_pixel[2] + learning_rate * frame_pixel[2];
                background.at<cv::Vec3b>(i, j) = background_pixel;
            }
        }
    }
}

步骤3:帧间差分,将当前帧与背景图像相减,得到差分图像。然后将差分图像进行二值化处理,得到前景物体掩模。

// 帧间差分
cv::Mat diff;
cv::absdiff(frame, background, diff);

// 二值化处理,得到前景掩模
cv::Mat foreground_mask;
cv::threshold(diff, foreground_mask, 50, 255, cv::THRESH_BINARY);

步骤4:过滤掉小的前景物体,使用形态学操作对前景掩模进行处理,去除噪声和小物体。

// 使用开运算去除噪声和小物体
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));
cv::Mat foreground_mask_filtered;
cv::morphologyEx(foreground_mask, foreground_mask_filtered, cv::MORPH_OPEN, kernel);

步骤5:显示结果,将原始图像和前景掩模相乘,得到只有前景物体的图像。

// 显示结果
cv::Mat result = frame.clone();
cv::Mat foreground_image = cv::Mat::zeros(frame.size(), frame.type());
frame.copyTo(foreground_image, foreground_mask_filtered);

cv::imshow("Original Image", frame);
cv::imshow("Foreground Mask", foreground_mask_filtered);
cv::imshow("Foreground Image", foreground_image);

cv::waitKey(30);

3.完整代码

演示了对单个摄像头的前景物体提取,双目摄像机需要对两个摄像头的同一幅图片场景分别做前景物体提取,然后作为左右视图对其进行进一步畸变矫正。

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

int main() {
    // 打开摄像机
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) {
        std::cout << "Cannot open camera" << std::endl;
        return -1;
    }

    // 初始化
    cv::Mat frame;
    cap.read(frame);

    // 背景建模
    cv::Mat background;
    double learning_rate = 0.01;
    background = frame.clone();
    while (true) {
        // 读取帧
        cap.read(frame);

        // 背景建模
        cv::Mat diff;
        cv::absdiff(frame, background, diff);

        for (int i = 0; i < diff.rows; i++) {
            for (int j = 0; j < diff.cols; j++) {
                cv::Vec3b pixel = diff.at<cv::Vec3b>(i, j);
                if (pixel[0] > 50 || pixel[1] > 50 || pixel[2] > 50) {
                    cv::Vec3b background_pixel = background.at<cv::Vec3b>(i, j);
                    cv::Vec3b frame_pixel = frame.at<cv::Vec3b>(i, j);
                    background_pixel[0] = (1 - learning_rate) * background_pixel[0] + learning_rate * frame_pixel[0];
                    background_pixel[1] = (1 - learning_rate) * background_pixel[1] + learning_rate * frame_pixel[1];
                    background_pixel[2] = (1 - learning_rate) * background_pixel[2] + learning_rate * frame_pixel[2];
                    background.at<cv::Vec3b>(i, j) = background_pixel;
                }
            }
        }

        // 帧间差分
        cv::Mat diff2;
        cv::absdiff(frame, background, diff2);
        cv::Mat foreground_mask;
        cv::threshold(diff2, foreground_mask, 50, 255, cv::THRESH_BINARY);

        // 去除噪声和小物体
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));
        cv::Mat foreground_mask_filtered;
        cv::morphologyEx(foreground_mask, foreground_mask_filtered, cv::MORPH_OPEN, kernel);

        // 显示结果
        cv::Mat result = frame.clone();
        cv::Mat foreground_image = cv::Mat::zeros(frame.size(), frame.type());
        frame.copyTo(foreground_image, foreground_mask_filtered);

        cv::imshow("Original Image", frame);
        cv::imshow("Foreground Mask", foreground_mask_filtered);
        cv::imshow("Foreground Image", foreground_image);

        cv::waitKey(30);
    }

    // 释放资源
    cap.release();
    cv::destroyAllWindows();

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938301.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++类模板的应用

template <class T> class mylist{ public: // 这是一个链表的节点 struct Link{ T val; Link* next; } 增 &#xff1a;insert(T val) 在链表中创建新节点&#xff0c;节点上保存的数据为 val 删&#xff1a;remove(T val) 移除链表中数据为 val 的节点 改: operator[](…

python学opencv|读取图像(十二)BGR图像转HSV图像

【1】引言 前述已经学习了opencv中图像BGR相关知识&#xff0c;文章链接包括且不限于下述&#xff1a; python学opencv|读取图像&#xff08;六&#xff09;读取图像像素RGB值_opencv读取灰度图-CSDN博客 python学opencv|读取图像&#xff08;七&#xff09;抓取像素数据顺利…

基于 mzt-biz-log 实现接口调用日志记录

&#x1f3af;导读&#xff1a;mzt-biz-log 是一个用于记录操作日志的通用组件&#xff0c;旨在追踪系统中“谁”在“何时”对“何事”执行了“何种操作”。该组件通过简单的注解配置&#xff0c;如 LogRecord&#xff0c;即可实现接口调用的日志记录&#xff0c;支持成功与失败…

如何在繁忙的生活中找到自己的节奏?

目录 一、理解生活节奏的重要性 二、分析当前生活节奏 1. 时间分配 2. 心理状态 3. 身体状况 4. 生活习惯 1. 快慢适中 2. 张弛结合 3. 与目标相符 三、掌握调整生活节奏的策略 1. 设定优先级 2. 合理规划时间 3. 学会拒绝与取舍 4. 保持健康的生活方式 5. 留出…

Docker:目录挂载、数据卷(补充二)

Docker&#xff1a;目录挂载、数据卷 1. 挂载2. 卷映射 1. 挂载 -v /app/nghtml:/usr/share/nginx/html /app/nghtml 是外部主机的地址 /usr/share/nginx/html 是内部容器的地址这里启动一个nginx&#xff0c;然后在后台运行时其命令为 (base) ➜ ~ docker run -d -p 80:80 …

新能源汽车大屏可视化第三次数据存储

任务&#xff1a; 将数据存放到temp.csv 链接&#xff1a; 1.排行页面 https://www.dongchedi.com/sales 2.参数页面 https://www.dongchedi.com/auto/params-carIds-x-9824 完善打印&#xff1a; 1. [{‘series_id’: 5952, ‘series_name’: ‘海鸥’, ‘image’: ‘https://…

Three.js资源-模型下载网站

在使用 Three.js 进行 3D 开发时&#xff0c;拥有丰富的模型资源库可以大大提升开发效率和作品质量。以下是一些推荐的 Three.js 模型下载网站&#xff0c;它们提供了各种类型的 3D 模型&#xff0c;适合不同项目需求。无论你是需要逼真的建筑模型&#xff0c;还是简单的几何体…

无人机故障安全模式设计逻辑与技术!

一、设计逻辑 故障检测与识别&#xff1a; 无人机系统需具备实时监测各项关键参数的能力&#xff0c;如电池电量、电机状态、传感器数据等。 当检测到参数异常或超出预设阈值时&#xff0c;系统应能迅速识别故障类型及其严重程度。 故障处理策略&#xff1a; 根据故障类型…

洞察:OpenAI 全球宕机,企业应该如何应对 LLM 的不稳定性?

北京时间12月12日上午&#xff0c;OpenAI证实其聊天机器人ChatGPT正经历全球范围的宕机&#xff0c;ChatGPT、Sora及API受到影响。 OpenAI 更新事故报告称&#xff0c;已查明宕机原因&#xff0c;正努力以最快速度恢复正常服务&#xff0c;并对宕机表示歉意。 此次 OpenAI 故障…

STM32F407ZGT6-UCOSIII笔记2:UCOSIII任务创建实验-Printf 函数卡住 UCOSIII 系统问题解决

今日简单编写熟悉一下UCOSIII系统的任务创建代码&#xff0c;理解一下OS系统&#xff1a; 并发现以及解决了 Printf 函数卡住 UCOSIII 系统问题解决 文章提供测试代码讲解、完整工程下载、测试效果图 目录 文件结构解释&#xff1a; 任务函数文件&#xff1a; 目前各个文件任…

CUDA从入门到精通(三)——CUDA编程示例

CUDA 编程简介 CUDA&#xff08;Compute Unified Device Architecture&#xff09;是由 NVIDIA 提供的一种并行计算平台和编程模型。它允许开发者利用 NVIDIA GPU 的并行计算能力&#xff0c;编写可以在 GPU 上高效运行的代码&#xff0c;从而加速计算密集型任务。 CUDA 通过…

【十进制整数转换为其他进制数——短除形式的贪心算法】

之前写过一篇用贪心算法计算十进制转换二进制的方法&#xff0c;详见&#xff1a;用贪心算法计算十进制数转二进制数&#xff08;整数部分&#xff09;_短除法求二进制-CSDN博客 经过一段时间的研究&#xff0c;本人又发现两个规律&#xff1a; 1、不仅仅十进制整数转二进制可…

舵机SG90详解

舵机&#xff0c;也叫伺服电机&#xff0c;在嵌入式开发中&#xff0c;舵机作为一种常见的运动控制组件&#xff0c;具有广泛的应用。其中&#xff0c;SG90 舵机以其高效、稳定的性能特点&#xff0c;成为了许多工程师和爱好者的首选&#xff0c;无论是航模、云台、机器人、智能…

如何为IntelliJ IDEA配置JVM参数

在使用IntelliJ IDEA进行Java开发时&#xff0c;合理配置JVM参数对于优化项目性能和资源管理至关重要。IntelliJ IDEA提供了两种方便的方式来设置JVM参数&#xff0c;以确保你的应用程序能够在最佳状态下运行。本文将详细介绍这两种方法&#xff1a;通过工具栏编辑配置和通过服…

跌倒数据集,5345张图片, 使用yolo,coco json,voc xml格式进行标注,平均识别率99.5%以上

跌倒数据集&#xff0c;5345张图片&#xff0c; 使用yolo&#xff0c;coco json&#xff0c;voc xml格式进行标注&#xff0c;平均识别率99.5%以上 &#xff0c;可用于某些场景下识别人是否跌倒或摔倒并进行告警。 数据集分割 训练组99&#xff05; 5313图片 有效集0&am…

nods.js之nrm安装及使用

nods.js之nrm安装及使用 一、简介二、安装 nrm与使用三、报错解决 一、简介 nrm 是 Node.js 的一个工具&#xff0c;用于管理和切换 npm 源&#xff08;Registry&#xff09;。它使得在不同的 npm 镜像源之间切换变得非常容易&#xff0c;尤其对于那些经常因为网络问题或速度原…

selenium自动化测试基础知识

目录 一、概念知识 (一)三大核心组件 (二)Selenium 自动化测试的工作原理 (三)Selenium 支持的操作 (四)Selenium 自动化测试的优点 (五)Selenium 自动化测试的缺点 (六)Selenium 自动化测试的应用场景 总结 二、实操例子 使用前提--安装步骤 注意事项 (一)浏览器的…

Cisco Packet Tarcer配置计网实验笔记

文章目录 概要整体架构流程网络设备互连基础拓扑图拓扑说明配置步骤 RIP/OSPF混合路由拓扑图拓扑说明配置步骤 BGP协议拓扑图拓扑说明配置步骤 ACL访问控制拓扑图拓扑说明配置步骤 HSRP冗余网关拓扑图拓扑说明配置步骤 小结 概要 一些环境配置笔记 整体架构流程 网络设备互连…

RNN LSTM Seq2Seq Attention

非端到端&#xff1a; data -》 cleaning -》 feature Engining &#xff08;70%-80%工作 设计特征&#xff09;-》 分类器 -》预测 端到端 End-to-End&#xff1a; data -》 cleaning -》Deep learning&#xff08;表示学习&#xff0c;从数据中学习特征&#xff09; -》…

【AI日记】24.12.17 kaggle 比赛 2-6 | 把做饭看成一种游戏 | 咖喱牛肉

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加&#xff1a;kaggle 比赛 Regression with an Insurance Dataset时间&#xff1a;9 小时睡得好很重要 读书 书名&#xff1a;富兰克林自传时间&#xff1a;0.5 小时阅读原因&#xff1a;100 美元纸…