3

A black and white image showing a smile face inside a frame.

smiling face

What I want is to find out the location of most right point of the smile face. (in this case, color black shall be at around “184,91” of the image)

By using below I hope to list the colors in the image, then see what can look for further.

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

However it returns None, and I am stuck.

How can I get the most right point of the face?

Tonechas
  • 13,398
  • 16
  • 46
  • 80
Mark K
  • 8,767
  • 14
  • 58
  • 118
  • Not an answer to the question, but are you aware that there are more black points is the starry border? – tobias_k Jul 18 '16 at 15:29
  • @tobias_k, thanks for the comment. I am thinking if there's a way to limit the search to certain range, for example from "40,30" to "200,160" etc. – Mark K Jul 18 '16 at 15:31
  • Well, you could `crop` the image, but then you need to know the size of the smiley (in order to not crop too much) to determine the size of the smiley... – tobias_k Jul 18 '16 at 15:33
  • ok. can you share a way to detect the most right colored point of an image (taking it as a cropped image)? thanks. – Mark K Jul 18 '16 at 15:37
  • Unfortunately, I can't (otherwise I'd have); I can reproduce the method giving None, but I know too little PIL to help, I'm afraid. – tobias_k Jul 18 '16 at 15:58
  • @tobias_k, thanks for the help anyway. :) – Mark K Jul 18 '16 at 15:59

2 Answers2

4

This is the solution I came up with:

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

The code above yields:

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

This is consistent with the fact that there is a vertical straight line at the rightmost part of the smiling face.

The threshold has to be carefully chosen to avoid detecting noisy pixels:

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

smiley

Tonechas
  • 13,398
  • 16
  • 46
  • 80
1

As an indirect way, maybe I can: 1. remove the frame 2. trim the white

What’s left is the core image itself. The dimension of the image can tell the coordinates if the core image is of regular pattern.

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

Trim whitespace using PIL teaches how to remove the circle white portions.

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

now to get the dimension of the core image.

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

I got it as 131,132. So 131,66 shall be the most right point of the image.

Community
  • 1
  • 1
Mark K
  • 8,767
  • 14
  • 58
  • 118
  • however this 131,66 is the most right of the smiley, not the location of the most right in the full image. – Mark K Mar 21 '17 at 08:47