OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理计算机视觉以及模式识别程序。该程序库也可以使用英特尔公司的IPP进行加速处理。

  OpenCVSharp是一个.Net平台使用的OpenCV封装库。现在网上关于openCV的教程基本都是c++和python,如果是C#方向,可以跟着这两个语言的步骤自己写demo。

  开始我们今天的课程。

一、分析

  这个功能只要是给绿幕人物加上背景,比如:在直播的时候,因为私密或者其他原因,不想透露出背景

  设想只需要购买一块绿幕,然后上网挑选一张自己喜欢的背景照片,就可以拥有一个好看的背景。

  如何替换视频背景呢?我们一步一步入门!!

  1)绿幕相片扣出人物

  2)人物放进背景图片

  3)操作视频帧图片,实现替换绿幕。

  需要安装的nuget包,注意查看依赖项选版本

OpenCvSharp4
OpenCvSharp4.runtime.win

二、绿幕相片扣出人物

  只展示核心代码

  1)识别绿幕函数(一般操作图片是使用指针的,为了更好理解,我们这里先At执行,后面会讲使用指针改进)

        //删除绿幕
private unsafe void RemoveImageScreen(Mat src, Func<Vec3b, bool> func)
{
for (int i = 0; i < src.Rows; i++)
{
for (int j = 0; j < src.Cols; j++)
{
if (func(src.At<Vec3b>(i, j)))
{
src.At<Vec3b>(i, j) = new Vec3b(0, 0, 0);
}
}
}
}

  2)选择图片并清除绿幕

            using (ResourcesTracker t = new ResourcesTracker())
{
Bitmap bitmap = new Bitmap(pictBox_origin.Image);
var mat = BitmapConverter.ToMat(bitmap);
RemoveImageScreen(mat,
p =>
{
int max = Math.Max(p.Item0, Math.Max(p.Item1, p.Item2));
if (max == p.Item1 && p.Item1 > 30) //BGR,当G最大时且大于30时,可以根据实际调节这个阈值
return true;
return false;
});
pictBox_result.Image = BitmapConverter.ToBitmap(mat_bg);
        }

  效果展示:(我是跟着杨神的思路写的这个程序,素材就直接用杨神了,这篇是入门级别,可以看完我这篇再去观摩杨神的)

  杨中科(就是下图这个帅哥):https://www.bilibili.com/read/cv8850462?spm_id_from=333.999.0.0

  

三、人物放进背景图片

  合并图片函数

        private unsafe void MergeImageAt(Mat bg, Mat src, Func<Vec3b, bool> func)
{
Cv2.Resize(bg, bg, src.Size());//以背景人物大小为准
for (int i = 0; i < bg.Rows; i++)
{
for (int j = 0; j < bg.Cols; j++)
{
if (func(src.At<Vec3b>(i, j)))
{
bg.At<Vec3b>(i, j) = src.At<Vec3b>(i, j);
}
}
}
}

  续上上一步,加上合并图片的步骤

            using (ResourcesTracker t = new ResourcesTracker())
{
Bitmap bitmap = new Bitmap(pictBox_origin.Image);
var mat = BitmapConverter.ToMat(bitmap);
var mat_bg = t.T(Cv2.ImRead("images/bg2.jpg"));
RemoveImageScreen(mat,
p =>
{
int max = Math.Max(p.Item0, Math.Max(p.Item1, p.Item2));
if (max == p.Item1 && p.Item1 > 30)
return true;
return false;
});
MergeImageAt( mat_bg, mat,
p =>
{
if (p == new Vec3b(0, 0, 0))
{
return false;
}
return true;
}
);
pictBox_result.Image = BitmapConverter.ToBitmap(mat_bg);
}

  效果如图:

  

