ue4 android vulkan,在Android用vulkan完成蓝绿幕扣像

效果图(1080P处理)

因为摄像头开启自动曝光,画面变动时,亮度变化导致扣像在转动时如上。

这个demo主要测试二点,一是测试ndk camera集成效果,二是本项目对接外部实现的vulkan层是否方便,用于以后移植GPUImage里的实现。

我简化了在android下vulkan与opengles纹理互通里的处理,没有vulkan窗口与交换链这些逻辑,只用到vulkan compute shader计算管线得到结果然后交换给opengl里的纹理。

NDK Camera集成

主要参考 NdkCamera Sample的实现,然后封装成满足Aoce定义设备接口。

说下遇到的坑。

AIMAGE_FORMAT_YUV_420_888 可能是YUV420P,也可能是NV12,需要在AImageReader_ImageListener里拿到image通过AImage_getPlanePixelStride里的UV的plan是否为1来判断是否为YUV420P,或者看data[u]-data[y]=1来看是否为NV12.具体可以看getVideoFrame的实现。

AImageReader_new里的maxImages比较重要,简单理解为预先申请几张图,这个值越大,显示越平滑。

AImageReader_new如果不开线程,则图像处理加到这个线程里,导致读取图像变慢。打开线程处理,

我用的Redmi K10 pro,可以读40003000,在AImageReader_ImageListener回调不做特殊处理,如下错误。

首先是Unable to acquire a lockedBuffer, very likely client tries to lock more than.

可以看到,运行四次后报的,就是我设的maxImages,通过比对代码逻辑,应该是AImageReader_new读四次后,我还没处理完一桢,没有AImage_delete,也就读不了数据了.

然后检查 AImageReader_acquireNextImage 这个状态,不对不读,然后继续引发读取不可用内存问题,分析应该是处理数据的乱序线程AImage_delete可能释放别的处理线程上的image,然后处理图像线程上加上lock_guard(mutex),不会引发问题,但是会导致每maxImages卡一下,可以理解,读的线程快,处理的慢,后面想了下,直接让thread.join,图片读取很大时慢(比不开线程要快很多,40003000快二倍多,平均45ms),但是平滑的,暂时先这样,后面看能不能直接拿AImage的harderbuffer去处理,让处理速度追上读取速度。

Chroma Key

如上所说,项目对接外部实现的vulkan层是否方便,在这重新生成一个模块aoce_vulkan_extra,在这我选择UE4 Matting里的逻辑来测试,因为这个逻辑非常简单,也算让我对手机的性能有个初步的了解。

首先把相关逻辑整理下,UE4上有相关节点,看下实现整理成glsl compute shader实现。

#version 450

// https://www.unrealengine.com/en-US/tech-blog/setting-up-a-chroma-key-material-in-ue4

layout (local_size_x = 16, local_size_y = 16) in;// gl_WorkGroupSize

layout (binding = 0, rgba8) uniform readonly image2D inTex;

layout (binding = 1, rgba8) uniform image2D outTex;

layout (std140, binding = 2) uniform UBO {

// 0.2 控制亮度的强度系数

float lumaMask;

float chromaColorX;

float chromaColorY;

float chromaColorZ;

// 用环境光补受蓝绿幕影响的像素(简单理解扣像结果要放入的环境光的颜色)

float ambientScale;

float ambientColorX;

float ambientColorY;

float ambientColorZ;

// 0.4

float alphaCutoffMin;

// 0.5

float alphaCutoffMax;

float alphaExponent;

// 0.8

float despillCuttofMax;

float despillExponent;

} ubo;

const float PI = 3.1415926;

vec3 extractColor(vec3 color,float lumaMask){

float luma = dot(color,vec3(1.0f));

// 亮度指数

float colorMask = exp(-luma*2*PI/lumaMask);

// color*(1-colorMask)+color*luma

color = mix(color,vec3(luma),colorMask);

// 生成基于亮度的饱和度图

return color / dot(color,vec3(2.0));

}

