前景物体提取
参考:精选课: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;
}
相关文章:
前景物体提取
参考:精选课:C完整的实现双目摄像头图像采集、双目摄像头畸变矫正、前景物体提取、生成视差图、深度图、PCL点云图 前景物体提取是计算机视觉中的一个重要技术,可以用于视频监控、虚拟现实和计算机视觉等领域。 1.前景物体提取的原理 前景…...

Kotlin复习
一、Kotlin类型 1.整数 2.浮点 显示转换: 所有数字类型都支持转换为其他类型,但是转换前会检测长度。 toByte(): Byte toShort(): Short toInt(): Int toLong(): Long toFloat(): Float toDouble(): Double 不同进制的数字表示方法(为了提高…...

【AI日记】24.12.17 kaggle 比赛 2-6 | 把做饭看成一种游戏 | 咖喱牛肉
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加:kaggle 比赛 Regression with an Insurance Dataset时间:9 小时睡得好很重要 读书 书名:富兰克林自传时间:0.5 小时阅读原因:100 美元纸…...

操作系统(14)请求分页
前言 操作系统中的请求分页,也称为页式虚拟存储管理,是建立在基本分页基础上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能的一种内存管理技术。 一、基本概念 分页:将进程的逻辑地址空间分成若干个大小相等的页&am…...
uniapp navigateTo、redirectTo、reLaunch等页面路由跳转方法的区别
uni.switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 // app.json {"tabBar": {"list": [{"pagePath": "index","text": "首页"},{"pagePath": "other","text&…...

模型 A/B测试(科学验证)
系列文章 分享 模型,了解更多👉 模型_思维模型目录。控制变量法。 1 A/B测试的应用 1.1 Electronic Arts(EA)《模拟城市》5游戏网站A/B测试 定义目标: Electronic Arts(EA)在发布新版《模拟城…...

谷歌发布升级版AI视频生成器Veo 2与图像生成器Imagen 3
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

快速掌握源码部署Filebeat
文章目录 1. 裸金属安装1.1 压缩包方式安装1.2 yum方式安装 2. docker安装3. K8s安装 项目使用了Filebeat,现在需要运行在ARM架构的服务器上,但是Filebeat官方没有提供,需要自己编译一份 filebeat等组件的源码地址 https://github.com/elasti…...

C++ 哈希表封装unordered_map 和 unordered_set
1.源码框架 SGI-STL30版本源代码中没有unordered_map和unordered_set,SGI-STL30版本是C11之前的STL 版本,这两个容器是C11之后才更新的。但是SGI-STL30实现了哈希表,只容器的名字是hash_map 和hash_set,他是作为⾮标准的容器出现…...
pymysql 入门
发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 1. 什么是 PyMySQL? PyMySQL 是一个纯 Python 编写的 MySQL 客户端库,可以通过它轻松地在 Python 中连…...

Leecode刷题C++之形成目标字符串需要的最少字符串数①
执行结果:通过 执行用时和内存消耗如下: 代码如下: class Solution { public:int minValidStrings(vector<string>& words, string target) {auto prefix_function [](const string& word, const string& target) -> vector<…...

Linux应用开发————mysql数据库
数据库概述 什么是数据库(database)? 数据库是一种数据管理的管理软件,它的作用是为了有效管理数据,形成一个尽可能无几余的数据集合,并能提供接口,方便用户使用。 数据库能用来干什么? 顾名思义,仓库就是用来保存东…...

4_使用 HTML5 Canvas API (3) --[HTML5 API 学习之旅]
4_使用 HTML5 Canvas API (3) --[HTML5 API 学习之旅] 1.缩放 canvas 对象 在 <canvas> 中缩放对象可以通过 scale 方法来实现。这个方法会根据提供的参数对之后绘制的所有内容进行缩放。下面是两个具体的示例,展示如何使用 scale 方法来缩放 canvas 上的对…...
docker build次数过多,导致磁盘内存不足:ERROR: no space left on device
在使用 docker build 构建镜像时,Docker 会创建一个临时的构建上下文,生成镜像的过程中会产生多个中间层。这些文件和层会占用磁盘空间。构建完成后,如果你没有清理这些不再使用的中间层和临时文件,可能会导致磁盘空间不足。 常见…...
LDO和DC-DC的区别、DCDC和LDO主要指标
LDO和DC-DC的区别 LDO外围器件少,电路简单,成本低;DC-DC外围器件多,电路复杂,成本高; LDO负载响应快,输出纹波小;DC-DC负载响应比LDO慢,输出纹波大; LDO效…...
LeetCode hot100-81
https://leetcode.cn/problems/climbing-stairs/description/?envTypestudy-plan-v2&envIdtop-100-liked 70. 爬楼梯 已解答 简单 相关标签 相关企业 提示 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&…...
RTMP、RTSP、RTP、HLS、MPEG-DASH协议的简介,以及应用场景
实时视频传输协议 1. RTMP(Real Time Messaging Protocol) 简介:RTMP是由Adobe公司开发的实时消息传输协议,主要用于流媒体数据的传输。它基于TCP传输,具有低延迟、高可靠性的特点。特点:RTMP支持多种视…...

力扣-图论-15【算法学习day.65】
前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非…...

“AI智慧数字孪生系统:开启智能新纪元
嘿,大家好!今天我想和大家聊聊一个特别酷炫的话题——AI智慧数字孪生系统。这可是个新鲜玩意儿,可能有些朋友还不太了解,别急,我来慢慢道来。 首先,啥叫数字孪生呢?简单来说,就是给现…...

54、库卡机器人轴的软限位设置
步骤1:将用户组改为“专家”。 步骤2:点击“投入运行”----“售后服务”-----“软件限位开关” 步骤3:就可以针对每个轴修改对应的角度值,然后点击“保存”。...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...