利用OpenCV实现绿幕视频背景替换
创作时间:
作者:
@小白创作中心
利用OpenCV实现绿幕视频背景替换
引用
1
来源
1.
https://www.zhangshengrong.com/p/w4N7DxxgXr/
本文将详细介绍如何使用OpenCV C++实现绿幕视频背景替换。通过将视频转换为HSV色彩空间,使用inRange函数进行颜色范围筛选,最后通过像素赋值实现背景替换。文章包含完整的代码示例和步骤说明,适合有一定编程基础的读者学习参考。
前言
本文将使用OpenCV C++ 进行绿幕视频背景替换。
一、图像预处理
背景
绿幕视频
首先,我们需要使用resize API将背景图尺寸修改与视频尺寸大小。这样才能进行后续的像素赋值操作。
Mat bg = imread("background.jpg"); //背景图
VideoCapture capture; //读取待处理的绿幕视频
capture.open("5.flv");
if (!capture.isOpened())
{
cout << "Can not open video!" << endl;
system("pause");
return -1;
}
int width = capture.get(CAP_PROP_FRAME_WIDTH);
int height = capture.get(CAP_PROP_FRAME_HEIGHT);
resize(bg, bg, Size(width, height), 1, 1, INTER_CUBIC); //将背景图resize成视频尺寸大小
二、HSV色彩空间转换
1. cvtColor色彩空间转换
cvtColor(frame, HSV, COLOR_BGR2HSV); //将原图转换成HSV色彩空间
2. inRange抠图
经百度查表,我们可以获取绿色HSV颜色分量范围
//绿色HSV颜色分量范围
int hmin = 35, smin = 43, vmin = 46;
int hmax = 77, smax = 255, vmax = 255;
由于我们已经将原图转换为HSV色彩空间,故可以使用inRange API将前景从绿幕中抠出来。inRange将两阈值内的像素置为255(即绿色被置为白色),阈值外的像素置为0(其他颜色被置为黑色)。故由此我们可以将前景抠出来。
//经过inRange API处理,输出一张二值图像,即将前景从绿幕中扣出来啦
inRange(HSV, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), mask);
mask图像,即从绿幕中抠出来的前景图。
三、背景替换
我们通过修改图像像素值达到替换背景目的。通过遍历视频图像像素值,当mask像素值为0时,表示此时图像像素为前景,将绿幕视频当前像素点赋给目标图像dst;当mask像素值为255时,表示此时图像像素为背景,将背景图当前像素点赋给目标图像dst。
Mat Replace_Background(Mat frame, Mat mask, Mat bg)
{
Mat dst = Mat::zeros(frame.size(), frame.type());
for (int i = 0; i < frame.rows; i++)
{
for (int j = 0; j < frame.cols; j++)
{
int p = mask.at<uchar>(i, j); //传入的mask是张二值图,p为当前mask像素值
if (p == 0)
{ //代表mask此时为前景,将绿幕视频中的前景像素赋给dst
dst.at<Vec3b>(i, j) = frame.at<Vec3b>(i, j);
}
else if (p == 255)
{
//代表mask此时为背景,将背景图像素赋给dst
dst.at<Vec3b>(i, j) = bg.at<Vec3b>(i,j);
}
}
}
return dst;
}
最终效果如图所示。
四、源码
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat Replace_Background(Mat frame, Mat mask, Mat bg)
{
Mat dst = Mat::zeros(frame.size(), frame.type());
for (int i = 0; i < frame.rows; i++)
{
for (int j = 0; j < frame.cols; j++)
{
int p = mask.at<uchar>(i, j); //传入的mask是张二值图,p为当前mask像素值
if (p == 0)
{ //代表mask此时为前景,将绿幕视频中的前景像素赋给dst
dst.at<Vec3b>(i, j) = frame.at<Vec3b>(i, j);
}
else if (p == 255)
{
//代表mask此时为背景,将背景图像素赋给dst
dst.at<Vec3b>(i, j) = bg.at<Vec3b>(i,j);
}
}
}
return dst;
}
int main()
{
Mat bg = imread("background.jpg"); //背景图
VideoCapture capture; //读取待处理的绿幕视频
capture.open("5.flv");
if (!capture.isOpened())
{
cout << "Can not open video!" << endl;
system("pause");
return -1;
}
int width = capture.get(CAP_PROP_FRAME_WIDTH);
int height = capture.get(CAP_PROP_FRAME_HEIGHT);
resize(bg, bg, Size(width, height), 1, 1, INTER_CUBIC); //将背景图resize成视频尺寸大小
Mat frame, HSV, mask, dst;
//绿色HSV颜色分量范围
int hmin = 35, smin = 43, vmin = 46;
int hmax = 77, smax = 255, vmax = 255;
while (capture.read(frame))
{
cvtColor(frame, HSV, COLOR_BGR2HSV); //将原图转换成HSV色彩空间
//经过inRange API处理,输出一张二值图像,即将前景从绿幕中扣出来啦
inRange(HSV, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), mask);
dst = Replace_Background(frame, mask, bg);
imshow("demo", frame);
//imwrite("frame.jpg", frame);
imshow("mask", mask);
//imwrite("mask.jpg", mask);
imshow("dst", dst);
//imwrite("dst.jpg", dst);
char key = waitKey(10);
if (key == 27)
{
break;
}
}
destroyAllWindows();
capture.release();
system("pause");
return 0;
}
总结
本文使用OpenCV C++进行绿幕视频背景替换,关键步骤有以下几点。
1、将原图转换成HSV色彩空间。
2、使用inRange API将前景从绿幕中抠出来,得到一张二值图。
3、通过像素赋值操作达到背景替换效果。
到此这篇关于利用OpenCV实现绿幕视频背景替换的文章就介绍到这了,更多相关OpenCV绿幕视频背景替换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
热门推荐
docx转为TXT:详细指南及步骤解析
docx转为TXT:详细指南及步骤解析
员工提前离职的方式及补偿金处理指南
只要我们用心去做,就能让豌豆成为餐桌上的一道美味佳肴
如何在云计算中优化数据传输速度
小朋友频繁抠指甲需要找心理医生?指甲保卫战到你破解问题行为
为什么总喜欢逆势做单? 因为是市场认知出了问题!
法院异议书回复格式详解:基本原则与实用技巧
265mm是多少码的鞋子?一文详解各国鞋码换算
济南春日赏花攻略:5大绝美花海等你来
Excel数据填充模板:公式、模板功能、VBA宏编程与第三方工具详解
怎么提高自己的说话能力
澳大利亚482签证大变革!482SID签证申请全攻略
高膳食纤维食物排行榜:从紫苏到高丽菜,这些食物助你远离便秘
如何查看主力增仓的情况?这种查看方式有哪些实际应用价值?
国企客户如何管理工作
如何在国内进行加币的兑换操作?这种兑换的汇率如何确定?
常见的大米有几种?怎样鉴别优质与劣质米
长沙市雅礼中学:百年名校的教育探索与实践
如何绘制DIF线并理解其技术含义?这种技术含义对股票分析有何作用?
“3·15”曝光后,最新进展来了
中国人拥有多少钱,才称得上“有钱人”?银行:97%可能不达标?
宏基因组文献解读|工业化社会人类肠道纤维素降解细菌的隐秘多样性
无人机的七大常见用途
网络众筹的步骤指南:轻松实现您的创意计划
足底筋膜炎康复训练:4种弹力带训练方法详解
中国全职爸爸增多:家庭角色如何转变?
手掌肿胀是什么原因引起的
受伤后冷敷或热敷?抽筋到崩溃如何快速缓解?很多人都做错了
算力服务订单不断,累计金额超80亿元!租赁板块领涨,10股涨停