Python – 移除图像的一部分
移除图像的一部分是指在图像的某些区域破坏图像数据的过程。去除可以是动态的,也可以是硬编码的。在大多数移除过程中,图像的尺寸在结果图像中保持不变。从字面上看,从图像中删除的部分将以无法解释的方式改变尺寸。在这篇文章中,我们将看看如何去除图像的某一区域,并了解不同的方法。
为什么要从图像中删除一个区域
有时,图像中含有某些人工制品(不规则)或不需要的区域,可能是不受欢迎的。一旦这些区域被识别出来,那么确定它们的类型是必要的,这将有助于想出摆脱它们的最佳方法。大多数图像处理软件包,如Photoshop、Gimp等,都提供了执行这一特定任务的工具。但这也可以通过编程来完成,我们一会儿就会看到。下面的图片将被用于演示。
示例 1:
从图像中删除一个部分(区域)需要事先提供感兴趣的区域。每次进行处理时提供ROI意味着ROI是硬编码的。而ROI本身的计算(_随着不同的图像和条件而相应改变)意味着ROI是动态的。ROI通常是一个大小为4的元组,包含Bbox的左上和右下坐标。
移除一个区域意味着我们首先选择我们愿意移除的区域。选择可以是基于区域或像素值。一旦区域被确定,我们将把该区域的像素值变成背景的像素值。背景颜色不是恒定的,因此取决于图像的使用环境。最常见的背景是白色或黑色。在这篇文章中,我们将假设背景颜色是黑色。为了证明这一点,我们将删除上述图像的(0,0)至(400,400)(左上角)区域的像素。
以下是实现情况:
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()
输出:
移除图像的左上角区域
解释:
首先,我们导入了PIL图像库和Numpy模块,这将允许我们将同质的像素值存储为数组,这反过来又导致了对它们更快的操作。然后我们使用Image.open()函数打开图像(创建图像对象),随后将图像转换为RGB颜色模式(最初是RGBA)。之后,我们使用np.array()函数从图像数据中创建了一个Numpy数组。后来,我们利用索引切片将(0, 0)-(400, 400)区域的像素值变成黑色(0, 0, 0)。最后,我们用Image.fromarray()函数从修改后的像素数据中创建了一个图像并显示出来。
例子2:删除具有rgba颜色模式的图像区域
如果一个图像是RGBA颜色模式,那么被移除的区域就不需要用颜色值来表示(就像前面的情况)。我们可以让被移除的区域显示为完全透明(alpha为0)。这不仅可以达到将该区域从最终图像中移除的目的(或者说是消失),而且还可以提供一个该区域不存在的像素的视觉提示。为了证明这一点,我们将使用以下图片:-
我们将去除图像中被黑色填充的区域。由于该区域不能被描述为一个形状,我们将使用floodfill函数用透明的像素值来填充该区域。在下面的例子中,我们将使用品红色的颜色值作为泛滥填充算法的种子,并使用它来获得完全透明的像素值。
以下是实现情况:
# 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)。我们在上面的代码中所做的是。
1.首先找出由黑色组成的最长的连续区域(使用洪水/种子填充算法来做)。
2.将该区域的颜色值改为(0, 0, 0, 0)(全透明)。