首先说明,参考的博客

https://blog.csdn.net/linqianbi/article/details/78975998
https://blog.csdn.net/linqianbi/article/details/79151960

一.算法的选择
绿幕背景视频抠图对实时性要求比较高,如果使用kmeans或者GMM的话那么就太耗时了,达不到要求,因此将RGB空间转换到HSV色彩空间进行处理。
关于HSV参考上面的博客

二.本实例的程序设计思路

三.源程序
(和网上的一样,我自己加了些注释,方便自己理解)

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;#define WINDOW_NAME1 "title"
#define WINDOW_NAME2 "resultWin"Mat replace_and_blend(Mat &frame, Mat &mask);//绿幕抠图的实现函数Mat background_01;
Mat background_02;int main(int argc, char** argv)
{//定义你想替换的背景,背景1和背景2都可选择background_01 = imread("E:\\图像处理图片\\34.jpg");background_02 = imread("E:\\图像处理图片\\35.jpg");VideoCapture capture; //读取视频capture.open("E:\\图像处理图片\\01.mp4");if (!capture.isOpened()) //检验是否读取到视频{printf("could not find the video file...\n");return -1;}namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);Mat frame, hsv, mask;  //frame表示每一帧的图像while (capture.read(frame)) //检测读取到的每一帧图像{cvtColor(frame, hsv, COLOR_BGR2HSV); //将帧图像转为HSVinRange(hsv, Scalar(35, 43, 46), Scalar(155, 255, 255), mask);//inRange()函数可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作。//主要是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0),该功能类似于之间所讲的双阈值化操作。//函数原型:void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);//   参数1:输入要处理的图像,可以为单通道或多通道。//   参数2:包含下边界的数组或标量。//   参数3:包含上边界数组或标量。//   参数4:输出图像,与输入图像src 尺寸相同且为CV_8U 类型。//   请注意:该函数输出的dst是一幅二值化之后的图像。// 形态学操作Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); morphologyEx(mask, mask, MORPH_CLOSE, k);  //闭运算erode(mask, mask, k);  //腐蚀GaussianBlur(mask, mask, Size(3, 3), 0, 0);  //高斯模糊Mat result = replace_and_blend(frame, mask);char c = waitKey(30); //停顿30毫米给计算机做处理if (c == 27)  //按下“ESC”键即退出程序{break;}imshow(WINDOW_NAME2 result);imshow(WINDOW_NAME1, frame);}waitKey(0);return 0;
}//对视频的每一帧的图像进行处理
Mat replace_and_blend(Mat &frame, Mat &mask)
{Mat result = Mat::zeros(frame.size(), frame.type());int h = frame.rows;int w = frame.cols;int dims = frame.channels();// 背景的融合替换int m = 0;  //图像的像素值double wt = 0;  //初始化权重值,即融合的比例//输出像素int r = 0, g = 0, b = 0;int r1 = 0, g1 = 0, b1 = 0;int r2 = 0, g2 = 0, b2 = 0;//这里的遍历像素选择指针,因为指针的效果速度快,效率高for (int row = 0; row < h; row++) {//访问图像像素有三种可行的方法://指针访问访问的速度最快,Mat类可以通过ptr函数得到图像任意一行的首地址,//同时,Mat类的一些属性也可以用到公有属性 rows和cols 表示行和列//通道数可以通过channels()函数获得;uchar* current = frame.ptr<uchar>(row);   //current为帧图像的行数,即高度uchar* bgrow = background_02.ptr<uchar>(row);  //bgrow为要替换的背景图像的行数,即高度uchar* maskrow = mask.ptr<uchar>(row);   //maskrow为二值化后的图像mask的行数,即高度uchar* targetrow = result.ptr<uchar>(row);  //targetrow为输出结果图像的行数,即高度for (int col = 0; col < w; col++) {m = *maskrow++;  //读取mask的像素值,每运行一次行数加一if (m == 255)  {// 背景*targetrow++ = *bgrow++;*targetrow++ = *bgrow++;*targetrow++ = *bgrow++;current += 3;  //将frame的图像的像素的通道也移动单个保持一致}else if (m == 0) {// 前景*targetrow++ = *current++;*targetrow++ = *current++;*targetrow++ = *current++;bgrow += 3;   //将background_02的图像的像素的通道也移动单个保持一致}else{//要替换的背景图background_02每个像素的三个通道b1 = *bgrow++;g1 = *bgrow++;r1 = *bgrow++;//每一帧每一个像素的三个通道b2 = *current++;g2 = *current++;r2 = *current++;// 权重wt = m / 255.0;// 混合b = b1 * wt + b2 * (1.0 - wt);g = g1 * wt + g2 * (1.0 - wt);r = r1 * wt + r2 * (1.0 - wt);*targetrow++ = b;*targetrow++ = g;*targetrow++ = r;}}}return result;
}

程序运行后的结果却不尽人意,原视频和背景换掉的视频都播放的很慢,我调了等待的时间也没用,不知道是电脑的问题,还是程序的问题,总之没解决,希望看到的大佬能给我指点下。。。

