Вот возможная реализация. Я создал следующие четыре функции:
get_pixels(img)
возвращает словарь, значения которого представляют собой кортежи с компонентами RGB цветов в img
(исключая (0, 0, 0)
), а значения представляют собой списки координат (строка и столбец) пикселей, которые имеют соответствующий цвет. bounding_box(coords)
возвращает координаты диагонально противоположных вершин ограничивающей рамки области изображения, определенной через список координат. is_rectangle(coords)
возвращает True
, если переданный список координат составляет прямоугольник. create_image()
возвращает образец изображения.
def get_pixels(img):
coords = {}
for j in range(len(img[0])):
for i in range(len(img)):
rgb = img[i][j]
if rgb != (0, 0, 0):
pixels[rgb] = pixels.get(rgb, []) + [(i, j)]
return pixels
def bounding_box(coords):
upper = min([i for i,j in coords])
lower = max([i for i,j in coords])
left = min([j for i,j in coords])
right = max([j for i,j in coords])
return upper, lower, left, right
def is_rectangle(coords):
upper, lower, left, right = bounding_box(coords)
for i in range(upper, lower + 1):
for j in range(left, right + 1):
if (i, j) not in coords:
return False
return True
Demo
In [382]: img = create_image()
In [383]: pixels = get_pixels(img)
In [384]: for color, coords in pixels.items(): print(color, coords)
(43, 39, 102) [(2, 1), (3, 1), (4, 1), (5, 1), (2, 2), (3, 2), (4, 2), (5, 2), (2, 3), (3, 3)]
(162, 201, 115) [(4, 3), (5, 3), (6, 3), (4, 4), (5, 4), (6, 4)]
In [385]: colors = list(pixels.keys())
In [386]: if not is_rectangle(pixels[colors[0]]):
...: colors = colors[::-1]
In [387]: colors
Out[387]: [(162, 201, 115), (43, 39, 102)]
In [388]: for n, color in enumerate(colors):
...: upper, lower, left, right = bounding_box(pixels[color])
...: print(f'{n}. ({left} {upper}) ({right} {lower}) of', color)
0. (3 4) (4 6) of (162, 201, 115)
1. (1 2) (3 5) of (43, 39, 102)