void main(){

ivec2 uv = ivec2(gl_GlobalInvocationID.xy);

ivec2 size = imageSize(outTex);

if(uv.x >= size.x || uv.y >= size.y){

return;

}

vec3 inputColor = imageLoad(inTex,uv).rgb;

vec3 chromaColor = vec3(ubo.chromaColorX,ubo.chromaColorY,ubo.chromaColorZ);

vec3 ambientColor = vec3(ubo.ambientColorX,ubo.ambientColorY,ubo.ambientColorZ);

vec3 color1 = extractColor(chromaColor,ubo.lumaMask);

vec3 color2 = extractColor(inputColor,ubo.lumaMask);

vec3 subColor = color1 - color2;

float diffSize = length(subColor);

float minClamp = diffSize-ubo.alphaCutoffMin;

float dist = ubo.alphaCutoffMax - ubo.alphaCutoffMin;

// 扣像alpha

float alpha= clamp(pow(max(minClamp/dist,0),ubo.alphaExponent),0.0,1.0);

// 受扣像背景影响的颜色alpha

float inputClamp = ubo.despillCuttofMax - ubo.alphaCutoffMin;

float despillAlpha = 1.0f- clamp(pow(max(minClamp/inputClamp,0),ubo.despillExponent),0.0,1.0);

// 亮度系数

vec3 lumaFactor = vec3(0.3f,0.59f,0.11f);

// 添加环境光收益

vec3 dcolor = inputColor*lumaFactor*ambientColor*ubo.ambientScale*despillAlpha;

// 去除扣像背景

dcolor -= inputColor*chromaColor*despillAlpha;

dcolor += inputColor;

// 为了显示查看效果,后面屏蔽

dcolor = inputColor*alpha + ambientColor*(1.0-alpha);

imageStore(outTex,uv,vec4(dcolor,alpha));

}

这里面代码最后倒数第二句实现混合背景时去掉,在这只是为了显示查看效果。

然后引用aoce_vulkan里给的基类VkLayer,根据接口完成本身具体实现,相关VkChromKeyLayer的实现可以说是非常简单,至少我认为达到我想要的方便。

还是一样,先说遇到的坑,

开始在glsl中的UBO,我特意把一个float,vec3放一起,想当然的认为是按照vec4排列,这里注意,vec3不管前后接什么,大部分结构定义下,都至少占vec4,所以后面为了和C++结构align一样,全部用float.

层启用/不启用会导致整个运算graph重置,一般情况下,运算线程与结果输出线程不在一起,在重置时,运算线程相关资源会重新生成,而此时输出线程还在使用相关资源就会导致device lost错误,在这使用VkEvent用来表示是否在资源重置中。

然后就是与android UI层对接,android的UI没怎么用过,丑也就先这样吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++静态关联与动态关联

1.1确认具体对象的过程叫关联(binding),在这里指把一个函数与类对象捆绑在一起,建立关联。 1.2什么是静态关联? 函数重载和通过对象名调用的虚函数,在编译时即可确定其调用的虚函数属于哪一个类,其过程称为静态关联&…

html5 规定输入字段,HTML5 Input属性详解

本篇教程探讨了HTML5 Input属性详解&#xff0c;希望阅读本篇文章以后大家有所收获&#xff0c;帮助大家HTML5CSS3从入门到精通 。<value 属性value 属性规定输入字段的初始值&#xff1a;readonly 属性readonly 属性规定输入字段为只读(不能修改)&#xff1a;readonly 属性…

html5程序自动登录,Jtro的技术分享:网页调起unity的exe程序并自动登录

思路是这样&#xff1a;通过一个额外的exe文件来实现登录&#xff0c;并保存一个token文件&#xff0c;然后在unity的项目提交数据的时候读取这个token向服务器发送数据。下面是具体的方法&#xff1a;s这个需要用到WPF来编写&#xff0c;首先打开VS2017&#xff0c;选择创建WP…

C++纯虚函数与抽象类

纯虚函数 1.1纯虚函数是在声明虚函数时被“初始化”为0的函数。声明纯虚函数的一般形式为&#xff1a;virtual 函数类型 函数名 (参数列表) 0;如 virtual float area() const 0;1.2纯虚函数没有函数体&#xff0c;而且这是一个声明语句后面应有分号。1.3纯虚函数最后面的“0”并…

html 图片防盗链,【反防盗链】介绍一个对付图片防盗链的方法

悲催的声明&#xff1a;由于腾讯也采用了防盗链技术&#xff0c;本文方法已经失效了&#xff01;当我们想在文章里引用某张图片时&#xff0c;如果对方设置了防盗链&#xff0c;我们看到的将是404或forbidden或其他图片&#xff0c;而不是想要的那张图片&#xff0c;为此&#…

C++文件操作与文件流

文件的概念 1.1文件是程序设计中一个重要的概念&#xff0c;所谓“文件”&#xff0c;一般指存储在外部介质上数据的集合。1.2外存文件包括磁盘文件&#xff0c;光盘文件&#xff0c;和U盘文件。1.3对用户来说常用的文件类型有两大类&#xff0c;一类是程序文件&#xff0c;如C…

html字体阴影怎么设置6,css怎么设置字体阴影

css设置字体阴影的方法&#xff1a;使用代码【text-shadow:3px 3px 3px #00f;】&#xff0c;【text-shadow】属性应用于阴影文本&#xff0c;语法为【text-shadow: h-shadow v-shadow blur color;】。本教程操作环境&#xff1a;windows10系统、css3版&#xff0c;该方法适用于…

PCL入门

