Harris角点检测

UI还是用的上次扣像的,只有前后置可以用,别的没有效果,只看实现就好.

相应源码

在实现之前,我先重新整理编译glsl的生成工具,如Harris角点检测中间计算过程需要针对rgba32f做高斯模糊,我们前面针对rgba8实现过,现在使用glslangValidator针对一份文件生成一编译文件会导致维护麻烦,很多无意义的重复代码,暂时还不想把glslangValidator集成到代码中动态生成,所以在这,先搞定glsl根据编译条件生成多份文件的工具.

其所有glsl代码全统一移到根目录glsl/source下,编写一个py文件,在vscode里用python脚本编写工具确实很方便,写好了可以在vscode里直接运行py脚本,其中针对多条件编译定义如下文件.

blend.comp
chromaKey.comp
filterColumn.comp filterColumn.comp CHANNEL_RGBA=1
filterColumn.comp filterColumnC1.comp CHANNEL_R8=1
filterColumn.comp filterColumnF4.comp CHANNEL_RGBAF32=1
filterRow.comp filterRow.comp CHANNEL_RGBA=1
filterRow.comp filterRowC1.comp CHANNEL_R8=1
filterRow.comp filterRowF4.comp CHANNEL_RGBAF32=1

glsl代码修改如下

#if CHANNEL_RGBA
layout (binding = 0, rgba8) uniform readonly image2D inTex;
layout (binding = 1, rgba8) uniform image2D outTex;
#elif CHANNEL_R8
layout (binding = 0, r8) uniform readonly image2D inTex;
layout (binding = 1, r8) uniform image2D outTex;
#elif CHANNEL_RGBAF32
layout (binding = 0, rgba32f) uniform readonly image2D inTex;
layout (binding = 1, rgba32f) uniform image2D outTex;
#endif // 共享块,扩充前后二边HALO_SIZE(分为上HALO_SIZE,中间自身*PATCH_PER_BLOCK,下HALO_SIZE)
#if CHANNEL_RGBAF32
shared vec4 column_shared[16*(PATCH_PER_BLOCK+HALO_SIZE*2)][16];//vec4[local_size_y][local_size_x]
#define packUnorm4x8
#define unpackUnorm4x8
#else
shared uint column_shared[16*(PATCH_PER_BLOCK+HALO_SIZE*2)][16];//vec4[local_size_y][local_size_x]
#endif

python脚本流程,针对传入的文件分析每行需要编译的文件,确认是否需要条件编译,根据条件编译每个文件,错误的话提示错误文件,正确则把所有文件复制到运行目录,安装目录.其中android则使用build.gradle复制生成目录下的编译文件到assets目录下.

相关harris检测原理可以参考:harris边角(兴趣点)检测算法

移植Harris角点检测的代码,实现比较简单,根据GPUImage源码,按XYDerivative/ GaussianBlur/ HarrisCornerDetection/ ThresholdedNonMaximumSuppression四层连接起来就行了,根据GPUImage的代码移植到Compute shader还是很快的,有兴趣可以查看VkHarrisCornerDetectionLayer的实现.

把角点和原图加一起显示倒是取了巧,1080P下,角点显示一个像素还是很难看清的,于是想根据原图上的点周边是否包含角点,然后显示成红色,发现这么简单一个问题,我想不到适合GPU来算的方法,取个巧,把检测的角点图模糊一下,1.0周边根据模糊半径都大于0了,然后直接比对大于0的就显示.

导向滤波

嗯,我发现GPUImage好像没这实现,不过这个算法效果不错,如下效果图.

原图:

绿色扣图:

扣图经过导向滤波处理:

我原来移植到CUDA过里,有兴趣移步CUDA加opencv复现导向滤波算法.

我总结下了GPU里比较容易实现的流程.

看了这图,我忽然理解GPUImage为什么不实现这个算法了,算法不复杂,需要节点多输入多输出以及流程正确顺序保证,先看下类的主要流程实现,有兴趣可以查看详细代码.

void VkGuidedLayer::onInitGraph() {
VkLayer::onInitGraph();
// 输入输出
inFormats[0].imageType = ImageType::rgba32f;
inFormats[1].imageType = ImageType::rgba32f;
outFormats[0].imageType = ImageType::rgba8;
pipeGraph->addNode(convertLayer.get())
->addNode(resizeLayer->getLayer())
->addNode(toMatLayer.get());
pipeGraph->addNode(box1Layer->getLayer());
pipeGraph->addNode(box2Layer->getLayer());
pipeGraph->addNode(box3Layer->getLayer());
pipeGraph->addNode(box4Layer->getLayer());
pipeGraph->addNode(guidedSlayerLayer->getLayer());
pipeGraph->addNode(box5Layer->getLayer());
pipeGraph->addNode(resize1Layer->getLayer());
} void VkGuidedLayer::onInitNode() {
resizeLayer->getNode()->addLine(box1Layer->getNode(), 0, 0);
toMatLayer->getNode()->addLine(box2Layer->getNode(), 0, 0);
toMatLayer->getNode()->addLine(box3Layer->getNode(), 1, 0);
toMatLayer->getNode()->addLine(box4Layer->getNode(), 2, 0);
box1Layer->getNode()->addLine(guidedSlayerLayer->getNode(), 0, 0);
box2Layer->getNode()->addLine(guidedSlayerLayer->getNode(), 0, 1);
box3Layer->getNode()->addLine(guidedSlayerLayer->getNode(), 0, 2);
box4Layer->getNode()->addLine(guidedSlayerLayer->getNode(), 0, 3);
guidedSlayerLayer->getNode()->addLine(box5Layer->getNode());
box5Layer->getNode()->addLine(resize1Layer->getNode());
convertLayer->getNode()->addLine(getNode(), 0, 0);
resize1Layer->getNode()->addLine(getNode(), 0, 1);
getNode()->setStartNode(convertLayer->getNode());
}

