imuncle.github.io icon indicating copy to clipboard operation
imuncle.github.io copied to clipboard

代码实现圆筒镜艺术

Open imuncle opened this issue 5 years ago • 1 comments
trafficstars

圆筒镜艺术是一门比较冷面的艺术,百度里搜索也找不到几张图片,不过大家一看就懂,比如下面这两幅图:

image

image

在我看来这种艺术的精妙之处在于得到的作品看似畸变无序,看不出是个什么玩意儿,但当把圆筒镜放上去的时候,相信所有人都会惊呼【卧槽】

然而我虽然热爱绘画,但我的绘画水平不行,所以我决定用代码的方式来绘制。

原理分析

直观来看,圆筒镜成像的过程如下所示:

image

但是这个没有揭示本质,实际的成像过程应该是下图所示:

image

可以把成像过程看为两步。图中O点为相机的聚焦点,①为相机的像平面,即我们期望在相机里看到的画面,②为①的纸张平面的透射变换,③为②对于圆筒镜的反射成像,③也就是我们最后要得到的图像。

透射变换

透射变换很简单,只需要求出纸张平面和相机像平面之间的单应矩阵即可,我这里直接使用相机标定中的棋盘,识别到角点后直接使用OpenCV的findHomography函数求得单应矩阵,这里用H表示,则两个坐标系之间的关系如下:

image

反射变换

反射变换则在纸张平面上分析,但因为圆筒镜的镜面是曲面,反射面法线方向都是改变的,所以我们首先要找到图像上每一点对应的法线方向,或者说对应的圆筒镜上的反射点。

如下图所示,我们可以根据相机像平面得到反射点,并且很容易知道,图像中同一列的像素点对应的反射点是一样的。

image

回到纸张平面,考虑一点(x, y),其反射点为(△x, -△y),反射成像点为(x', y')

image

通过简单的平面几何分析可以得到反射成像点的公式。

image

写成矩阵形式即为:

image

总结

至此,我们对成像过程的解析就完成了,用两个矩阵即可完全表示。我们只需要遍历每一个像素,对每一个像素依次做透射变换和反射变换即可。

最后给出我的效果:

image

imuncle avatar Sep 16 '20 02:09 imuncle

1

GuanghuiLin avatar Dec 31 '20 16:12 GuanghuiLin