龙空技术网

Python图像处理-模糊和锐化

人工智能遇见磐创 696

前言:

眼前各位老铁们对“python图像维数”大约比较注意,兄弟们都需要分析一些“python图像维数”的相关知识。那么小编在网摘上收集了一些有关“python图像维数””的相关知识,希望咱们能喜欢,我们一起来了解一下吧!

在这篇文章中,我们将讨论如何应用模糊和锐化图像。这些基本知识构成了许多更高级应用程序的主干。

我们将讨论如何将这些知识应用到彩色图像上。现在开始吧!

从导入所需的Python库开始。

import numpy as npimport matplotlib.pyplot as pltfrom skimage.io import imshow, imreadfrom skimage.color import rgb2yuv, rgb2hsv, rgb2gray, yuv2rgb, hsv2rgbfrom scipy.signal import convolve2d

我们将使用下图:

dog = imread('fire_dog.png')plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(dog);

现在我们应用到图像的核是高斯模糊核和锐化核。你可以在下面看到如何定义它们的矩阵。

# 锐化sharpen = np.array([[0, -1, 0],                    [-1, 5, -1],                    [0, -1, 0]])                    # 高斯模糊gaussian = (1 / 16.0) * np.array([[1., 2., 1.],                                  [2., 4., 2.],                                  [1., 2., 1.]])                                  fig, ax = plt.subplots(1,2, figsize = (17,10))ax[0].imshow(sharpen, cmap='gray')ax[0].set_title(f'Sharpen', fontsize = 18)    ax[1].imshow(gaussian, cmap='gray')ax[1].set_title(f'Gaussian Blur', fontsize = 18)    [axi.set_axis_off() for axi in ax.ravel()];

但如何将这些核应用到图像中呢?我首先定义了下面的函数来允许我们迭代地处理核。请注意,我们将边界设置为fill,将fillvalue设置为0,这对于确保输出将是一个0填充的矩阵、且其大小与原始矩阵相同非常重要。

def multi_convolver(image, kernel, iterations):    for i in range(iterations):        image = convolve2d(image, kernel, 'same', boundary = 'fill',                           fillvalue = 0)    return image    multi_convolver(dog, gaussian, 2)

似乎我们遇到了一个值错误。为什么会这样?记住,当我们将一个矩阵与另一个矩阵卷积时,矩阵的维数应该相同。这意味着我们不能将2D卷积应用到3D矩阵(因为颜色通道)。为了解决这个问题,我们必须首先将图像转换成灰度。

dog_grey = rgb2gray(dog)plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(dog_grey);

现在如果我们运行这个函数,应该会得到想要的效果。

convolved_image = multi_convolver(dog_grey, gaussian, 2)plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(convolved_image);

我们现在可以看到,图像已经明显模糊了。下面的代码将告诉我们,如果继续对图像运行高斯模糊卷积,图像会发生什么。

def convolution_plotter(image, kernel):    iterations = [1,10,20,30]    f_size = 20        fig, ax = plt.subplots(1,4, figsize = (15,7))    for n, ax in enumerate(ax.flatten()):        ax.set_title(f'Iteration : {iterations[n]}', fontsize =                     f_size)        ax.imshow(multi_convolver(image, kernel, iterations[n]),                   cmap='gray')        ax.set_axis_off()    fig.tight_layout()    convolution_plotter(dog_grey, gaussian)

太好了!由于核的应用,我们可以清楚地看到图像的持续模糊。

但是如果你需要模糊图像并保留颜色呢?让我们首先尝试应用每个颜色通道的卷积。

def convolver_rgb(image, kernel, iterations = 1):    convolved_image_r = multi_convolver(image[:,:,0], kernel,                                        iterations)    convolved_image_g = multi_convolver(image[:,:,1], kernel,                                         iterations)    convolved_image_b  = multi_convolver(image[:,:,2], kernel,                                          iterations)        reformed_image = np.dstack((np.rint(abs(convolved_image_r)),                                 np.rint(abs(convolved_image_g)),                                 np.rint(abs(convolved_image_b)))) /                                 255                                                           fig, ax = plt.subplots(1,3, figsize = (17,10))        ax[0].imshow(abs(convolved_image_r), cmap='Reds')    ax[0].set_title(f'Red', fontsize = 15)        ax[1].imshow(abs(convolved_image_g), cmap='Greens')    ax[1].set_title(f'Green', fontsize = 15)        ax[2].imshow(abs(convolved_image_b), cmap='Blues')    ax[2].set_title(f'Blue', fontsize = 15)        [axi.set_axis_off() for axi in ax.ravel()]        return np.array(reformed_image).astype(np.uint8)    convolved_rgb_gauss = convolver_rgb(dog, gaussian, 2)