如何保证层的执行顺序,可以查看PipeGraph的resetGraph的实现,简单来说,pipegraph添加节点的顺序不重要,重要的是addLine接入接出正确,PipeGraph会自动根据节点连接线来重构执行顺序.

可以看到虽然有很多计算层,但是效率非常高,N卡2070下,1080P的图像 ,快速导向resize长宽/8下,关于导向滤波的处理差不多就1ms,主要是导向滤波与图像的分辨率无关,中间所有计算可以在很少的分辨率下进行.

可以看到中间很多层大多全是0.02ms,主要就是因为导向滤波的分辨率无关性.

在安卓机器Redmi 10X Pro下测试,720P能流畅跑此效果.

Vulkan移植GpuImage(二)Harris角点检测与导向滤波的更多相关文章

  1. Vulkan移植GpuImage(四)从D到O的滤镜

    现把D到O的大部分滤镜用vulkan的ComputeShader实现了,列举其中一些有点特殊的说明. GaussianBlurPosition 指定区域高斯模糊 没有按照GPUImage里的方式实现, ...

  2. Harris角点检测算法优化

    Harris角点检测算法优化 一.综述 用 Harris 算法进行检测,有三点不足:(1 )该算法不具有尺度不变性:(2 )该算法提取的角点是像素级的:(3 )该算法检测时间不是很令人满意. 基于以上 ...

  3. Harris角点检测

    代码示例一: #include<opencv2/opencv.hpp> using namespace cv; int main(){ Mat src = imread(); imshow ...

  4. Harris 角点检测

    一 .Motivation 对于做图像处理的人来说,Harris角点检测肯定听过,1988年发表的文章"A combined corner and edge detector"描述 ...

  5. Harris角点检测算原理

    主要参考了:http://blog.csdn.net/yudingjun0611/article/details/7991601  Harris角点检测算子 本文将该文拷贝了过来,并做了一些数学方面的 ...

  6. Harris角点检测原理分析

    看到一篇从数学意义上讲解Harris角点检测很透彻的文章,转载自:http://blog.csdn.net/newthinker_wei/article/details/45603583 主要参考了: ...

  7. Opencv学习笔记------Harris角点检测

    image算法测试iteratoralgorithmfeatures 原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/73 ...

  8. harris角点检测的简要总结

    目录 1. 概述相关 2. 原理详解 1) 算法思想 2) 数学模型 3) 优化推导 3. 具体实现 1) 详细步骤 2) 最终实现 4. 参考文献 1. 概述相关 harris角点检测是一种特征提取 ...

  9. OpenCV-Python:Harris角点检测与Shi-Tomasi角点检测

    一.Harris角点检测 原理: 角点特性:向任何方向移动变换都很大. Chris_Harris 和 Mike_Stephens 早在 1988 年的文章<A CombinedCorner an ...

随机推荐

  1. 修改jupyter-notebook的python3版本

    将默认的kernel修改为对应的python即可: /home/a/.virtualenvs/YOUR_VENV/bin/python -m pip install ipykernel /home/a ...

  2. fibonacci number & fibonacci sequence

    fibonacci number & fibonacci sequence https://www.mathsisfun.com/numbers/fibonacci-sequence.html ...

  3. CSS rulesets

    CSS rulesets https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax#CSS_rulesets https://css-tricks ...

  4. 微信小程序 components

    微信小程序 components wx-xcx-components https://developers.weixin.qq.com/miniprogram/dev/component/ https ...

  5. how to check a var whether is number in js

    how to check a var whether is number in js js check var is number Number.isInteger(NaN) false Number ...

  6. APP 跳转到支付包小程序

    APP 跳转到支付包小程序 APP选择支付宝支付,会跳转到支付宝小程序再支付 支付包 小程序 我司有自己的APP.生活号,小程序,这种情况下如何和小程序关联,跳转到小程序里去,做到无缝对接? 其实,小 ...

  7. CORS OPTIONS

    CORS OPTIONS A CORS preflight request is a CORS request that checks to see if the CORS protocol is u ...

  8. Java自学第10期——File类与IO流(输入输出流、处理流、转换流、缓冲流、Properties集合、打印流)

    1.IO简介 IO(输入输出)通过java.io包下的类和接口来支持,包下包括输入.输出两种IO流,每种输入输出流又可分为字符流和字节流两大类. 2.File类 File类是io包下与平台无关的文件和 ...

  9. 1107 Social Clusters——PAT甲级真题

    1107 Social Clusters When register on a social network, you are always asked to specify your hobbies ...

  10. JUnit5学习之四:按条件执行

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...