📜  使用Python创建一个小插图过滤器 – OpenCV

📅  最后修改于: 2022-05-13 01:55:35.558000             🧑  作者: Mango

使用Python创建一个小插图过滤器 – OpenCV

一般来说,计算机中的图像是以矩阵的形式存储的。在彩色图像的情况下,图像以3 维矩阵的形式表示,或者可以说我们使用三个 2d 矩阵来表示三个颜色通道,一个 2d 矩阵用于表示红色通道,一个用于绿色通道,一个用于表示蓝色通道。在灰度图像的情况下,存在单个通道,因此我们使用单个 2d 矩阵来表示灰度图像。

每当我们说内核或蒙版时,我们通常指的是一个小尺寸矩阵,可用于对我们的图像应用效果,例如模糊浮雕边缘检测锐化等,逐像素应用这些效果的过程称为卷积.

为了想象卷积是如何工作的,让我们考虑尺寸为 3×3 的内核,并考虑尺寸为 9×9 的图像矩阵,如图所示。现在我们在图像矩阵中选择 3×3(与内核大小相同)的像素块,并将图像中选择的块与我们的内核相乘,然后求和。作为结果获得的总和成为我们的新像素值,该像素值的位置是中心位置,如图中蓝色所示。为了获得完整的过滤图像,我们在图像矩阵上逐像素滚动内核矩阵,并在循环中执行此过程。

什么是晕影滤镜?

晕影滤镜通常用于将观众的注意力集中在图像的某些部分上,而不会完全隐藏其他部分。一般聚焦的部分具有较高的亮度和饱和度,而当我们从中心向外径向外围时,亮度和饱和度会降低。

如何创建和应用过滤器?

由于我们希望将图像的亮度和饱和度保持在中心正常,并在我们从图像中心径向向外移动时尝试减少这种情况,因此我们应该使用分配函数,为最近的像素分配比像素更多的权重这很远。这是我们将使用高斯分布的主要原因,因为我们知道在高斯分布中,大多数值实际上接近于零且不为零。所以我们将创建一个足够大的面具。为了创建二维高斯函数,我们将创建两个一维高斯函数并将这两个函数相乘。一个属于 X 方向,另一个属于 Y 方向。由于我们当前的内核矩阵尺寸很大,因此我们将进行归一化以减小内核尺寸,否则应用过滤器的成本将太大。

OpenCV 提供了一个名为getGaussianKernel的函数,我们将使用它来构建大小与图像大小匹配的 2D 内核。

getGaussianKernel函数

函数的第一个参数即ksize:决定内核的大小,我们通常更喜欢奇数,正值。函数的第二个参数,即sigma :是高斯的标准偏差,它控制明亮中心图像的半径。该函数计算并返回第一个参数中分配的大小的矩阵,并包含高斯滤波器系数

Mask = (scale size) * (Normalized kernel matrix )

创建蒙版后,我们将遍历所有颜色通道并将蒙版应用于每个通道。缩放是一个重要的步骤,否则在您将蒙版叠加到图像上后,所有像素值都接近于 0,图像将看起来是黑色的。
下面是实现。

Python3
import numpy as np
import cv2
   
     
#reading the image
input_image = cv2.imread('food.jpeg')
   
#resizing the image according to our need
# resize() function takes 2 parameters, 
# the image and the dimensions
input_image = cv2.resize(input_image, (480, 480))
   
# Extracting the height and width of an image
rows, cols = input_image.shape[:2]
   
# generating vignette mask using Gaussian
# resultant_kernels
X_resultant_kernel = cv2.getGaussianKernel(cols,200)
Y_resultant_kernel = cv2.getGaussianKernel(rows,200)
   
#generating resultant_kernel matrix
resultant_kernel = Y_resultant_kernel * X_resultant_kernel.T
   
#creating mask and normalising by using np.linalg
# function
mask = 255 * resultant_kernel / np.linalg.norm(resultant_kernel)
output = np.copy(input_image)
   
# applying the mask to each channel in the input image
for i in range(3):
    output[:,:,i] = output[:,:,i] * mask
       
#displaying the original image  
cv2.imshow('Original', input_image)
   
#displaying the vignette filter image
cv2.imshow('VIGNETTE', output)
   
# Maintain output window utill
# user presses a key
cv2.waitKey(0)
   
# Destroying present windows on screen
cv2.destroyAllWindows()


输出: