11

I have an image that looks equivalent to this image:

this.

It is a series of circles on a page in a curvy line, and the line is different every time.

from PIL import Image
im = Image.open("bride.jpg")

After importing it, I was wondering if there was a way of distinguishing the colours. For the example this might be:

[Purple, Cyan, Purple, Cyan, Purple Cyan...]

The line has no pattern to it, and is several thousand circles long, which means that it cannot be done manually. Also note that the image I'm actually testing on is of much higher quality, the actual image can be found here.

Alexander Craggs
  • 7,874
  • 4
  • 24
  • 46
  • 1
    It's a bit unclear exactly what you are trying to do. Please show some code? What is the source of this image? – André Laszlo Dec 22 '14 at 10:38
  • Ah, okay, I'll add in some code and try to expand, mind giving me a minute. – Alexander Craggs Dec 22 '14 at 10:42
  • 1
    I'm intrigued :-) Are you able to say what you are doing with such things - what generates them and how you use them? – Mark Setchell Dec 22 '14 at 10:58
  • 1
    This question might have some helpful info: http://stackoverflow.com/questions/5368449/python-and-opencv-how-do-i-detect-all-filledcircles-round-objects-in-an-image Do you know where the starting circle is located, or does it matter which circle you start from? – alienth Dec 22 '14 at 10:59
  • 1
    I'm sorry to disappoint @MarkSetchell , thee are only used for fun. It would be cool to find something useful to do with them. And yes alienth, that helped incredibly. The linked question [here](http://stackoverflow.com/questions/4785419/detection-of-coins-and-fit-ellipses-on-an-image?lq=1) was also very useful for anyone in the future looking at this question. – Alexander Craggs Dec 22 '14 at 11:06
  • Fun is cool by me! Knock yourself out enjoying them :-) :-) :-) And have a vote for a good fun question too! – Mark Setchell Dec 22 '14 at 11:07
  • You want a solution for that particular image? I mean, can you assume that has a circular structure? Additionally, can you assume you know the starting point (by selecting it manually for example)? – Imanol Luengo Dec 22 '14 at 11:10
  • Don't worry @iluengo, I've already solved it. And thanks for the upvote Mark! – Alexander Craggs Dec 22 '14 at 11:12
  • Color me intrigued. Is your solution interesting enough to share as a self-answer? – Jongware Dec 22 '14 at 11:14
  • 3
    @Jongware Will do, but going out now. I will post a self-answer when I get back (5-7 hours). – Alexander Craggs Dec 22 '14 at 11:16
  • My self-solution appeared to work, but I found a fatal bug which made it stop working. I'm continuing to work on it. – Alexander Craggs Dec 23 '14 at 17:53
  • so is this a question still? – Ross Dec 24 '14 at 01:01
  • @Ross No, not any more. I'm going to post a self-answer once I figure out the answer myself. It's a tiny problem with *my* programming. – Alexander Craggs Dec 24 '14 at 17:50
  • 1
    @PopeyGilbert post the answer ^_^ even with the bug. :) So we can have fun too. ;) – karlcow Dec 30 '14 at 19:05

2 Answers2

1

Just create a list of RGB values along the line and then filter the list to remove like-adjacent values.

Get pixel's RGB using PIL

#find RGB values   
rgb_values = []
for point in line:
   r, g, b = rgb_im.getpixel(point)
   rgb_values += [ (r,g,b)]
#remove similar adjacent values
for i in range(len(rgb_values)-1):
    if rgb_values[i] == rgb_values[i+1]:
        rgb_values.pop(i)
        i -= 1
if len(rgb_values) > 1:
    if rgb_values[-1] == rgb_values[-2]:
         rgb_values.pop(-1)
Community
  • 1
  • 1
mattsap
  • 3,790
  • 1
  • 15
  • 36
1

I think the main problem for you is to find a good path of pixels to follow from one end of your curve to the other. Once you have decided this path, you can just follow it and check the pixel colors as you go.

For now, I would suggest you input the path yourself by specifying a set of waypoints. Here is some code for your example figure. I took the first point in the left purple disc, the second at the angle, and the last one in the bottom-right purple disc.

from PIL import Image
from numpy import array, arange

im = Image.open("aqoGkjs.png")
rgb_im = im.convert('RGB')

def get_color_at(p):  # color function as mattsap suggested
    r, g, b = rgb_im.getpixel(tuple(p))
    if r > g and r > b:
        return 'Purple'
    elif r < 10 and g < 10:
        return 'Blue'
    return 'Cyan'

colors = []
via_points = [array([25, 65]), array([185, 44]), array([240, 210])]

for i in xrange(len(via_points) - 1):
    for x in arange(0, 1, 0.01):
        p = x * via_points[i] + (1 - x) * via_points[i + 1]  # linear interpolation
        cur_color = get_color_at(p)
        if cur_color == 'Blue':  # ignore borders
            continue
        if not colors or cur_color != colors[-1]:
            colors.append(cur_color)

print colors

It prints:

 ['Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple', 'Cyan', 'Purple']

For your big image, you can input all the waypoints by hand. Or try to make a smart piece of code to find them automatically ;)

Tastalian
  • 369
  • 4
  • 12