简体   繁体   中英

How to get the bounding box of regions excluding specific RGB values

I am currently using PIL.Image.Image.getbbox() to get the bounding box for the non-zero (non-transparent) regions of an image.

What if I have an image that has a background of a specific color? How can I get the bounding box of the image then? Same idea as getbbox() but instead of non-zero, I specify the RGB values.

I'm afraid, my comment didn't properly express, what I wanted to suggest. So, here's a full answer:

  • Make a copy of your image (that one, that has a specific background color).
  • On that copy, replace the specific background color with black.
  • Call getbbox on that copy.

Maybe, the following code and examples make things more clear:

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())

There's one image with black background:

黑色背景

The corresponding output of getbbox is:

(40, 40, 381, 331) 

Also, there's an image with a specific background color (yellow):

黄色背景

Calling getbbox on that image – obviously – returns:

(0, 0, 400, 400) 

By simply replacing yellow with black in some copy of the second image, we again get the correct results from getbbox (both proposed methods):

(40, 40, 381, 331) 

(40, 40, 381, 331)

Since iterating single pixels in Pillow is kinda slow, you could also use NumPy's vectorization abilities to speed up that task.

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
NumPy:         1.19.5
Pillow:        8.1.0
----------------------------------------

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM