[Numpy-discussion] color filtering

paul taney paultaney@yahoo....
Wed Sep 17 07:29:18 CDT 2008


Hi,

I"m just learning numpy and I am not a math.  I just need it.

I need to do a color filter;  I have it working in python
but it runs forever on some of my images.  And I dont know 
enuf c or c++ to use weave (or Boost or Pyrex or...)

This looks like the best way, and I have somebody who is 
advising me, but he said to put the question to you guys, so

I have an array from a wx.Image, but for testing we can use
something just 5 * 5 * 3.  I want the x,y coords of the blues 
pixel(s) per x returned as a line of this sort:

    [(x1, y1), (x2, y2)...(xn, yn)]

# In real life we have an image:

import wx
import numpy as np
image = wx.Image(path, wx.BITMAP_TYPE_ANY)
w, h = image.GetWidth(), image.GetHeight()
# Rappin page 362, Smart page 285
a = np.fromstring(image.GetData(), np.uint8)  
a.reshape(w, h, 3)

# But while testing we can use:

import numpy as np
    a = np.array(
    [[[ 64, 237, 108],  #  x  y
      [185, 240,  68],  # [0, 1]
      [ 17, 116,  55],  # [0, 2]
      [107,  11, 185],  # [0, 3] is blue
      [154,  30,  52]], # [0, 4]

     [[251,  73, 150],  #  x  y
      [ 47, 225,  97],  # [1, 1]
      [101,  91, 251],  # [1, 2] is blue
      [ 61,  23,  79],  # [1, 3]
      [161,  22, 165]], # [1, 4]

     [[  4, 162, 188],  # [2, 0]
      [ 25, 131, 211],  # [2, 1]
      [162, 112, 177],  # [2, 2]
      [169,  83, 214],  # [2, 3] is blue
      [254, 139,  95]],

     [[  2,  88, 216],  # [3, 0] is blue
      [230,  63, 192],
      [ 71,  78, 250],  # [3, 2] is blue
      [113, 151, 142],
      [104,  65, 127]],

     [[  6, 191, 220],  # [4, 0] is blue
      [ 38, 141,   4],
      [245,  41,  23],
      [ 23, 127, 183],  # [4,] is blue
      [165,  24,   5]]], np.uint8)


# some of these tests work...
# Proceeding from the concrete to the abstract...

DIM = (5, 5)
def test1(a):

    red, grn, blu = a[0,0]
    print "r=%r, g=%r, b=%r" % (red, grn, blu)  # prints r=64, g=237, b=108

    red, grn, blu = a[4, 4]
    print "r=%r, g=%r, b=%r" % (red, grn, blu)  # prints r=165, g=24, b=5


def test2(a):
    # this is a threshold filter
    rmin, rmax, gmin, gmax, bmin, bmax = 0,178, 0,178, 100,255

    very_blue_pixels = []
    w = DIM[0] 
    x = y = 0
    # searches rows first (x is turning faster, so...)
    for yslice in a:
        for xyslice in yslice:
            if 0: print "x=%r, y=%r, type(xyslice)= %r" % (x, y, type(xyslice))
            if 0: print "a[x=%i, y=%i] = %r" % (x, y, a[x,y])
            red, grn, blu = xyslice
            if (rmin <= red <= rmax) and \
               (gmin <= grn <= gmax) and \
               (bmin <= blu <= bmax):
                if 1: print "a very blue pixel at x=%i, y=%i, rgb=%r" % (x, y, xyslice)
                very_blue_pixels.append((x,y))
            y += 1
            if y==w: y=0  # ugly
        x += 1
    print very_blue_pixels


def test3(a, THRESH):
    # for my dataset I can optimize the above loop like this 
    # at the cost of getting less output since the THRESHOLD 
    # is only one number
    
    very_blue_pixels = []
    w = w=DIM[0]
    x = y = 0
    for yslice in a:
        for xyslice in yslice:
            red, grn, blu = xyslice
            if (red <= THRESH) and (grn <= THRESH) and (THRESH <= blu):
                very_blue_pixels.append((x, y))
                if 1: print "I see blue a[x=%i, y=%i] pixel = %r" % (x, y, xyslice)
            y += 1
            if y==w: y=0
        x += 1
    print very_blue_pixels

# <snip>
# I see blue a[x=3, y=2] pixel = array([ 71,  78, 250], dtype=uint8)
# I see blue a[x=4, y=3] pixel = array([ 23, 127, 183], dtype=uint8)
# [(0, 3), (1, 2), (2, 0), (2, 1), (2, 3), (3, 0), (3, 2), (4, 3)]


def test4(a):
    RED, GRN, BLU = 0, 1, 2
    rmin, rmax, gmin, gmax, bmin, bmax = 0,178, 0,178, 100,255
    line_pix = ((rmin <= a[:, :, RED] <= rmax) &
                (gmin <= a[:, :, GRN] <= gmax) &
                (bmin <= a[:, :, BLU] <= bmax))
    print "test4: line_pix = %r" % (line_pix)
    # ValueError: The truth value of an array with more than 
    # one element is ambiguous. Use a.any() or a.all()

# There is one more test in the attached file who"s 
# results mystify me.  It goes like this:


def test5(a, rmax, gmax, bmin):
    RED, GRN, BLU = 0, 1, 2
    line_pix = ((a[:, :, RED] <= rmax) &
                (a[:, :, GRN] <= gmax) &
                (a[:, :, BLU] >= bmin))
    print "test5: line_pix = %r" % (line_pix)

# returns
# test5: line_pix = array([
#        [False, False, False,  True, False],
#        [False, False,  True, False,  True],
#        [ True,  True,  True,  True, False],
#        [ True, False,  True,  True,  True],
#        [False, False, False,  True, False]], dtype=bool)


All I need is a line like this: [(x,y),(x,y)(x,y)...(x,y)]
preferably 1 y per x at the "best" (cluster) location,
without going into kmeans or anything obscure.

Any suggestions?

This is for a volunteer project vectorizing scanned
stripcharts for http://IEDRO.org

Thank you in advance.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_threshold.py
Type: application/octet-stream
Size: 5840 bytes
Desc: not available
Url : http://projects.scipy.org/pipermail/numpy-discussion/attachments/20080917/e2356998/attachment-0001.obj 


More information about the Numpy-discussion mailing list