Python OpenCV 图像的 最近邻插值 与 双线性插值算法 优化迭代
Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 43 篇。
基础知识铺垫
先补齐一下昨天文章发布出去的一个小坑,最后一段代码实现之后,发现运行之后图像边缘出现了很多锯齿。
疑惑的同时,肯定是代码有细节弄差了,复查代码的时候发现问题了,注意下述代码:
与公式比对,这个细致的活你可以自己比对一下。f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
问题出在图像的行与列上,代码的 u*(1-v) * src[j+1, i, n] + (1-u)*v*src[j, i+1, n]
这个部分我写反了~尴尬
修改成下述代码,搞定,基本一模一样了。
算法优化
下面说一下算法优化吧,咱还在 这篇博客 挖下了一个小坑,最近邻插值算法最终的结果不尽人意,图像在放大的时候出现了很强的锯齿。
先把之前的代码迁移过来,修改成如下格式:
第一部分的优化是关于中心点的,这部分说真的,橡皮擦找了很多资料,发现都解释的不太清楚,基本就是到重点的地方就略过了,大意我在进行转述一遍,如果你有好的解释,欢迎在评论区提供给我,重点就是那 0.5 像素的问题。
上文代码如果想实现和 OpenCV 提供的内置函数一样的效果,重点修改的地方如下:
就是在这个地方直接懵掉了,有的博客中写道 srcX=dstX* (srcWidth/dstWidth)+0.5*(srcWidth/dstWidth-1)
相当于我们在原始的浮点坐标上加上了0.5*(srcWidth/dstWidth-1)
?
但是这个地方没有其它解释了,有的博客会用两张图对比着说要源图像与目标图像的几何中心对齐,但是也只是画了两张图加上一些简单的文字描述,摘抄如下:
假设源图像是 3x3
,这个图像的中心点坐标为 (1,1)
,目标图像为 9x9
,中心点坐标是 (4,4)
,那中心点对齐就应该指的是 (4,4)
点对齐到 (1,1)
点,但是根据 srcx = round(x*src_x/tar_x)
与 srcy = round(y*src_y/tar_y)
公式计算,得到的中心点坐标是 (1.333,1.333)
并不是 (1,1)
,图像整体偏右下方,现在需要对齐。
那我们进行一下简单的推算。中心点对齐提前假设源图像不动,那最终应该是存在下列公式。
源图像 src
中心点坐标 ,目标图像 dst
中心点坐标
将上述值带入公式:
式子转换成
最后求得 K 的值为
所以 K 其实等于
对应到代码上,就变成了如下内容:
其实这时你在这里一下,就得到最终的结果了。
修改之后,运行感觉比系统内置的效果还出色一些了,哈哈哈。
相同的优化复制到双线性插值算法中,自己可以对比一下运行的效果。
关于运行速度,我也找了一些资料,奈何目前掌握的基础知识不够,目前先搁置一下吧,这个系列过 100 篇的时候,我们在聊。
橡皮擦的小节
真没有想到,一个 0.5 像素的小问题竟然这么费力。
希望今天的 1 个小时你有所收获,我们下篇博客见~
版权声明: 本文为 InfoQ 作者【梦想橡皮擦】的原创文章。
原文链接:【http://xie.infoq.cn/article/17945992fbbbf63af273e7b7e】。文章转载请联系作者。
评论