Direct3D 11 总结 —— 9 通过键盘调整绿幕抠图阈值
介绍
本文主要介绍如何通过键盘设置绿幕抠图的阈值,通过设置不同的阈值,看最终的结果。
最终结果
阈值为 0.9
阈值为 0.2
阈值为 0.5
知识点
获取键盘输入
当键盘按下后,会给窗口的回调函数,传入 msg:WM_KEYDOWN 事件,并通过 wparam 参数,传入是哪个键按下了。
然后窗口回调通过事件的方式通知到 Graphics。
将阈值传到 shader 中
directX 中有个常量值 vertex shader 和 pixel shader 都可以设置,说是常量值,但是该值是可以改变的,说常量应该是绘图的时候对于 shader 是一个常量。通过 PSSetConstantBuffers 函数设置常量资源。
代码
事件相关代码
参考 写的,感觉还有优化的空间,目前只支持传入成员函数,后面学完 c++ 模板相关在回来优化。
#pragma once
#include <windows.h>class Object
{};template<typename returnType, typename argsType>
class Event
{#define EVENT_LIST_MAX_NUM (10)typedef returnType(Object::* pMemFunc)(argsType arg);
public:Event(){m_totalFunc = 0;m_obj = NULL;for (int i = 0; i < EVENT_LIST_MAX_NUM; i++)m_func[i] = NULL;}template<class funcType>void associate(Object* obj, funcType func){m_obj = obj;m_func[m_totalFunc] = static_cast<pMemFunc>(func);m_totalFunc++;}template<class funcType>void disAssociate(Object* obj, funcType func){bool isFind = false;int i = 0;if (obj != m_obj)return;for (i = 0; i < m_totalFunc; i++){if (m_func[i] == func){isFind = true;break;}}if (isFind){for (i; i < m_totalFunc - 1; i++)m_func[i] = m_func[i + 1];m_func[i] = NULL;m_totalFunc--;}}void sendEvent(argsType arg){for (int i = 0; i < m_totalFunc; i++){if (m_func[i] != NULL)((m_obj->*pMemFunc(m_func[i])))(arg);}}private:Object* m_obj;pMemFunc m_func[EVENT_LIST_MAX_NUM];int m_totalFunc;
};
窗口回调
LRESULT Window::HandleMsg(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{switch (msg){case WM_CLOSE:PostQuitMessage(0);return 0;case WM_KEYDOWN:m_winEvent.sendEvent(wparam);break;default:break;}return DefWindowProc(hwnd, msg, wparam, lparam);
}
创建常量值资源
// constant
D3D11_BUFFER_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
bufferDesc.ByteWidth = 16; // 必须是 16 的倍数,不然不能创建资源
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;m_pDevice->CreateBuffer(&bufferDesc, NULL, &m_constBuffer);m_pContext->PSSetConstantBuffers(0, 1, &m_constBuffer);
更新常量值资源
D3D11_MAPPED_SUBRESOURCE ms;m_pContext->Map(m_constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);{std::lock_guard<std::mutex> guard(m_mutex);memcpy_s(ms.pData, sizeof(m_threshold), &m_threshold, sizeof(m_threshold));}m_pContext->Unmap(m_constBuffer, 0);
shader 中使用
Texture2D tex : register(t0);
SamplerState samplerLinear : register(s0);cbuffer ConstantBuffer : register(b0)
{float m_threshold;
}struct VSOut
{float4 pos : SV_Position;float2 tex : TEXCOORD1;
};float4 MyPs(VSOut pIn) : SV_Target
{float4 sampleColor = tex.Sample(samplerLinear, pIn.tex);float dis = distance(float3(sampleColor.xyz), float3(0.0, 1.0, 0.0));return float4(sampleColor.xyz, step(m_threshold, dis));
}
其他
窗口时,不能使用 printf 或者 cout 输出信息到屏幕上,调试起来不太方便。对于窗口可以使用 OutputDebugString 函数将数据打印到 输出窗口。下面的函数是对 OutputDebugString 进行了封装。参考
void __cdecl odprintf(const char* format, ...)
{char buf[4096], * p = buf;va_list args;va_start(args, format);p += _vsnprintf(p, sizeof buf - 1, format, args);va_end(args);if (p > buf && isspace(p[-1])){*--p = '\0';*p++ = '\r';*p++ = '\n';*p = '\0';}OutputDebugString(buf);
}
举例
odprintf("m_threshold %f ", m_threshold);
Direct3D 11 总结 —— 9 通过键盘调整绿幕抠图阈值相关推荐
- Direct3D 11 总结 —— 8 实现简单的绿幕抠图效果
介绍 绿幕抠图指将图片中的绿色扣去,并将该处的 alpha 分量设为 0,并将另外一张图片作为背景,以实现背景替换的功能,常用于电影和电视的制作场景. 最终效果 原始图片 绿幕抠图后效果 代码 这一块 ...
- 编程去除背景绿幕抠图,基于.NET+OpenCVSharp
摘要:本文介绍了一种使用OpenCVSharp对摄像头中的绿幕视频进行实时"抠人像.替换背景"的方式,对于项目中的算法进行了分析.本文中给出了简化OpenCVSharp中Mat.M ...
- 抖音直播画中画、绿幕抠图直播,如此简单
抖音直播目前较火,但只单存的播放视频,很容易限流,无法加热... 目前较火的直播方式,无非就是画中画+绿幕直播了.可能会环节以上问题. 什么是画中画,就是两个媒体源叠加在一起 如下图: 如何把摄像头只 ...
- 直播绿幕抠图的例子(绿幕抠图直播实例参考)
阿酷TONY / 2022-11-21 / 长沙 什么是绿幕抠图: 设定绿幕或绿布,做直播软件抠图,这时绿幕绿布就可以被实时的抠掉,绿色就变成透明了,只剩下绿幕外的人物,此时添加上直播的背景画质,就 ...
- 绿幕抠图在手机上使用认识.
简单介绍 疑问1: 绿幕技术在手机APP上合适吗? 毕竟带着绿布在户外不现实. 是的, 太不现实了, 我们之前不做也是这样想的, 用户量不大, 使用场景不大. 没有谁愿意在户外先支好绿布,然后再拍视频 ...
- 视频编辑SDK,AE模版SDK,绿幕抠图SDK,AI人像分割SDK,VLOG模版SDK
蓝松短视频SDK(视频编辑.AE模版.绿幕抠图.人像分割.人体抠图.VLOG模版): 高集成度:SDK中的大部分功能,都是一行代码设置 高完整度:提供常见视频编辑UI界面,可直接使用 高独立性:蓝松S ...
- Windows OpenGL 图像绿幕抠图
目录 一.OpenGL 图像绿幕抠图 1.原始图片 2.效果演示 二.OpenGL 图像绿幕抠图源码下载 三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 & ...
- Unity3D视频绿幕抠图的实现及优化
Unity3D视频绿幕抠图的实现及优化 展开 本文是通过Shader处理绿幕的方式来实现Unity中视频(VideoPlayer)的绿幕抠图.因为项目原因,不追究细节(能用就好能用就好)orz可是我连 ...
- 通过OpenCV对视频进行绿幕抠图
通过OpenCV对视频进行绿幕抠图 效果 代码 1.打开视频素材 2.保存视频路径及格式设置 3.读取一帧视频 4.寻找绿幕背景 5.融合 6.代码执行效果 效果 今天跟大家分享的是最近比较受大家喜欢 ...
最新文章
- freeBSD挂载光驱
- android 按下缩小效果松开恢复_iPhone XS/XS Max如何强制重启?如何进入恢复模式或DFU模式?...
- Follow My Logic 1048 PKU
- 科技感的动态设计方法-1
- OGRE 1.7.2 [Cthugha] 编译配置全过程方法
- iphone桌面横屏设置在哪里_我和我各司其职的桌面们
- 在Chrome78浏览器上如何实现自动播放音视频
- flash制作文字笔顺_Flash中使用逐帧动画实现按笔顺书写汉字的效果
- mapabc 地图失效不能进行任何操作
- 2019年江苏卷数学高考真题Word版含答案解析
- 微软bi报表服务器,升级 Power BI 报表服务器
- 【学习资源】光学、物理类、电子学实验合集
- 软件测试肖sir__006xmind思维导图实战__微信发红包
- SpringMVC中使用hibernate-validator的坑
- python异常处理try判断整数_Python之异常处理
- 2022电动两轮市场格局分化,九号异军突起
- 关于Connection Closed Gracefully问题
- Windows10退出微软账户使用本地账户
- 乐忧商城项目总结-4
- MCTF--MISC