绿幕背景视频抠图替换相关推荐

  1. opencv 绿幕背景视频抠图

    文章目录 一.说明 二.程序实例 三.结果展示 一.说明 在视频中采用KMeans或者GMM的算法效率太低了,用来做视频抠图效果不好,这里使用了一个更加便捷的方式.就是HSV格式. 由于在视频中只有的 ...

  2. Opencv图像分割小案例 --- 绿幕背景视频抠图

    基于HSV色彩空间的实时背景替换: 注:新更换的背景图必须和原视频的背景图尺寸一样.  相关API: 1. inRange()函数 opencv中的inRange()函数可实现二值化功能(这点类似th ...

  3. 基于opencv的绿幕背景视频抠图算法流程

  4. 【学习OpenCV4】教你替换绿幕背景

    绿幕图像的背景替换 一.色彩空间转换 二.提取绿幕区域 三.替换背景 绿幕图像的背景替换需要经历①色彩空间转换.②提取绿幕区域.③反转绿幕区域.④复制图像,其中遇到的各种函数和代码也都在本文有详细介绍 ...

  5. 【我的OpenGL学习进阶之旅】 OpenGL ES 实现 绿幕抠图 以及 替换绿幕背景的功能

    一.绿幕抠图 "近来,我们总是不经意间看到一些自媒体公众号,影评人在谈到某部上映的影视剧制作如何稀烂,演员如何不敬业时总会用到"抠图"这个词.似乎"抠图&quo ...

  6. 绿幕背景抠图,去除掉物体周围一圈的绿边 OpenCVForUnity

    近段时间采用OpenCVForUnity在Unity中做图像分割 利用HSV方法进行 绿幕抠图 有一个问题,抠出的图像存在一层绿色的边(个人认为是没有分割清楚造成的). 解决办法:用OpenCV中的f ...

  7. 绿幕特效视频的透明通道输出与拼合为图像矩阵

    既然之前的特效实现提升到了质的飞跃,那么就考虑敌机(本机)爆炸时的效果问题了. 首先download下某个绿幕爆炸特效视频: 本次使用aftereffects进行抠像: 首先视频导入到ae中,在效果- ...

  8. 一键绿幕抠像替换背景,绿幕抠图是如何操作的?

    一般要抠像的视频,前期都使用绿幕或蓝幕拍摄.拍摄结束进入后期软件进行抠像处理.那再我们日常生活中,没有用绿幕蓝幕拍摄,我们又改如何进行视频抠像替换背景的操作呢? 在电影.电视剧拍摄中应特效需要常用到绿 ...

  9. AI视频抠图换背景,无需「绿幕」,也可达到影视级效果

    相信很多小伙伴在平时拍摄剪辑视频的时候,都会遇到视频背景杂乱的情况吧,这个时候都会想到像抠图一样,将视频中的人像抠出来换一个背景!那么具体应该怎么操作呢? 其实这个问题很简单,利用AI智能视频抠图,无 ...

最新文章

  1. 在js中获取input中的value
  2. 全球及中国商业座机电话行业投资潜力及竞争格局展望报告2021-2027年版
  3. Transformation XML(TCODE-STRANS)
  4. js中的if与Java中的if_JS中的if和else的用法以及基础语法
  5. Android APK的加固方法
  6. NiFi 脚本执行器使用指南 (part 3)
  7. as安装过程中gradle_在安装钢结构平台过程中需要注意哪些事项?
  8. Metaspace泄漏排查
  9. helpdesk2 foxmail和outlook互导问题
  10. 米家扫地机器人是石头代工_扫地机器人“两强”突进,选科沃斯还是石头科技?...
  11. .net 有哪些主流的设计模式_「设计模式自习室」门面模式 Facade Pattern
  12. Linux下rpm安装MySQL及配置
  13. nodejs、express下载和配置
  14. 生信技能树 WES分析教程学习(1)conda安装软件,配置环境
  15. 《重装系统》Windows纯净装机+常用工具(最简单易懂教程)--菜鸟小回
  16. 搭建个人网盘-owncloud
  17. 使用ASProfile分析可变剪切事件
  18. Testin云测平台操作步骤
  19. 时间类型转换为字符串
  20. java的开发工具是什么_java都用什么开发工具

热门文章

  1. spring 事物(一)—— 事物详解
  2. 木叶村第一次全村人民代表大会
  3. leecode-C语言实现-1619. 删除某些元素后的数组均值
  4. Linux云计算好学吗?Linux云计算运维学习资料 Vim编辑器
  5. ubuntu 22端口不通
  6. 微信小程序引入组件以及catchtouchmove实现拖动效果
  7. mac系统+frida 简单测试真机or genymotion模拟器
  8. Matrix67的情书 题解 恺撒移位密码
  9. python中fabs函数_Python fabs() 函数 - Python 教程 - 自强学堂
  10. 民宿平台airbnb是如何动态定价的