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("input", CV_WINDOW_AUTOSIZE);
 imshow("src", background);

 VideoCapture capture;
 capture.open("1.mp4");

    CvSize size = cvSize(capture.get(CV_CAP_PROP_FRAME_WIDTH), capture.get(CV_CAP_PROP_FRAME_HEIGHT));
 VideoWriter writer("qq.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'),12.0, size, true);

 while (capture.read(frame)) {
 imshow("input", frame);
 cvtColor(frame, hsv, CV_BGR2HSV);
 inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);//颜色过滤,得到mask绿色部分为1,其它部分都为0
 imshow("mask", mask);
 Mat kernel = getStructuringElement(MORPH_RECT,Size(3,3));
 morphologyEx(mask, mask, MORPH_DILATE, kernel);
 GaussianBlur(mask, mask, Size(3, 3), 0, 0);//0,0会根据Size自动算的

 result = replace_and_blend(frame, mask);
        writer.write(result);
 char c = waitKey(1);
 if (c == 27) {
  break;
 }
 imshow("input", frame);
 imshow("result", result);
 }
 waitKey(0);
 return 0;
}

//通过颜色过滤得到的掩码为单通道图像
Mat replace_and_blend(Mat &frame, Mat &mask)
{
 int rows = frame.rows;
 int cols = frame.cols;
 result = Mat::zeros(frame.size(), frame.type());
 for (int i = 0; i < rows; i++)
 {
 uchar *pf = frame.ptr(i);//人物前景
 uchar *pm = mask.ptr(i);//掩码
 uchar *pb = background.ptr(i);//背景
 uchar *pr = result.ptr(i);//结果

 for (int j = 0; j < cols; j++)
 {
  pm++;
  if (*pm == 255)//背景
  {
  pr[3 * j] = pb[3 * j];
  pr[3 * j + 1] = pb[3 * j + 1];
  pr[3 * j + 2] = pb[3 * j + 2];
  }
  else if (*pm == 0)//前景
  {
  pr[3 * j] = pf[3 * j];
  pr[3 * j + 1] = pf[3 * j + 1];
  pr[3 * j + 2] = pf[3 * j + 2];
  }
  else //融合部分
  {
  int m = *pm;
  double w = m / 255.0;
  pr[3 * j] = w *pb[3 * j] + (1-w) * pf[3 * j];
  pr[3 * j + 1] = w * pb[3 * j + 1] + (1-w) * pf[3 * j + 1];
  pr[3 * j + 2] = w * pb[3 * j + 2] + (1-w) * pf[3 * j + 2];
                //或者取前景和背景的平均值
  /*pr[3 * j] = (pb[3 * j] + pf[3 * j])/2;
  pr[3 * j + 1] = (pb[3 * j + 1] + pf[3 * j + 1])/2;
  pr[3 * j + 2] = (pb[3 * j + 2] + pf[3 * j + 2])/2;*/
  }
 }
 }
 return result;
}

/*
Mat replace_and_blend(Mat &frame, Mat&mask) {
 result = Mat::zeros(frame.size(), frame.type());
 int h = frame.rows;
 int w = frame.cols;
 int dims = frame.channels();
 int m ;
 double wt ;
 int b , g, r;
 int b1, g1, r1;
 int b2 , g2, r2 ;
 //指针操作速度最快,直接访问地址
 for (int row = 0; row < h; row++) {
 uchar* current = frame.ptr<uchar>(row);
 uchar* bgrow = background.ptr<uchar>(row);
 uchar* maskrow = mask.ptr<uchar>(row);
 uchar* targetrow = result.ptr<uchar>(row);
 for (int col = 0; col < w; col++) {
  m = *maskrow++;
  if (m == 255) {//背景
  *targetrow++ = *bgrow++;
  *targetrow++ = *bgrow++;
  *targetrow++ = *bgrow++;
  current += 3;
  }
  else if (m == 0) {//前景
  *targetrow++ = *current++;
  *targetrow++ = *current++;
  *targetrow++ = *current++;
  bgrow += 3;
  }
  else {
  b1 = *bgrow++;
  g1 = *bgrow++;
  r1 = *bgrow++;
  b2 = *current++;
  g2 = *current++;
  r2 = *current++;
  wt = m/ 255.0;
  b = wt*b1 + (1 - wt)*b2;
  g = wt*g1 + (1 - wt)*g2;
  r = wt*r1 + (1 - wt)*r2;
  *targetrow++ = b;
  *targetrow++ = g;
  *targetrow++ = r;
  }
 }
 }
 return result;
}
*/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 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实现绿幕视频背景替换功能

    基于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实现绿幕视频背景替换

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

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

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

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

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

  • python+opencv打开摄像头,保存视频、拍照功能的实现方法

    以下代码是保存视频 # coding:utf-8 import cv2 import sys reload(sys) sys.setdefaultencoding('utf8') cap = cv2.VideoCapture(0) cap.set(3,640) cap.set(4,480) cap.set(1, 10.0) #此处fourcc的在MAC上有效,如果视频保存为空,那么可以改一下这个参数试试, 也可以是-1 fourcc = cv2.cv.CV_FOURCC('m', 'p', '4

  • 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是没

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

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

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

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

  • Python+OpenCV实现图像识别替换功能详解

    OpenCV-Python是一个Python库,旨在解决计算机视觉问题. OpenCV是一个开源的计算机视觉库,1999年由英特尔的Gary Bradski启动.Bradski在访学过程中注意到,在很多优秀大学的实验室中,都有非常完备的内部公开的计算机视觉接口.这些接口从一届学生传到另一届学生,对于刚入门的新人来说,使用这些接口比重复造轮子方便多了.这些接口可以让他们在之前的基础上更有效地开展工作.OpenCV正是基于为计算机视觉提供通用接口这一目标而被策划的. 安装opencv pip3 in

随机推荐