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. openssl的用法

    Openssl详细用法: OpenSSL 是一个开源项目,其组成主要包括一下三个组件: openssl:多用途的命令行工具 libcrypto:加密算法库 libssl:加密模块应用库,实现了ssl及 ...

  2. Windows font-size: 10px; bug

    Windows font-size: 10px; bug Windows 最小只能渲染 font-size: 12px; ???屏幕分辨率 macOS 正常渲染 10px PC 最小只能渲染 font ...

  3. code screenshot beautify plugin & 代码截图美化插件

    code screenshot beautify plugin & 代码截图美化插件 代码截图美化 codesnap 微信分享代码截图 https://github.com/kufii/Cod ...

  4. 如何将多个 Apple 设备中保存在 iCloud 里面密码同步

    如何将多个 Apple 设备中保存在 iCloud 里面密码同步 iCloud 钥匙串 密码同步 数据迁移 iOS iCloud 钥匙串会记住一些信息,因此您就无需记忆这些信息. 它会在您批准的任何设 ...

  5. js 构造函数 & 静态方法 & 原型 & 实例方法

    js 构造函数 & 静态方法 & 原型 & 实例方法 ES5 "use strict"; /** * * @author xgqfrms * @licens ...

  6. 「NGK每日快讯」2021.2.8日NGK公链第97期官方快讯!

  7. Unity安卓apk打包过程

    前言:对于Unity开发小白来说,Android打包无疑是个头痛的问题,所以我总结了 Unity安卓APK的打包过程 第一步:下载对应版本的Android Platform 第二步:安装JDK并配置J ...

  8. 自己写的一个抢票加速的Python小程序源码分享-----纯属娱乐

    最近这段时间频频看到微信群里发什么 抢票加速,智行.携程.飞猪.美团,对于我这能坐客车就不坐火车的人来说,无所谓靠谱不靠谱 突发奇想的整理了下整个抢票加速的逻辑,写了这个小程序,代码很low,拒绝批评 ...

  9. spring-ioc心得

    1.创建spring容器,严格的来说就是创建ClassPathXmlApplicationContext对象, 该对象属于ApplicationContext类型(是一个接口)该接口下有很多实现类, ...

  10. 对Map进行复合操作(读写)且并发执行时,无法保证业务的行为是正确的,对读写操作进行同步则可以解决。

    ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全的Map容器,比如 Hashtable和Collections.synchronizedMap.线程安全的容器, ...