pcl的入门 本博客主要是对外文的翻译&#xff0c;及其他资料的一些整理。 pcl 分割成好几个模块的库 Filters(滤波器) Features(特征) Keypoints(关键点) Registration(注册) KdTree:k-dimension tree(k维的树) OcTree(八叉树) Segmetation(分割) Sample Consensus(采…

台式电脑怎么看计算机型号,怎么查看台式机的型号

电脑配置有很多&#xff0c;很多人在买电脑总是觉得配置和商家说的不是一样的&#xff0c;下面就让小编教大家台式机怎么查看型号和配置。查看台式机型号和配置的方法金山卫士查看首先打开自己电脑的安全卫士软件&#xff0c;其实卫士都有这种功能的&#xff0c;我这里实用的是…

pcl的初步使用(ROS)

ROS里面已经预装好了pcl&#xff0c;和一些与pcl之间的转换&#xff0c;我们接下来看看如何在ros里面使用pcl.。 总的来说&#xff0c;PCL包含了一个很重要得到数据结构&#xff0c;叫PointCloud&#xff0c;这是一个模板类&#xff0c;把点的类型作为模板参数。 下面是最重要…

四川大学计算机学硕分数线,川大计算机考研分数线

川大计算机考研分数线&#xff1f;2016高考志愿填写&#xff0c;高考考生家长有开端着手预备吗 厚学网收拾了对于普通高校招生填写志愿的有关诀窍&#xff0c;供考生和家长参阅。绝密:高考填报志愿有技巧!志愿填报需要注意的细节问题&#xff1a;语种有限制在咱们要学习的外语语…

pcl里面的3D特征

我这里不介绍pcl里面的类的命名规范&#xff0c;及点的类型。为什么呢?pcl里面类的命名规范&#xff0c;比较繁琐&#xff0c;而且主要是针对要对pcl这个库要开源的人士&#xff0c;而pcl里面的点的类型太多&#xff0c;足够满足你的要求。所以我们要走一条具有中国特色的pcl主…

html本地缓存未查看信息,不同用户看到了相同的信息-一次web系统缓存问题的解决...

最近负责的系统总是出现奇怪的缓存问题&#xff0c;在这里简单记录一下碰到的问题和踩到的坑。问题&#xff1a;用户反映使用不同账号A&#xff0c;B登录时&#xff0c;都出现账号A的页面信息(未邮寄账单提示)。如下所示&#xff1a;图1&#xff1a;未邮寄账单提示一 session缓…

pcl里面的法线估计

法线估计是一个很重要的特征&#xff0c;常常在被使用在很多计算机视觉的应用里面&#xff0c;比如可以用来推出光源的位置&#xff0c;通过阴影与其他视觉影响。 给一个几何表面&#xff0c;去推断给定点的法线方向&#xff0c;即垂直向量的方向往往是不容易的。然而&#xf…

pcl通过积分图来进行法线预测

首先&#xff0c;我们来看一下什么是积分图&#xff0c;我查了一下wiki&#xff0c;发现它的定义是这样的。 A summed area table is a data structure and algorithm for quickly and efficiently generating the sum of values in a rectangular subset of a grid. In the i…

个人计算机的防毒软件无法防御,在win10系统中无法启动defender防御软件的解决方法...

软件大小&#xff1a; 3.56 MB软件版本&#xff1a; 3.3.30.180软件类型&#xff1a;系统补丁查看详情直接下载win10系统是我们现在都在使用的系统&#xff0c;下面小编为大家在win10系统中无法启动defender防御软件的解决方法,希望可以帮助到你们。解决方法&#xff1a;1、根据…

pcl里面的点特征直方图(PFH)

表面法线和曲率可以好的代表一个点的几何特征。然而它们算得很快&#xff0c;而且算法简单&#xff0c;但是它们不能捕获细节&#xff0c;它们只是点的近邻的几何特征的近似估计。作为一个直接的结论&#xff0c;大多数的场景往往会包括很多有着相似特征的点&#xff0c;这会减…

为什么计算机休眠风扇还转,Win7系统进入睡眠模式后电脑风扇还在转的解决方法...

如果长时间离开电脑&#xff0c;可以让win7系统进“睡眠”模式&#xff0c;这样可以节省能源&#xff0c;延长硬盘寿命。但是有位用户说自己Win7系统进入睡眠模式后&#xff0c;依旧可以听到风扇还在转&#xff0c;怎么回事呢&#xff1f;其实这是因为Win7处在低耗能的状态&…

快速特征点直方图描述器(FPFH)

PFH的理论上的时间复杂度是O(nk的平方)&#xff0c;n是点的数量&#xff0c;k是最近邻的个数。对于实时系统来说&#xff0c;这压根就是不行的&#xff0c;所以作为PFH规划的简化版本&#xff0c;FPFH把计算复杂度减少成O(nk),但是还具有很好的和PFH差不多的区分能力。 第一步…