四、操作视频帧图片,实现替换绿幕

  和图片的区别,就是需要先逐帧获取 视频/摄像机 的图片,然后按上述操作进行

  直接附上完整Demo(已经将两个函数改为指针操作,大家可以先试试原来的At操作,可以明显看到视频是慢速播放)

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MyOpenCV
{
public static class RemoveGreenScreen
{
public static unsafe void Start()
{
//VideoCapture videoCapture = new VideoCapture(1, VideoCaptureAPIs.DSHOW);//摄像头
VideoCapture videoCapture = new VideoCapture(@"images/绿幕视频.mp4");
using (videoCapture)
using (Mat frameMat = new Mat())
using (Mat mat_bg = Cv2.ImRead("images/bg.png"))
{
if (videoCapture.CaptureType == CaptureType.Camera)//如果是摄像头
{
videoCapture.FrameWidth = 800;
videoCapture.FrameHeight = 600;
videoCapture.FourCC = "MJPG";
}
while (true)
{
if (!videoCapture.Read(frameMat))
{
//如果是视频文件,从头部开始播放
if (videoCapture.CaptureType == CaptureType.File)
{
videoCapture.PosFrames = 0;
}
continue;
}
RemoveImageScreen(frameMat,
p =>
{
int max = Math.Max(p.Item0, Math.Max(p.Item1, p.Item2));
if (max == p.Item1 && p.Item1 > 30)
return true;
return false;
});
var bg_clone = mat_bg.Clone();
MergeImage(bg_clone, frameMat,
p =>
{
if (p == new Vec3b(0, 0, 0))
{
return false;
}
return true;
});
Cv2.ImShow("press any key to quit", bg_clone);
if (Cv2.WaitKey(1) > 0)
{
break;
}
}
}
Cv2.DestroyAllWindows();
} private static unsafe void RemoveImageScreen(Mat src, Func<Vec3b, bool> func)
{
Vec3b* start = (Vec3b*)src.DataStart;
Vec3b* end = (Vec3b*)src.DataEnd;
for (Vec3b* p = start; p <= end; p++)
{
if (func(*p))
{
*p = new Vec3b(0, 0, 0);
}
}
}
private static unsafe void MergeImage(Mat bg, Mat src, Func<Vec3b, bool> func)
{
Cv2.Resize(bg, bg, src.Size());
Vec3b* bg_pointer = (Vec3b*)bg.DataStart;
Vec3b* start = (Vec3b*)src.DataStart;
Vec3b* end = (Vec3b*)src.DataEnd;
for (Vec3b* p = start; p <= end; p++, bg_pointer++)
{
*bg_pointer = func(*p) ? *p : *bg_pointer;
}
}
}
}

  素材:

      

  效果展示:(这是视频的一张截图)

  

  完成!!!

  图片去绿幕的效果还是很粗糙的,后续会持续更新改进方法,希望大家点赞+关注

  并欢迎大家留言...

  

C# OpenCVSharp图像入门_给绿幕图片视频加背景的更多相关文章

  1. 在Android用vulkan完成蓝绿幕扣像

    效果图(1080P处理) 因为摄像头开启自动曝光,画面变动时,亮度变化导致扣像在转动时如上. 源码地址vulkan_extratest 这个demo主要测试二点,一是测试ndk camera集成效果, ...

  2. AI目标分割能力,无需绿幕即可实现快速视频抠图

    绿幕抠图是影视制作过程中常见的技术手段,常用于视频中抠除并替换背景,通过后期加工实现视频剪辑制作的更多可能性.然而,绿幕抠图技术制作成本费时费力,无法应用于日常生活. 华为视频编辑服务近期上线目标分割 ...

  3. 09_android入门_采用android-async-http开源项目的GET方式或POST方式实现登陆案例

    根据08_android入门_android-async-http开源项目介绍及使用方法的介绍,我们通过最常见的登陆案例进行介绍android-async-http开源项目中有关类的使用.希望对你学习 ...

  4. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

  5. 09_android入门_採用android-async-http开源项目的GET方式或POST方式实现登陆案例

    依据08_android入门_android-async-http开源项目介绍及用法的介绍,我们通过最常见的登陆案例进行介绍android-async-http开源项目中有关类的使用.希望对你学习an ...

  6. 『TensorFlow』第九弹_图像预处理_不爱红妆爱武装

    部分代码单独测试: 这里实践了图像大小调整的代码,值得注意的是格式问题: 输入输出图像时一定要使用uint8编码, 但是数据处理过程中TF会自动把编码方式调整为float32,所以输入时没问题,输出时 ...

  7. 07_android入门_採用HttpClient的POST方式、GET方式分别实现登陆案例

    1.简单介绍 HttpClient 是 Apache Jakarta Common 下的子项目,能够用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,而且它支持 HTTP 协议 ...

  8. OpenCvSharp 图像旋转

    /// <summary> /// 图像旋转 /// </summary> private Mat MatRotate(Mat src, float angle) { Mat ...

  9. 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2  任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...

  10. Camtasia绿幕素材的视频合成

    随着科技和互联网的快速发展,让越来越多的人喜欢上了视频的各项制作,那么怎么让两个视频进行合成并一起播放呢?操作很简单,下面来讲解具体的操作步骤.小编选用的是Camtasia2019版本的视频编辑软件进 ...

