参考资料:
据百度百科的介绍,图像美化是一个比较宽泛的概念,凡是用计算机对图像进行分析,达到所需的效果;换句话说,利用计算机对图像信息进行加工以满足人的视觉心理或者应用需求的行为,就可以被称为图像美化。常见的处理有图像数字化、图像编码、图像增强、图像复原、图像分割和图像分析等,综合称之为图像美化。我们这里主要介绍图像的增强美化。
图像增强美化也包括很多的方面,基本的图像处理方法有例如增加对比度,去掉模糊和噪声,修正几何畸变等,也有图片滤镜,超分辨率等技术。
传统的图像增强可以分为两大类,分别是频率域法和空间域法。
前者把图像看成一种二维信号,对其进行基于二维傅里叶变换的信号增强。采用低通滤波(即只让低频信号通过)法,可去掉图中的噪声;采用高通滤波法,则可增强边缘等高频信号,使模糊的图片变得清晰。
后者空间域法中具有代表性的算法有局部求平均值法和中值滤波(取局部邻域中的中间像素值)法等,它们可用于去除或减弱噪声。
在图像增强过程中,不分析图像降质的原因,处理后的图像不一定逼近原始图像。图像增强技术根据增强处理过程所在的空间不同,可分为基于空域的算法和基于频域的算法两大类。
空域法是对图像中的像素点进行操作,用公式描述如下:
g ( x , y ) = f ( x , y ) ∗ h ( x , y ) g(x,y)=f(x,y) * h(x,y) g(x,y)=f(x,y)∗h(x,y)
其中是f(x,y)是原图像;h(x,y)为空间转换函数;g(x,y)表示进行处理后的图像。
基于空域的算法处理时直接对图像灰度级做运算,基于频域的算法是在图像的某种变换域内对图像的变换系数值进行某种修正,是一种间接增强的算法。
基于空域的算法分为点运算算法和邻域去噪算法。
点运算算法即灰度级校正、灰度变换和直方图修正等,目的或使图像成像均匀,或扩大图像动态范围,扩展对比度。
邻域增强算法分为图像平滑和锐化两种。
平滑一般用于消除图像噪声,但是也容易引起边缘的模糊。常用算法有均值滤波、中值滤波。锐化的目的在于突出物体的边缘轮廓,便于目标识别。常用算法有梯度法、算子、高通滤波、掩模匹配法、统计差值法等。
大多数的增强美化方法都可以使用传统图像处理方法进行实现,也有使用深度学习方法实现的图片增强和超分辨率技术。
图像滤镜特指对图像本身加一些特效,以满足人的视觉需求。最初滤镜是指安装在相机镜头前过滤自然光的附加镜头,用来实现调色和添加效果。而我们现在在软件应用中所看到的滤镜,是我们使用软件技术对真实滤镜的一种模拟实现而已。一般地,图像滤镜可由多种传统处理方法构成,也可以通过DL方法进行实现。
按照实现方法的不同,图像滤镜可以被分为LUT滤镜和几何滤镜;
这两种方法的传统实现均是基于一些规则,或是特定的算法。
DL在很大程度上也可以实现,甚至超越传统方法的滤镜效果。
有很多的滤镜效果可以通过设定不同的卷积核(算子),对图像进行卷积操作实现,诸如模糊,高斯模糊,锐度增强,细节,轮廓,边界提取,边界增强,平滑,浮雕等滤镜效果均是由不同的卷积核对原图进行卷积操作实现的[1]。
列举一些常用的滤镜卷积核:
# https://github.com/python-pillow/Pillow/blob/5.1.x/src/PIL/ImageFilter.py
# 模糊-blur
scale = 16
offset = 0
1, 1, 1, 1, 1
1, 0, 0, 0, 1
1, 0, 0, 0, 1
1, 0, 0, 0, 1
1, 1, 1, 1, 1
# 轮廓-contour
scale = 1
offset = 255
-1, -1, -1
-1, 8, -1
-1, -1, -1
# 细节-detail
scale = 6
offset = 0
0, -1, 0
-1, 10, -1
0, -1, 0
彩色图像转灰度图传统的方法有分量法,最大值法,平均值法以及加权平均法2。这些方法有一些局限性,由此产生的灰度图可能会丢失对比度。
《Contrast Preserving Decolorization》这篇文章提出的算法可以对图片进行去色,但保留了对比度,opencv3.0+有对该方法的实现[python] cv2.decolor
。下面是效果:
code:
import cv2
%matplotlib inline
import matplotlib.pyplot as plt
im = cv2.imread('/Users/wuyanxue/Desktop/test_org.jpg')
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
plt.imshow(im)
plt.show() # 左上
# im_gray1 = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
im_gray1 = 0.299 * im[:, :, 0] + 0.578 * im[:, :, 1] + 0.114 * im[:, :, 2]
im_gray1 = np.dstack([im_gray1, im_gray1, im_gray1])
plt.imshow(im_gray1)
plt.show() # 右上图,加权平均的方法
im_de_col, _ = cv2.decolor(im)
im_gray = np.dstack([im_de_col, im_de_col, im_de_col])
plt.imshow(im_gray)
plt.show() # 左下
# CLAHE and to gray
import albumentations as A
import random
random.seed(42)
image = cv2.imread('./images/test_org.jpg')
light = A.Compose([
A.RandomBrightnessContrast(p=1),
A.RandomGamma(p=1),
A.CLAHE(p=1),
], p=1)
image_enh = light(image=image)['image']
image_enh = cv2.cvtColor(image_enh, cv2.COLOR_BGR2RGB)
image_enh = cv2.cvtColor(image_enh, cv2.COLOR_RGB2GRAY)
im_gray = np.dstack([image_enh, image_enh, image_enh])
plt.imshow(im_gray)
plt.show() # 右下
左上是原图,右上是传统的RGB加权平均得到的结果,左下是采用对比度保留的去色算法得到的结果,右下是对图像先采用增强方法(对比度提升,Gamma矫正,CLAHE),然后灰度化。可以看到,尽管我们先对图像做了增强,然后灰度化,效果也不及decolor的效果。
[4]这篇博文介绍了很多滤镜效果的原理和C#实现过程,主要包含如下滤镜效果:
LUD: 1. Brannan 2. Toaster 3. Hudson 4. 暴雨 5. 大雪 6. 大雾 7. 连环画 8. 暗调 9. 怀旧 10. 老照片 11. 交叉冲印 12. 漏光 13. 漫画 14. LOMO 15. Glow 16. 1977 17. 素描 18. 水彩画 19. 光照效果 20. 油画 21. Swirl 22. Wave 23. 旋转模糊 24. 霓虹 25. 浮雕 26. 木刻 27. 乐高拼图 28. 磨皮。
几何: 1. 球面 2. 挤压。
[x]这篇博文给出了实现多种滤镜效果(但不是全部,有些特别的滤镜效果需要多张图层堆叠)的简易方法,即找到滤镜的对应色卡(可以将原始色卡放入美图软件得到对应滤镜的色卡),然后进行像素级的颜色替换即可。对于某一些简单的滤镜效果,这种方法会比较方便快捷。但这种方法基本上不适用于卷积滤镜,因为卷积滤镜考虑到的不是单个像素的映射,而是一个区域里面的像素集合。
[x]这里也给出了一个所谓万能滤镜的破解方法:
对于一款滤镜,我们构建一个模板,这个模板大小自定,可以看到滤镜效果即可,比如Instagram,它指定的图像大小是530 * 530,那么我们构建一个530 * 530大小的空白模板图像,假如我们要破解Hudson效果,那么,经过 我们分析,这个效果不仅包括基本变换,而且还有 晕影 ,甚至有 与位置相关的梯度模板,这个是破解的 难点,如何 破解,我们可以使用如下步骤:
1,构建256个530 * 530大小的模板,分别填充0-255种颜色,即灰度颜色;
2,将每个模板 进行Hudson效果处理,得到相应的映射模板库,这个库也就记录了所有的Hudson效果设置,包括基本变换,晕影,梯度等;
3,对于任何一张530 * 530大小的原始图像,我们只要从2中的模板库中找到对应颜色,对应位置的像素值,那么 这个值就是Hudson的效果;
这里提到构建256个灰度level,依次做滤镜,得到256个滤镜像素映射表,但很显然,如果是彩色图像,需要的是RGB三个通道值的映射。灰度level显然是不行的
[x]这篇博文采用CNN,搭建了4层卷积,也同样实现了彩色图像decolor的效果。
[x]这个git项目用DL方法实现了图像增强的方法,它针对图片不同的属性:灯光,颜色,纹理,对比度,清晰度这几个方面,用4种不同的损失函数来描述这些属性。
颜色损失:预测图像和目标图像模糊版本之间的欧几里得距离。
纹理损失:基于生成对抗网络(GAN)的分类损失。GAN 被训练来预测灰度照片质量的高低。由于使用了灰度图,网络将很好地聚焦于图像的纹理,而不是颜色。
内容损失:预测图像的 VGG 特征与地面真像之间的差异。这一损失确保了图像中的对象(即图像语义)和整体结构保持不变。
总变化损失:图像中的垂直和水平总梯度。这将增强图像的平滑度,这样最终得到的图像就不会太粗糙或有噪音。
最后将这些损失相加生成一个end-to-end的网络,通过训练来做预测。下面是一些效果,感觉还可以,这个方法的优势在于综合了图像增强的几个方面,灯光,颜色,纹理,对比度等等。
之前我们简介了传统的图像增强方法,本小节列举了一些具体的彩色图像增强方法。传统的图像增强方法有诸如:对比度伸展,直方图均衡化,Gamma矫正,限制对比度适应直方图均衡化(CLAHE),2012这篇文章提到上述方法的表现不是特别好(度量:RMSE, PSNR, MAE),而另外一些传统方法诸如Retinex,同态滤波(Homomorphic filter),小波多尺度变换(Wavelet multiScale transform)效果良好。我对这些传统方法做了一些彩色图像增强的测试。实际上在上面的程序中已经用到了图像增强的方法,选用的工具为albumentations
这个库。
下面是代码
# image_url = http://people.ee.ethz.ch/~ihnatova/demo/iphone/0_0.jpg
# image_url = http://people.ee.ethz.ch/~ihnatova/demo/iphone/1_0.jpg
import albumentations as A
import random
random.seed(42)
image = cv2.imread('./images/0_0.jpg')
plt.imshow(image)
plt.show() # 上面左图
# 下面这段代码可能需要运行多次才能得到图示效果
light = A.Compose([
A.RandomBrightnessContrast(p=1, brightness_limit=0.5, contrast_limit=0.3),
A.RandomGamma(p=1),
A.CLAHE(p=1),
], p=1)
image_enh = light(image=image)['image']
image_enh = cv2.cvtColor(image_enh, cv2.COLOR_BGR2RGB)
plt.imshow(image_enh)
plt.show() # 上面右图
总体上感觉这个增强比起DL的方法还是要差了一些,右下图的结果丢失了一些色彩信息,但DL可以保留这种色彩。另外,传统方法的参数不易调节,针对不同的图像可能需要不同的参数才能达到比较良好的效果。
albumentation
这个库提供了很多有关图像的预处理方法,其中包括很多图像增强技术,特别是很多方法不仅会提供图像本身的处理方法,还会提供和object detection, image segmentation, landmark localization等任务相关的图像-label联动变换方法。
详情可参见:https://github.com/albu/albumentations