如果对单帧去马赛克有兴趣的朋友,可以参考我的专栏文章:提高驾驶技术:用GAN去除(爱情)动作片中的马赛克和衣服 - 知乎专栏
=========== 分割线:20170625 ===========
鉴于这个问题收到过不少反馈,补充两句为什么要用遗传算法: 1) 回答问题的时候手头刚好有个GA工具包(基于MIT的GALib),2)“屌”的例子是个二值图案,3)可以做出相变般酷炫的动画(http://images.cnitblog.com/blog/609274/201411/141950421945566.gif) 作为一个玩具例子,我觉得屌还是挺不错的,但是强调下如果用到实际中,1)GA是不合适,屌字也不合适,尤其是这么极端的图案,不管L几Norm都是降不下去的。 另,排版更佳的答案请移步:http://www.cnblogs.com/frombeijingwithlove/p/4098072.html
=========== 分割线:20151103 ===========
举个玩具例子来讲一下大概的思想吧:
首先打开画图板,写下一个
线条分明,软绵无力,面对这么屌的一个字,我决定拍一段长达一秒的8x8分辨率的视频:
注意到知乎居然不能现实动图,站外链接如下:
http:// images.cnitblog.com/blo g/609274/201411/141950421945566.gif取出几帧示意如下:
因为手抖,并且相机分辨率低,已经没了屌样。
其实上面是我先把原图的图像随机平移,然后线性插值降采样到8x8分辨率得到的。在这个过程中我模拟了两件事:1) 随机平移模拟视频拍摄过程中的随机抖动,这是从多帧图像中重建超分辨率图像的关键,后面我会讲到,同时这也是符合现实生活规律的,虽然宏观来说拍摄一段静止的视频很容易,可是在像素级别任何微小的画面移动都可以被体现出来。2) 线性插值降采样模拟在CMOS上成像时图像元素小于像素时细节的丢失,线性插值是因为像素记录的值是在像素原件有效感光面积上的平均曝光强度。这两个过程的示意图如下:
首先看第一个图中两个圆的例子,这两个圆大小完全一样,因为成像位置不同,圆在每个像素上覆盖的面积也不一样,对应像素的灰度会不一样,最后在像素阵列上对应了不同的图案,而这个信息正是进行超分辨率重建的基础。同样的对于写下的屌字,在不同的抖动位置上,也会得到不一样的低分辨率图案。
所以问题可以描述为,一幅高分辨率的图像,经过n次某种变换后得到了n幅低分辨率图像,其中第i幅图像为。而具体到视频录制中,"某种变换"就是每次拍摄每一帧的时候记录图像的过程,具体到这个例子中就是手抖导致的图像平移和线性插值的降采样。
所以本质上来讲从多帧低分辨率图像中进行超分辨率重建是个Inference的问题,高分辨率图像中的细节信息在录制成低分辨率帧的时候导致了丢失,然而抖动带来的位移相当于给了多一个维度的信息让我们可以通过算法对信息进行恢复,从某种意义上讲抖动保存了原来图像的细节信息。
抖动有多重要呢,先来做一个简单的试验,尽管采样到的帧分辨率都低得可怜,可是我们如果把抖动的信息恢复出来,也就是把抖动后的这些低分辨率图片对齐,然后求一个平均,结果如下:
这时候已经可以勉强看出屌样了。。
进一步的,我们想推断出更高分辨率的图像,一个很自然的想法就是对超分辨率图像进行猜测,把猜测的图像变换后的结果和录制采样到的结果进行对比,然后把差异作为目标函数进行优化:
对于上面这个优化问题,如果抖动的范围完美覆盖了一个像素周期以内的所有区域,并且每一帧都采样到了这个区域内的所有的点的话,那么理论上是可以恢复出高分辨率图像的,然而通常情况并非如此,比方说我想把我例子中24帧8x8的视频恢复成一幅48x48的高分辨率图像,也就是6倍的分辨率提升,那么24帧显然不够,这种情况叫做ill-posed,也就是说有无数个解可以满足这个优化问题,所以需要一些regularization。通常而言我们看到的图像一般都是较为平滑的,而不是像老式电视机里没信号是那样满屏的雪花斑噪声,所以可以加入一项抑制图像梯度的项:
注意我这里用的都是L1 Norm,一般来说L1的优点是使梯度的分布更为稀疏,这样能更好的保存边缘,另外计算量也小。
用遗传算法来解这个优化问题试试,得到结果如下:
0代:
10代
20代
50代
100代
200代
500代
1000代
2000代
20000代
进化过程动图的链接: http://images.cnitblog.com/blog/609274/201411/181506083165247.gif 因为是GA,所以看上去还是有一点瑕疵,不过屌样已经很明显了,如果继续优化应该能得到完美的结果。当然了,如前所述,我只是用一个玩具例子讲一下超分辨率重构的基本思想,具体的问题中,除了抖动和低分辨率采样,还有镜头PSF(Point Spread Function),图像的转动和其他形变,场景中的物体移动等因素,优化算法也不会是GA这种相比起来漫无目的的搜索(虽然我还修改了变异和交叉函数)。另外降采样我这里用的是线性插值,这包含一个假设,就是每个像素的感光元件的有效感光面积接近这个元件在传感器表面占用的面积,而这个假设通常是很难成立的,尤其是对现在消费级相机和手机中流行的CMOS,还有一种常见的降采样是点采样,这个就比线性采样相对而言简单一些,然而这个通常也不成立,并且一般应用的消费级CMOS还要考虑Bayer阵列的问题。
至于楼主问到PS能否实现,据我所知应该没有。不过OpenCV里做这件事已经非常简单了,一个简化版的代码如下:
cv::Ptr<cv::superres::FrameSource> frames = cv::superres::createFrameSource_Video( "diao.mp4" ); cv::Ptr<cv::superres::SuperResolution> super_res = cv::superres::createSuperResolution_BTVL1(); super_res->setInput( frames ); cv::Mat super_resolved_image; super_res->nextFrame( super_resolved_image ); cv::imshow( "Super Resolved Image", super_resolved_image ); cv::waitKey( 0 );
我用我的高级智能手机拍了一段长达2秒的176x144分辨率的视频测试了一下这段代码:
视频截图(为方便比较用Nearest Neighbor放大到和重建图像等同分辨率):
重建的超分辨率图像:
效果还行。通常情况下超分辨率重建运算量还是比较大的,所以实际情况代码不会这么简单,一个用到GPU的基于OpenCV的例子可以在OpenCV的sample code里找到。
上一次,我在文章 <压缩成像与使用压缩感知的高速摄影技术> 中介绍了压缩成像的基本原理,即将高速摄影时的信号采集表达为一个欠定问题,通过测量信号y和先验信息,恢复出原始信号x。这一次,我来讲讲这个技术如何应用到光学超分辨率这个领域中。
众所周知,大分辨率的常规传感器已经非常普及了。你现在去买个手机,没有千万像素都不好跟人打招呼
然而,这种情况仅限于可见光传感器。 在许多非可见光波段,传感器每像素的价格非常昂贵。 这里显示了2015年几种非可见光波段的传感器的单像素价格。例如短波红外传感器(SWIR),主要采用InGaAs(铟镓砷)材料,单像素约0.1美元,这样的话即便一个100万像素的SWIR传感器,也需要10万美元。这就根本不是普通人能够承受的了。
我们自然会想到上一次介绍的压缩感知技术——如果构建一个相机,采用极少像素的非可见光传感器,就能够恢复出高分辨率的原始场景信息,那么相机成本将大大下降。
于是,就有了图中这种激进的解决方案——单像素相机:Single Pixel Camera。这个系统中,场景的光线通过透镜汇聚,并在数字微镜面上反射,并最终在单个光电探测器上合并,再转换为数字信号。由于单次拍摄只能获取到一个测量值,为了能够恢复出场景的图像,需要不断随机改变数字微镜面形成的掩模,从而获取到多个不同时刻的测量值,再通过这一系列测量值,利用一些先验信息,恢复出场景的图像,这个重建的过程利用了典型的压缩成像重建技术。
这个想法来自2008年Duarte等发表的论文 <通过压缩采样的单像素成像>,单像素相机后续简称为SPC (Single Pixel Camera)
这是作者在论文中展示的原型设备。光线通过两次反射汇聚到光电二极管,并形成最后的信号。 单次采集只能获取到一个测量值,但如果采集了多个测量值后,利用压缩传感技术,就能够恢复出原始信号。 整个系统的分辨率实际上由数字微镜阵列的分辨率决定,而它可以非常便宜。 真正的传感器只有一个光电二极管,并调校至对特定的波段敏感,这样整个系统的就价格大大降低了。
这里最关键的变化是首先将场景发射的光通过可控的数字镜面装置进行调制。这个装置由很多小镜面组成,其方向可以进行轻微的调整,使得它们可以反射光到传感器,或者不反射光到传感器。这就相当于用一个特定的掩模乘以了场景的光线。而后,反射的光线通过透镜汇聚到单个光电传感器上,形成一个测量信号。
这里左图显示了一个微镜面设备上的两个小镜面,它们分别以不同的角度倾斜,而右图则用一只蚂蚁腿来展示了微镜面上的镜面的尺寸。
SPC重建图像依然基于图中所示的压缩成像的重建原理,作者利用了空域梯度的稀疏性作为先验条件。
但仅仅利用SPC的测量值和基本的空域稀疏性,在重建动态场景时会出现各种各样的问题。 如图所示,如果只是利用短时间内的测量值,结果图像的质量很差,而利用了太长时间的测量值,结果又会模糊。
2015年Aswin C. Sankaranarayanan等提出了一种叫做CS-MUVI的方法,能高效的利用到时域和空域两方面的稀疏性信息,得到更好的重建结果。
CS-MUVI能得到当时在SPC重建方面的SOTA结果,这里展示了一个128x128的短视频,是由16384个测量值重建出的61帧128x128的图像,整个系统的压缩比是61:1。
然而,SPC的缺点也很明显,由于DMD的切换频率远低于ADC的工作频率,因此成为了整个系统的瓶颈,一般在10kHz左右。也就是说,每秒钟大概能获得10000个测量值——这使得短时间采集的数据不足以重建更高分辨率的视频。 这也是为什么前面的SOTA结果的分辨率也只是在128x128。
为了能够提升整个系统在固定时间内的测量值数量,一个很自然的想法就是用多个像素来取代原来的单像素,比如用像素阵列来取代单像素。
这里图中用F代表像素的个数,于是整个系统的采样率可以用 表示。由于之前介绍的,非可见光的传感器像素是非常昂贵的,我们又希望F的数量是最少的——因此F的数量需要使得采集的模拟信号量刚好能够使得ADC达到最大利用率,即 ,因此 。通常这个数量是非常少的,大概1000个像素左右。
这类方法中,典型的就是Wang Jian等提出的LiSens,他们将多个像素组成了线状的传感器,并用一个柱状镜来使得每个像素能看到DMD中的一行。
作者为了简化系统设计,对DMD采用了每一行相同的编码,并利用最后传感器上采集的信号来重建原始图像。当重建单帧图像时,这里主要是利用了空间梯度的稀疏性,并利用二维全变分方法来重建原始信号。
当需要重建视频时,作者利用了多组读出信号(每组测量M次),并利用视频的时空梯度稀疏性来重建视频帧。重建时用了3D全变分技术。这个方法的缺点是重建高速运动的场景时有模糊感。
这是LiSens的原型设计,其中作者还加入了一个SPC,用于对比。这个系统总的采样频率达到了1MHz
接下来,我们比较LiSens和SPC在相同捕获持续时间下获得的重建结果。捕获持续时间很重要,因为它对应于该设备的时间分辨率。捕获持续时间越短,设备的帧速率越高,最终目标就是尽可能缩短捕获持续时间。
作者对SPC的参数进行了优化,以在给定的捕获持续时间内获得可能的最佳重构。尽管如此,SPC的低测量速率仅提供低空间分辨率的重建。相比之下,LiSens即使在较低的捕获持续时间下也能提供高质量的重建。
这是用LiSens和视频压缩感知技术重构的视频。这个视频达到了空间分辨率1024*768, 9fps。
除了像LiSens这样的线状传感器设计,也有块状传感器形式的设计,但总体来说都是利用了压缩传感的技术,实现了光学超分辨率。因此如下的规则依然是成立的:
参考资料
本文同步发表在我的微信公众号和知乎专栏“计算摄影学”,欢迎扫码关注,转载请注明作者和来源
我爸妈,庸医的最高境界。
我爸,南大生物系毕业,正高,研究方向是香烟烟气致癌性,然后每天一包烟。
我妈,上医大公共卫生系毕业,副高,研究方向是各类食品添加剂。目前三高,关键还不肯吃药,看着那高高的血糖,我担心的要死。对了,满满一箱的零食,高油高糖的那种。
家庭2个洁癖我从小生活在无菌中,结果抵抗力很差,经常感冒发烧或者拉肚子,2个教授会说看医生吃药没用,叫我多睡觉多喝热水,拉肚子拉干净饿2天就好了。
感觉学医的的确是挺无情的,看生死很淡薄,小时候有点伤心。