利用OpenCV实现绿幕视频背景替换

目录
  • 前言
  • 一、图像预处理
  • 二、HSV色彩空间转换
    • 1. cvtColor色彩空间转换
    • 2. 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绿幕视频背景替换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Opencv实现抠图背景图替换功能

    本文实例为大家分享了Opencv实现抠图替换背景图的具体代码,供大家参考,具体内容如下 下面简单图片演示一下: 提取mask: ===> 替换背景:  + = python的opencv代码如下: # coding=utf-8 import cv2 import numpy as np img=cv2.imread('lp.jpg') img_back=cv2.imread('back.jpg') #日常缩放 rows,cols,channels = img_back.shape img_bac

  • OpenCV实现背景分离(证件照背景替换)

    目录 实现原理 功能函数代码 C++测试代码 完整改进代码 本文主要介绍了OpenCV实现背景分离(证件照背景替换),具有一定的参考价值,感兴趣的可以了解一下 实现原理 图像背景分离是常见的图像处理方法之一,属于图像分割范畴.如何较优地提取背景区域,难点在于两个: 背景和前景的分割.针对该难点,通过人机交互等方法获取背景色作为参考值,结合差值均方根设定合理阈值,实现前景的提取,PS上称为蒙版:提取过程中,可能会遇到前景像素丢失的情况,对此可通过开闭运算或者提取外部轮廓线的方式,将前景内部填充完毕

  • Opencv实现绿幕视频背景替换功能

    基于hsv颜色空间的实时背景替换: #include<opencv2\opencv.hpp> using namespace cv; Mat replace_and_blend(Mat &frame, Mat&mask); Mat background,frame, hsv, mask,result; int main(int arc, char** argv) { background = imread("2.jpg"); namedWindow(&quo

  • OpenCV实战之AI照片背景替换

    目录 导语 正文 1)附主程序 2)展示其他 总结 导语 不少人在生活中都有抠人像图换背景的需求.那怎么抠图呢? 相信不少人第一时间就想到了 PS 抠图大法,为了学会 PS 抠图很多人还花费不少精力,而且学会后大家想必都有共同感触:PS 抠图在制作抠图选区这个步骤太耗费时间!!就跟我减肥似的! 今天木木子就手把手教大家编写一款抠图人像技术—— 这款小程序实现一键智能抠取人像图的功能,非常强大! 比 PS 慢慢抠图效率可提升了太多了,而且还能让不会 PS 的群体也能轻松学会抠人像图. 吹了这么多,

  • 利用OpenCV实现绿幕视频背景替换

    目录 前言 一.图像预处理 二.HSV色彩空间转换 1. cvtColor色彩空间转换 2. inRange抠图 三.背景替换 四.源码 总结 前言 本文将使用OpenCV C++ 进行绿幕视频背景替换. 一.图像预处理 背景 绿幕视频 首先,我们需要使用resize API将背景图尺寸修改与视频尺寸大小.这样才能进行后续的像素赋值操作. Mat bg = imread("background.jpg"); //背景图 VideoCapture capture; //读取待处理的绿幕视

  • python利用opencv保存、播放视频

    代码已上传至:https://gitee.com/tqbx/python-opencv/tree/master/Getting_started_videos 目标 学习读取视频,播放视频,保存视频. 学习从相机中捕捉帧并展示. 学习cv2.VideoCapture(),cv2.VideoWriter()的使用 从相机中捕捉视频 通过自带摄像头捕捉视频,并将其转化为灰度视频显示出来. 基本步骤如下: 1.首先创建一个VideoCapture对象,它的参数包含两种: 设备索引,指定摄像机的编号. 视

  • OpenCV去除绿幕抠图源码

    绿布原图 抠图后的图片 源码 #include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include <cstdio> #include <cstring> using namespace cv; using namespace std; int main() { //1.设置需要去除的颜色 //2.颜色比对 //3.展示效果 //只有png有透明度空间,jpg是没

  • python人物视频背景替换实现虚拟空间穿梭

    目录 引言 准备工作 纯RGB背景替换 自定义图像背景板替换 引言 近期网上这位卖蜂蜜的小伙鬼畜挺火的,大家质疑背景造假,这里我就带着大家实现“背景造假”(PS:原视频小伙是在真实场景拍摄的) 准备工作 在实现该功能之前,我们需要准备好python==3.7 然后执行: pip install mediapipe 方案一: PC端可以选择外界摄像头或者连接网络摄像头,最好挑选一个纯属的背景板作为视频画面背景(这样有利于任务分割): 方案二: 网上下载有人物活动的视频,然后用下载的视频替代连接摄像

  • Java利用opencv实现用字符展示视频或图片的方法

    背景:前段时间看到有人将图片转成符号,感觉挺有意思的,就结合了一下opencv. 代码如下: package org.fxd.utils; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; import org.opencv.videoio.VideoCapture; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import

  • python3基于OpenCV实现证件照背景替换

    本文实例为大家分享了python3实现证件照背景替换的具体代码,供大家参考,具体内容如下 import cv2 import numpy as np img=cv2.imread('zjz.jpg') #缩放 rows,cols,channels = img.shape img=cv2.resize(img,None,fx=0.5,fy=0.5) rows,cols,channels = img.shape cv2.imshow('img',img) #转换hsv hsv=cv2.cvtColo

  • opencv实现图片与视频中人脸检测功能

    本文实例为大家分享了opencv实现人脸检测功能的具体代码,供大家参考,具体内容如下 第一章:反思与总结 上一篇博客我相信自己将人脸检测中的AdaBoost算法解释的非常清晰了,以及如何训练人脸检测的强分类器:人脸检测中AdaBoost算法详解.事后,自我感觉对这个人脸检测还是不够具体,所以自己抽了一下午的时间用opencv实现图片与视频中的人脸检测,下面是我用vs2013加opencv4.9来实现的.做一下声明,我的代码是参考OpenCV实现人脸检测的一个博客写的,非常感谢这位博主,我学到了很

随机推荐