Как найти местонахождение самого правого черного пикселя

Черно-белое изображение с улыбающимся лицом внутри рамки.

улыбающееся лицо

Я хочу выяснить расположение самой правой точки улыбающегося лица. (в этом случае черный цвет должен быть на отметке «184,91» изображения)

Используя ниже, я надеюсь перечислить цвета на изображении, а затем посмотреть, что можно искать дальше.

from PIL import Image
im = Image.open("face.jpg")
print im.convert('RGB').getcolors() # or print im.getcolors()

Однако он возвращает None, и я застрял.

Как я могу получить самую правильную точку лица?


person Mark K    schedule 18.07.2016    source источник
comment
Не ответ на вопрос, а вы в курсе, что черных точек больше звездная кайма?   -  person tobias_k    schedule 18.07.2016
comment
@tobias_k, спасибо за комментарий. Я думаю, есть ли способ ограничить поиск определенным диапазоном, например, от 40,30 до 200,160 и т. д.   -  person Mark K    schedule 18.07.2016
comment
Ну, вы могли бы crop изображение, но тогда вам нужно знать размер смайлика (чтобы не обрезать слишком много), чтобы определить размер смайлика...   -  person tobias_k    schedule 18.07.2016
comment
в порядке. Можете ли вы поделиться способом определения самой правильной цветной точки изображения (принимая его за обрезанное изображение)? благодаря.   -  person Mark K    schedule 18.07.2016
comment
К сожалению, я не могу (иначе я бы сделал); Я могу воспроизвести метод, дающий None, но, боюсь, я слишком мало знаю PIL, чтобы помочь.   -  person tobias_k    schedule 18.07.2016
comment
@tobias_k, в любом случае спасибо за помощь. :)   -  person Mark K    schedule 18.07.2016


Ответы (2)


Это решение, которое я придумал:

import numpy as np
from skimage import io

img = io.imread('https://i.stack.imgur.com/sbqcu.jpg', as_grey=True)

left, right, top, bottom = 25, 25, 20, 20
crop = img[top: -bottom, left:- right]
threshold = .85
smiley = crop < threshold

rows, cols = np.nonzero(smiley)
rightmost = cols.max()
indices = np.nonzero(cols==rightmost)

for r, c, in zip(rows[indices], cols[indices]):
    print('(%d, %d)' % (r + top, c + left))

Приведенный выше код дает:

(87, 184)
(88, 184)
(89, 184)
(90, 184)
(91, 184)
(92, 184)
(93, 184)
(94, 184)
(95, 184)
(96, 184)
(97, 184)
(98, 184)

Это согласуется с тем фактом, что в самой правой части улыбающегося лица проходит вертикальная прямая линия.

Порог должен быть тщательно выбран, чтобы избежать обнаружения зашумленных пикселей:

threshold = .95
io.imshow(crop < threshold)

смайлик

person Tonechas    schedule 21.03.2017

Как косвенный способ, может быть смогу: 1. снять рамку 2. подрезать белую

Остается само основное изображение. Размер изображения может указать координаты, если основное изображение имеет регулярный рисунок.

from PIL import Image

img = Image.open("c:\\smile.jpg")
img2 = img.crop((30, 26, 218, 165))  # remove the frame
img2.save("c:\\cropped-smile.jpg")

Обрезать пробелы с помощью PIL учит, как удалять белые части круга.

def trim(im):
    bg = Image.new(im.mode, im.size, im.getpixel((0,0)))
    diff = ImageChops.difference(im, bg)
    diff = ImageChops.add(diff, diff, 2.0, -100)
    bbox = diff.getbbox()
    if bbox:
        return im.crop(bbox)

im = Image.open("c:\\cropped-smile.jpg")
im = trim(im)
im.save("c:\\final-smile.jpg")

теперь, чтобы получить размер основного изображения.

im = Image.open("c:\\final-sbqcu.jpg")
w, h = im.size

У меня получилось 131 132. Таким образом, 131,66 будет самой правой точкой изображения.

person Mark K    schedule 19.07.2016
comment
однако это 131,66 является самым правым из смайликов, а не самым правым расположением на полном изображении. - person Mark K; 21.03.2017