随机推荐

  1. 文心一言 VS chatgpt (5)-- 算法导论2.2 3~4题

    三.再次考虑线性查找问题(参见练习 2.1-3).假定要查找的元素等可能地为数组中的任意元素,平均需要检查输入序列的多少元素?最坏情况又如何呢?用0记号给出线性查找的平均情况和最坏情况运行时间.证明你 ...

  2. 2022-09-13:给你两个整数 m 和 n ,分别表示一块矩形木块的高和宽。 同时给你一个二维整数数组 prices ,其中 prices[i] = [hi, wi, pricei] 表示你可以

    2022-09-13:给你两个整数 m 和 n ,分别表示一块矩形木块的高和宽. 同时给你一个二维整数数组 prices ,其中 prices[i] = [hi, wi, pricei] 表示你可以以 ...

  3. 2021-05-24:盛最多水的容器。给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai)

    2021-05-24:盛最多水的容器.给你 n 个非负整数 a1,a2,-,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 ...

  4. 2021-07-27:给定一个数组arr,长度为N,arr中的值只有1,2,3三种。arr[i] == 1,代表汉诺塔问题中,从上往下第i个圆盘目前在左;arr[i] == 2,代表汉诺塔问题中,从上

    2021-07-27:给定一个数组arr,长度为N,arr中的值只有1,2,3三种.arr[i] == 1,代表汉诺塔问题中,从上往下第i个圆盘目前在左:arr[i] == 2,代表汉诺塔问题中,从上 ...

  5. (偶尔更新)【Linux】Linux常见不常用命令收集

    本文时间 2023-05-20 作者:sugerqube漆瓷 cd,vi,clear这些属于常见常用命令本文不再赘述. 安装命令 yum install vim举例安装vim rpm -ivh a.r ...

  6. openlayers Text字体大小设置

    今做一个app版的ol地图,发现区域太小显示拥挤,于是想把字体改小,看起来匀称点,于是盯紧了font属性使劲改 老是不听咋整呢?网上找大佬 于是找到了得到了各路大神鼎力相助 如: 赶紧跑去试试,原来这 ...

  7. 【技术积累】Linux中的基础知识【一】

    Linux系统是什么 Linux系统是一种开源操作系统,它极具可定制性和灵活性,因此受到了许多人的欢迎.Linux系统以简单,强大和兼容性而著称.它可用于各种设备,从个人计算机到超级计算机,从移动设备 ...

  8. IDEA的安装准备

    IDEA的安装 第一步 第二步 第三部 第四步

  9. CoFiltering:BestPracticesandTechniquesinTextGeneration

    目录 Co-Filtering: Best Practices and Techniques in Text Generation Introduction: Text generation has ...

  10. Pinot2的无人机任务和数据处理实践

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 4. 应用示例与代码实现讲解 4.1 应用场景介绍 4.2 应用实例分析 ...