介绍

本文主要介绍如何通过键盘设置绿幕抠图的阈值,通过设置不同的阈值,看最终的结果。

最终结果

阈值为 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 通过键盘调整绿幕抠图阈值相关推荐

  1. Direct3D 11 总结 —— 8 实现简单的绿幕抠图效果

    介绍 绿幕抠图指将图片中的绿色扣去,并将该处的 alpha 分量设为 0,并将另外一张图片作为背景,以实现背景替换的功能,常用于电影和电视的制作场景. 最终效果 原始图片 绿幕抠图后效果 代码 这一块 ...

  2. 编程去除背景绿幕抠图,基于.NET+OpenCVSharp

    摘要:本文介绍了一种使用OpenCVSharp对摄像头中的绿幕视频进行实时"抠人像.替换背景"的方式,对于项目中的算法进行了分析.本文中给出了简化OpenCVSharp中Mat.M ...

  3. 抖音直播画中画、绿幕抠图直播,如此简单

    抖音直播目前较火,但只单存的播放视频,很容易限流,无法加热... 目前较火的直播方式,无非就是画中画+绿幕直播了.可能会环节以上问题. 什么是画中画,就是两个媒体源叠加在一起 如下图: 如何把摄像头只 ...

  4. 直播绿幕抠图的例子(绿幕抠图直播实例参考)

    阿酷TONY  / 2022-11-21 / 长沙 什么是绿幕抠图: 设定绿幕或绿布,做直播软件抠图,这时绿幕绿布就可以被实时的抠掉,绿色就变成透明了,只剩下绿幕外的人物,此时添加上直播的背景画质,就 ...

  5. 绿幕抠图在手机上使用认识.

    简单介绍 疑问1: 绿幕技术在手机APP上合适吗? 毕竟带着绿布在户外不现实. 是的, 太不现实了, 我们之前不做也是这样想的, 用户量不大, 使用场景不大. 没有谁愿意在户外先支好绿布,然后再拍视频 ...

  6. 视频编辑SDK,AE模版SDK,绿幕抠图SDK,AI人像分割SDK,VLOG模版SDK

    蓝松短视频SDK(视频编辑.AE模版.绿幕抠图.人像分割.人体抠图.VLOG模版): 高集成度:SDK中的大部分功能,都是一行代码设置 高完整度:提供常见视频编辑UI界面,可直接使用 高独立性:蓝松S ...

  7. Windows OpenGL 图像绿幕抠图

    目录 一.OpenGL 图像绿幕抠图 1.原始图片 2.效果演示 二.OpenGL 图像绿幕抠图源码下载 三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  & ...

  8. Unity3D视频绿幕抠图的实现及优化

    Unity3D视频绿幕抠图的实现及优化 展开 本文是通过Shader处理绿幕的方式来实现Unity中视频(VideoPlayer)的绿幕抠图.因为项目原因,不追究细节(能用就好能用就好)orz可是我连 ...

  9. 通过OpenCV对视频进行绿幕抠图

    通过OpenCV对视频进行绿幕抠图 效果 代码 1.打开视频素材 2.保存视频路径及格式设置 3.读取一帧视频 4.寻找绿幕背景 5.融合 6.代码执行效果 效果 今天跟大家分享的是最近比较受大家喜欢 ...

最新文章

  1. freeBSD挂载光驱
  2. android 按下缩小效果松开恢复_iPhone XS/XS Max如何强制重启?如何进入恢复模式或DFU模式?...
  3. Follow My Logic 1048 PKU
  4. 科技感的动态设计方法-1
  5. OGRE 1.7.2 [Cthugha] 编译配置全过程方法
  6. iphone桌面横屏设置在哪里_我和我各司其职的桌面们
  7. 在Chrome78浏览器上如何实现自动播放音视频
  8. flash制作文字笔顺_Flash中使用逐帧动画实现按笔顺书写汉字的效果
  9. mapabc 地图失效不能进行任何操作
  10. 2019年江苏卷数学高考真题Word版含答案解析
  11. 微软bi报表服务器,升级 Power BI 报表服务器
  12. 【学习资源】光学、物理类、电子学实验合集
  13. 软件测试肖sir__006xmind思维导图实战__微信发红包
  14. SpringMVC中使用hibernate-validator的坑
  15. python异常处理try判断整数_Python之异常处理
  16. 2022电动两轮市场格局分化,九号异军突起
  17. 关于Connection Closed Gracefully问题
  18. Windows10退出微软账户使用本地账户
  19. 乐忧商城项目总结-4
  20. MCTF--MISC

热门文章

  1. 快排的改良版——内省式排序
  2. 【量化交易】股票价格前复权与后复权的区别以及注意事项
  3. TouchGFX软件包下载
  4. 联通无线猫3G转换WiFi是不是鸡肋?
  5. 图片懒加载是怎么实现的?如何实现图片懒加载?
  6. Supplier JAVA_使用Supplier Java 8进行缓存
  7. Tableau实战 房地产估值分析
  8. 模拟和数字电子电路基础-2-电阻网络
  9. 什么是浪涌保护器,浪涌保护器(SPD)的工作原理科普
  10. OpenCV+Mediapipe+UDP+Unity挥手电子书翻页