1 图像采样和量化

1 图像采样和量化

一、采样

1.1 上采样

上采样会遇到的问题: 新的大图像中会有一些像素在原来的小图像中没有对应的像素

解决办法: 猜测像素的值

具体方法:(1)聚合值,例如它最近一个或多个像素邻域值的平均值;

​ (2)使用双线性或三次插值的像素邻域的内插值。

1.1.1 最近邻法上采样

代码如下:

from PIL import Image
import matplotlib.pylab as pylab


im = Image.open(r'.../1.jpg')  # 绝对路径
im1 = im.resize((im.width*5, im.height*5), Image.NEAREST)
pylab.figure(figsize=(10, 10)), pylab.imshow(im1), pylab.show()

最近邻上采样方法计算量小,但可能会造成插值生成的图像灰度上不连续,在灰度变化的地方带有方块效应或出现明显的锯齿状。

1.1.2 双线性插值法上采样

一个灰度图像,基本上是一个整数网格中像素值的二维矩阵。为了对网格上任意点的像素值进行插值,可以使用类似二维线性插值的方法:双线性插值。在这种情况下,对于每个可能的点(想插值的点),4个邻域点的强度值将被结合起来在插值点处计算插值。

使用PIL库的resize()函数进行双线性插值,代码如下:

from PIL import Image
import matplotlib.pylab as pylab


im = Image.open(r'.../1.jpg')
im1 = im.resize((im.width*5, im.height*5), Image.BILINEAR)
pylab.figure(figsize=(10, 10)), pylab.imshow(im1), pylab.show()

双线性内插法的计算比最邻近点法复杂,计算量较大,但没有灰度不连续的缺点,结果基本令人满意。它具有低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊。

1.1.3 双三次插值法上采样

双三次插值是在二维规则网络上插值数据点的三次插值的扩展。插值曲面比双线性插值或最邻近插值得到的相应曲面光滑。双三次插值可以使用拉格朗日多项式、三次样条或三次卷积算法来完成。PIL在4*4环境下使用三次样条插值。

使用PIL库的resize()函数来进行双三次插值,代码如下:

from PIL import Image
import matplotlib.pylab as pylab


im = Image.open(r'.../1.jpg')
im1 = im.resize((im.width*5, im.height*5), Image.BICUBIC)
pylab.figure(figsize=(10, 10)), pylab.imshow(im1), pylab.show()

三次曲线插值方法计算量较大,但插值后的图像效果最好。

1.2 下采样

要缩小图像的尺寸,应对图像进行下采样。对于新的缩小图像中的每个像素,其中很多都源自原来的大图像。可以通过以下步骤:

(1)一系统的方式从较大图像中删除一些像素(例如,如果希望得到的图像大小是原始图像的1/4,可以每隔一行和每隔一列删除)

(2)计算新的像素值并将其作为原始图像中相应多个像素的聚合值。

1.2.1 系统方式删除像素

使用PIL库中的resize()函数将其大小调整为输入图像的1/25,将输入图像的宽度和高度分别设置为原来图像宽度和高度的1/5,只需从输入图像中选择每5行中的一行和每5列中的一列,代码如下所示:

from PIL import Image
import matplotlib.pylab as pylab


