Python - 删除图像的一部分
去除图像的一部分是指破坏图像某些区域中的图像数据的过程。删除可以是动态的,也可以是硬编码的。在大多数移除过程中,图像的尺寸在生成的图像中保持不变。从字面上删除图像中的部分会以无法解释的方式改变尺寸。在本文中,我们将研究去除图像区域的方法,并将了解这样做的不同方法。
为什么要从图像中删除一个区域?
有时,图像中包含某些可能不受欢迎的伪影(不规则性)或不需要的区域。一旦识别出这些区域,就需要识别它们的类型,这将有助于找到摆脱它们的最佳方法。大多数图像处理包,如 Photoshop、Gimp 等,都提供了执行特定任务的工具。但这也可以通过编程方式完成,我们稍后会看到。下图将用于演示。
示例 1:
从图像中移除部分(区域)需要事先提供感兴趣的区域。每次处理过程都提供 ROI 意味着 ROI 是硬编码的。而 ROI 的计算本身(随着不同的图像和条件而相应变化)意味着 ROI 是动态的。 ROI 通常是一个大小为 4 的元组,其中包含 Bbox 的左上角和右下角坐标。
删除区域意味着我们首先选择我们愿意删除的区域。其中选择可以是基于区域或像素值的。一旦确定了区域,我们将把该区域的像素值转换为背景的像素值。背景颜色不是恒定的,因此取决于要使用图像的上下文。最常见的背景是白色或黑色。在本文中,我们将假设背景颜色为黑色。为了证明这一点,我们将删除上述图像的 (0,0) 到 (400, 400)(左上角)区域中的像素。
下面是实现:
Python3
from PIL import Image
import numpy as np
# Opening the image and converting
# it to RGB color mode
# IMAGE_PATH => Path to the image
img = Image.open(r"IMAGE_PATH").convert('RGB')
# Extracting the image data &
# creating an numpy array out of it
img_arr = np.array(img)
# Turning the pixel values of the 400x400 pixels to black
img_arr[0 : 400, 0 : 400] = (0, 0, 0)
# Creating an image out of the previously modified array
img = Image.fromarray(img_arr)
# Displaying the image
img.show()
Python3
# Importing ImageDraw for
# using floodfill function
from PIL import Image, ImageDraw
# Opening the image and
# converting its type to RGBA
img = Image.open(r"IMG_PATH").convert('RGBA')
# Location of seed
seed = (0, 0)
# Pixel Value which would
# be used for replacement
rep_value = (0, 0, 0, 0)
# Calling the floodfill() function and
# passing it image, seed, value and
# thresh as arguments
ImageDraw.floodfill(img, seed, rep_value, thresh = 100)
img.show()
输出:
解释:
首先,我们导入了 PIL 图像库和 Numpy 模块,这将允许我们将同质像素值存储为数组,从而加快对它们的操作。然后我们使用Image.open()函数打开图像(创建的图像对象),然后将图像转换为 RGB 颜色模式(最初是 RGBA)。之后,我们使用np.array()函数从图像数据中创建了一个 Numpy 数组。后来我们利用索引切片将区域 (0, 0) – (400, 400) 的像素值变为黑色 (0, 0, 0)。最后,我们使用Image.fromarray()从修改后的像素数据创建了一个图像并显示它。
示例 2:删除具有 rgba 颜色模式的图像区域
如果图像是 RGBA 颜色模式,则不需要使用颜色值来表示移除的区域(如前一种情况)。我们可以使移除的区域看起来完全透明(alpha 0)。这不仅用于从最终图像中删除该区域(或某种消失),而且还提供该区域中不存在像素的视觉提示。为了证明这一点,将使用以下图像:-
我们将删除图像中填充黑色的区域。由于该区域不能被描述为形状,我们将使用洪水填充函数来用透明像素值填充该区域。在下面的示例中,我们将使用洋红色值作为填充算法的种子,并使用它来获得完全透明的像素值。
下面是实现:
蟒蛇3
# Importing ImageDraw for
# using floodfill function
from PIL import Image, ImageDraw
# Opening the image and
# converting its type to RGBA
img = Image.open(r"IMG_PATH").convert('RGBA')
# Location of seed
seed = (0, 0)
# Pixel Value which would
# be used for replacement
rep_value = (0, 0, 0, 0)
# Calling the floodfill() function and
# passing it image, seed, value and
# thresh as arguments
ImageDraw.floodfill(img, seed, rep_value, thresh = 100)
img.show()
输出:
看起来好像图像中的黑色被白色替换了。但是白色实际上是背景的颜色,该区域的像素是完全透明的(alpha = 0)。我们在上面的代码中所做的是:
- 首先找出由黑色组成的最长连续区域(使用洪水/种子填充算法来做到这一点)
- 将该区域的颜色值更改为 (0, 0, 0, 0)(完全透明)