【短道速滑五】性能只逼双线性插值,但效果要好很多---还有什么理由不用双三次立方插值呢?
在2年前,我写过SSE图像算法优化系列十八:三次卷积插值的进一步SSE优化 一文,在那里使用了SSE对三次卷积插值进行了SSE优化,原本以为那个速度已经比较极限了,最新遇到一个项目需要更高速的效果,自己又对这个算法进行了下构思,发现原来根本不是那回事,速度极限离天花板还早着呢。
早期的优化中,仅仅是在每个像素的放大内部使用SIMD指令进行处理,而没有考虑每个相邻像素或者相邻行像素之间的联系和关系,因此呢计算量依旧是很大。 再来仔细看看三次立方插值,他需要涉及到像素是4*4的领域,共有16个权重,但是16个权重可以看成是水平和垂直分离的,因此可以先计算行方向的累计值,然后再计算列方向的累加和,我们发现,在放大和缩小时,这4行的取样点一般来说总会有部分是重叠的,甚至是完全重叠的,如果是完全重叠,那么水平方向的累加和是根本无需进行计算的,部分重叠时,也可以只计算重叠的部分,这个时候,整体的计算量将大大的减少。这也是行和列分离计算所带来的好处。4*4的取样这个特性,决定他在某方面非常合适使用SIMD指令进行优化。对于灰度图,由于其一个采样点水平方向只涉及到4个像素(4个字节),不适合在取样时就计算其水平方向的累加值(是指不适合用SIMD指令,如果纯C实现反而就要在取样时计算了),我们先收集取样数据,然后再整体计算累加值时使用SIMD指令优化,而对于24位或者是32位图,由于取样4个像素占用了12个字节和16个字节,此时就可以直接在取样时进行计算,避免了收集取样数据的耗时,使得彩色模式图像比灰度也仅仅多了一倍时间,而不是3倍或4倍。
就是这么一个简单的思路,能极大的提高算法的速度,而对于另外一个经典的Lanczos4插值算法,他涉及到的领域范围是8*8,同样可以使用上述的方式进行优化。
测试一幅720P的彩色图放大到1080P,三次立方插值单次的执行时间越月8.5ms, Lanczos4的耗时17.7ms左右,如果是灰度图像,则三次立方耗时约6ms,Lanczos4用时7.5ms,差异很小。
如果4K彩色图缩小到1080P图,三次立方插值单次的执行时间越15ms, Lanczos4的耗时31ms左右,如果是灰度图像,则三次立方耗时约10ms,Lanczos4用时也是10ms左右,也差异很小。
和Opencv比较发现,CV你如果调用100次某个图的放大,他是多线程的执行的,CPU使用率到了100%,而且这个时候他的速度也就是和我的差不多。
另外,三次立方插值其实有个参数可以调节,他控制了结果是锐化还是模糊一些,如下图所示:
相关文章
- spatial4j入门实战
- 容灾系列(六)——数据存储容灾建设
- 在真实环境中使用深度残余网络进行面部情感识别
- 基础网络云服务器&云数据库资源切换私有网络如何实现IP不变
- 实战篇:Oracle 配置透明网关访问 MySQL 详细教程
- 如何计算服务限流的配额
- 分区副本限流机制三部曲(源码篇)
- 「Spark从精通到重新入门(一)」Spark 中不可不知的动态优化
- 云时代,我们到底需要怎样的数据库?
- OushuDB 学习经验分享(二):与HAWQ的区别
- Firestorm - 腾讯自研Remote Shuffle Service在Spark云原生场景的实践
- CancerSCEM: 人类癌症单细胞表达图谱数据库
- GT Transceiver中的RX功能块简述
- 我是如何赢得吴恩达首届 Data-centric AI 竞赛的?
- 一文速览 | 对话生成预训练模型
- 《云原生:运用容器、函数计算和数据构建下一代应用》
- SLAM中位姿估计的图优化方法比较
- 我是怎么用MySQL的
- 还在用分页?你out了 !试试 MyBatis 流式查询,真心强大!
- 深入分析 I/O 的工作机制