如何获取排除特定RGB值的区域边界框
How to get the bounding box of regions excluding specific RGB values
我目前正在使用 PIL.Image.Image.getbbox()
获取图像非零(非透明)区域的边界框。
如果我的图像具有特定颜色的背景怎么办?那我怎样才能得到图像的边界框呢?与 getbbox()
相同的想法,但我指定了 RGB 值而不是非零值。
恐怕,我的评论没有正确表达我想建议的内容。所以,这是一个完整的答案:
- 复制您的图像(具有特定背景颜色的图像)。
- 在该副本上,将特定背景颜色替换为黑色。
- 对该副本调用
getbbox
。
也许,下面的代码和例子会让事情更清楚:
import numpy as np
from PIL import Image, ImageDraw
# Black background
img = Image.new('RGB', (400, 400), (0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle((40, 40, 160, 160), (255, 0, 0))
draw.rectangle((280, 260, 380, 330), (0, 255, 0))
img.save('black_bg.png')
print(img.getbbox(), '\n')
# Specific color background
bg_color = (255, 255, 0)
img = Image.new('RGB', (400, 400), bg_color)
draw = ImageDraw.Draw(img)
draw.rectangle((40, 40, 160, 160), (255, 0, 0))
draw.rectangle((280, 260, 380, 330), (0, 255, 0))
img.save('color_bg.png')
print(img.getbbox(), '\n')
# Suggested color replacing (on image copy) - Pillow only, slow
img_copy = img.copy()
for y in range(img_copy.size[1]):
for x in range(img_copy.size[0]):
if img_copy.getpixel((x, y)) == bg_color:
img_copy.putpixel((x, y), (0, 0, 0))
print(img_copy.getbbox(), '\n')
# Suggested color replacing (on image copy) - NumPy, fast
img_copy = np.array(img)
img_copy[np.all(img_copy == bg_color, axis=2), :] = 0
print(Image.fromarray(img_copy).getbbox())
有一张黑色背景的图片:
getbbox
对应的输出为:
(40, 40, 381, 331)
此外,还有一张图片具有特定的背景颜色(黄色):
在那张图片上调用 getbbox
– 显然 – returns:
(0, 0, 400, 400)
通过简单地将第二张图片的某些副本中的黄色替换为黑色,我们再次从 getbbox
中得到正确的结果(两种建议的方法):
(40, 40, 381, 331)
(40, 40, 381, 331)
由于在 Pillow 中迭代单个像素有点慢,您还可以使用 NumPy 的矢量化能力来加速该任务。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.5
NumPy: 1.19.5
Pillow: 8.1.0
----------------------------------------
我目前正在使用 PIL.Image.Image.getbbox()
获取图像非零(非透明)区域的边界框。
如果我的图像具有特定颜色的背景怎么办?那我怎样才能得到图像的边界框呢?与 getbbox()
相同的想法,但我指定了 RGB 值而不是非零值。
恐怕,我的评论没有正确表达我想建议的内容。所以,这是一个完整的答案:
- 复制您的图像(具有特定背景颜色的图像)。
- 在该副本上,将特定背景颜色替换为黑色。
- 对该副本调用
getbbox
。
也许,下面的代码和例子会让事情更清楚:
import numpy as np
from PIL import Image, ImageDraw
# Black background
img = Image.new('RGB', (400, 400), (0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle((40, 40, 160, 160), (255, 0, 0))
draw.rectangle((280, 260, 380, 330), (0, 255, 0))
img.save('black_bg.png')
print(img.getbbox(), '\n')
# Specific color background
bg_color = (255, 255, 0)
img = Image.new('RGB', (400, 400), bg_color)
draw = ImageDraw.Draw(img)
draw.rectangle((40, 40, 160, 160), (255, 0, 0))
draw.rectangle((280, 260, 380, 330), (0, 255, 0))
img.save('color_bg.png')
print(img.getbbox(), '\n')
# Suggested color replacing (on image copy) - Pillow only, slow
img_copy = img.copy()
for y in range(img_copy.size[1]):
for x in range(img_copy.size[0]):
if img_copy.getpixel((x, y)) == bg_color:
img_copy.putpixel((x, y), (0, 0, 0))
print(img_copy.getbbox(), '\n')
# Suggested color replacing (on image copy) - NumPy, fast
img_copy = np.array(img)
img_copy[np.all(img_copy == bg_color, axis=2), :] = 0
print(Image.fromarray(img_copy).getbbox())
有一张黑色背景的图片:
getbbox
对应的输出为:
(40, 40, 381, 331)
此外,还有一张图片具有特定的背景颜色(黄色):
在那张图片上调用 getbbox
– 显然 – returns:
(0, 0, 400, 400)
通过简单地将第二张图片的某些副本中的黄色替换为黑色,我们再次从 getbbox
中得到正确的结果(两种建议的方法):
(40, 40, 381, 331)
(40, 40, 381, 331)
由于在 Pillow 中迭代单个像素有点慢,您还可以使用 NumPy 的矢量化能力来加速该任务。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.5
NumPy: 1.19.5
Pillow: 8.1.0
----------------------------------------