im = Image.open(r'.../1.jpg')
im1 = im.resize((im.width//5, im.height//5))
pylab.figure(figsize=(10, 10)), pylab.imshow(im1), pylab.show()

经过处理后的图像中存在一些原始图像中没有的黑色斑点或伪影——我们将其称之为混叠

发生混叠是因为采样率比奈奎斯特速率小(像素太少了的缘故)。因此避免混叠的另一种方法是增加采样率,使其大于奈奎斯特速率。

1.2.2 抗混叠

系统方式删除像素的方法由于输出图像中的一个像素对应于输入图像中的25个像素,而其只能对图像中的某一单个像素值进行采样,因此,应该采取对输入图像中的一小块区域求平均,并将平均值作为采样值的方法。

(1)通过PIL库中的ANTIALIAS(一个高质量的下采样滤波器)来实现,代码如下:

from PIL import Image
import matplotlib.pylab as pylab


im = Image.open(r'.../1.jpg')
im1 = im.resize((im.width//5, im.height//5), Image.ANTIALIAS)
pylab.figure(figsize=(10, 10)), pylab.imshow(im1), pylab.show()

此时生成的图像质量更好,几乎没有任何伪影/混叠效果。

抗混叠通常是在向下采样之前通过平滑图像(通过图像与低通滤波器的卷积,如高斯滤波器)来完成的。

(2)可使用scikit-image变换模块的具有抗混叠效果的rescale()函数来解决混叠问题,代码如下:

不使用抗混叠:

from skimage.io import imread
import matplotlib.pylab as pylab
from skimage.transform import rescale


im = imread(r'.../1.jpg')
im1 = im.copy()
pylab.figure(figsize=(10, 10))
for i in range(4):
    pylab.subplot(2, 2, i+1), pylab.imshow(im1, cmap='gray'), pylab.axis('off')
    pylab.title('image size = ' + str(im1.shape[1]) + 'x' + str(im1.shape[0]))
    im1 = rescale(im1, scale=0.5, multichannel=True, anti_aliasing=False)
pylab.subplots_adjust(wspace=0.1, hspace=0.1)
pylab.show()

在不使用抗混叠的情况下,混叠效果明显

使用抗混叠:

将以上代码行改变为使用抗混叠:

im1 = rescale(im1, scale=0.5, multichannel=True, anti_aliasing=True)

对比图:

不使用抗混叠:
在这里插入图片描述

使用抗混叠:

在这里插入图片描述

可以看出,使用抗混叠后,图像更加平滑。

二、量化

量化 与图像的强度有关,可以由每个像素所使用的比特数来定义。数字图像通常被量化到256灰度级。

随着像素存储的比特数的减少,量化误差增大,导致假边界、假轮廓和像素化,从而导致图像质量降低。

PIL量化

使用PIL中Image模块的convert()函数进行颜色量化,其中,选定P模式和颜色参数作为可能颜色的最大数目。使用SciPy中stats模块的signaltonoise()函数来获得图像的信噪比SNR,信噪比是指图像数组的均值除以图像数组的标准差。

代码如下:

from PIL import Image
import numpy as np
import matplotlib.pylab as pylab


def signaltonoise(a, axis, ddof=0):   # scipy1.1中stats模块中的signaltonoise已废除
    a = np.asanyarray(a)
    m = a.mean(axis)
    sd = a.std(axis=axis, ddof=ddof)
    return np.where(sd == 0, 0, m/sd)


im = Image.open(r'.../2.jpg')
pylab.figure(figsize=(30, 45))
num_colors_list = [1 << n for n in range(8, 0, -1)]
snr_list = []
i = 1
for num_colors in num_colors_list:
    im1 = im.convert('P', palette=Image.ADAPTIVE, colors=num_colors)
    pylab.subplot(4, 2, i), pylab.imshow(im1), pylab.axis('off')
    snr_list.append(signaltonoise(im1, axis=None)) # 得到的信噪比为数组时,是因为没有将axis指定为none
    pylab.title('Image with # colors = ' + str(num_colors) + ' SNR = ' + str(np.round(snr_list[i-1], 3)), size=30)
    i += 1
pylab.subplots_adjust(wspace=0.2, hspace=0)
pylab.show()
pylab.subplots_adjust(wspace=0.2, hspace=0)
pylab.show()
pylab.plot(num_colors_list, snr_list, 'r.-')
pylab.xlabel('Max# colors in the image')
pylab.ylabel('SNR')
pylab.title('Change in SNR w.r.t. # colors')
pylab.xscale('log', base=2) # basex has been renamed 'base'
pylab.gca().invert_xaxis()
pylab.show()

得到结果:
在这里插入图片描述
在这里插入图片描述

可以看出,图像质量随着颜色量化变小而降低,这是因为要存储一个像素的比特数少了。
在这里插入图片描述

由得到的颜色量化与图像信噪比之间关系的图形可以看出,若以信噪比来衡量的话,颜色量化虽然缩小了图像尺寸(因为比特/像素的数量减少了),但是也使得图像质量变差了。

注:信噪比越高,图像质量越好,这是衡量图像质量的一种常用方法。 

猜你喜欢

转载自blog.csdn.net/Westbrood/article/details/112847557
今日推荐