这个函数实际上返回给我们经过修改的图像,我们只需要将它插入show函数。

plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(convolved_rgb_gauss);

太好了!看来这个函数运行得很好。看看当我们将图像卷积10次时会发生什么。

所以这解决了问题,对吗?实际上不太对。要了解这个函数的问题,我们尝试锐化图像。

convolved_rgb_sharpen = convolver_rgb(dog, sharpen, 1)

到目前为止看起来不错,让我们看看转换后的图像是什么样子。

图像已经被修改,但我们现在看到有些轻微的扭曲。为什么会这样?

记住,RGB颜色空间隐式地混合了像素的亮度和颜色。这意味着,在不改变颜色的情况下,实际上是不可能在图像的亮度上应用卷积的。那么我们该如何处理这个问题呢?

解决这个问题的一种方法是改变图像的颜色空间。我们可以利用Y'UV颜色空间来代替RGB颜色空间。我们这样做是因为Y'UV空间中的亮度通道实际上是与颜色分离的(这是Y分量)。

出于本文的目的,我们将编辑函数,首先将图像转换为Y'UV颜色空间,然后进行所需的卷积。

def convolver_rgb(image, kernel, iterations = 1):    img_yuv = rgb2yuv(image)       img_yuv[:,:,0] = multi_convolver(img_yuv[:,:,0], kernel,                                      iterations)    final_image = yuv2rgb(img_yuv)                                   fig, ax = plt.subplots(1,2, figsize = (17,10))        ax[0].imshow(image)    ax[0].set_title(f'Original', fontsize = 20)        ax[1].imshow(final_image);    ax[1].set_title(f'YUV Adjusted, Iterations = {iterations}',                     fontsize = 20)        [axi.set_axis_off() for axi in ax.ravel()]        fig.tight_layout()        return final_image    final_image = convolver_rgb(dog, sharpen, iterations = 1)

可以看到,我们的函数现在返回的图像明显更清晰,没有任何颜色失真。有许多其他的方法来解决这个问题与Y'UV转换只是其中之一。记住,HSV颜色空间的V分量表示几乎相同的东西。然而,Y'UV空间的亮度分量和HSV空间的明度分量的方式略有不同。让我们看看用一个替代另一个的后果是什么。

def convolver_comparison(image, kernel, iterations = 1):    img_yuv = rgb2yuv(image)       img_yuv[:,:,0] = multi_convolver(img_yuv[:,:,0], kernel,                       iterations)    final_image_yuv = yuv2rgb(img_yuv)        img_hsv = rgb2hsv(image)       img_hsv[:,:,2] = multi_convolver(img_hsv[:,:,2], kernel,                       iterations)    final_image_hsv = hsv2rgb(img_hsv)                convolved_image_r = multi_convolver(image[:,:,0], kernel,                          iterations)    convolved_image_g = multi_convolver(image[:,:,1], kernel,                          iterations)    convolved_image_b  = multi_convolver(image[:,:,2], kernel,                         iterations)        final_image_rgb = np.dstack((np.rint(abs(convolved_image_r)),                                  np.rint(abs(convolved_image_g)),                                  np.rint(abs(convolved_image_b)))) /                                  255                                   fig, ax = plt.subplots(2,2, figsize = (17,17))        ax[0][0].imshow(image)    ax[0][0].set_title(f'Original', fontsize = 30)        ax[0][1].imshow(final_image_rgb);    ax[0][1].set_title(f'RGB Adjusted, Iterations = {iterations}',                        fontsize = 30)    fig.tight_layout()        ax[1][0].imshow(final_image_yuv)    ax[1][0].set_title(f'YUV Adjusted, Iterations = {iterations}',                        fontsize = 30)        ax[1][1].imshow(final_image_hsv)    ax[1][1].set_title(f'HSV Adjusted, Iterations = {iterations}',                        fontsize = 30)        [axi.set_axis_off() for axi in ax.ravel()]        fig.tight_layout()    convolver_comparison(dog, sharpen, iterations = 1)

我们看到HSV和Y'UV比原始RGB方法有一些轻微的改进。为了更好的说明,我们可以将迭代次数从1增加到2。

在2次迭代中,失真变得更加明显。但是也很明显,HSV和Y'UV调整后的图像比原始的RGB调整后的图像更加平滑。在决定对图像应用卷积核的最佳方法时,应该记住这些属性。

结论

我们学习了如何对图像进行模糊和锐化卷积。这些技术对于任何从事图像处理和计算机视觉领域的数据科学家来说都是至关重要的。

我们了解到,简单地将卷积应用于各个RGB通道可能不是最好的方法。在处理图像时,人们应该意识到有许多不同类型的颜色空间可供处理。希望这篇文章对你有所帮助,并能将其应用到你自己的工作中。

标签: #python图像维数