[Numpy-discussion] collecting the bluest pixels

paul taney paultaney at yahoo.com
Tue Oct 7 14:28:43 EDT 2008


Hi,

I have this silly color filter that Stefan gave me:


def vanderwalt(image, f):
    """colorfilter, thanks to Stefan van der Walt"""
    RED, GRN, BLU = 0, 1, 2
    bluemask = (image[...,BLU] > f*image[...,GRN]) & \
               (image[...,BLU] > f*image[...,RED])

    return bluemask


To collect the right number of the bluest pixels I am calling it from this arduous successive approximation routine.  It occured to me that someone on this list knows how to do this in a couple of lines...


def successive_approximation(image, density, width, height, bpp):
    """keep calling vanderwalt till line length is within 10% of density target"""
    count = 0
    failsafe = 20  # max iterations
    gimp.progress_init("this is the fun part...")
    init_high = 1.400001
    init_low = 1.399991
    high_guesses = [(init_high, width*height*bpp)]  # we collect recent stats in this list
    low_guesses  = [(init_low, 0)]
    crossed_high = crossed_low = False
    factor = 1.4
    delta_high = .18   # adjust the factor by this much when it is too high
    delta_low = .14    # adjust the factor by this much when it is too low 
                       # if they were the same amount then they"d cancel
    xlength = 0
    while not ((xlength < density*6.3) and (xlength > density*5.7)):
        bluemask = vanderwalt(image, factor)
        line = np.array(bluemask.nonzero()).swapaxes(0,1).tolist()

        xlength = len(line) 
        # spread the search outward from initial condition (1.4) 
        # until we cross target. we collect 6 times the desired 
        # line length because we will take an average y per x
        # (unless they are too spread out and then we skip this column (despeckling))
        # My dataset averages 6 blue pixels per column, so...
        if xlength > density*6:                                               
            """too many points so raise the factor"""  
            print "LOOP1.%i: factor too low =%.5f, target=%i, line length = %i" % (count, factor, density*6, xlength)
            crossed_low = True
            low_guesses.append((factor, xlength))      
            factor += delta_low
            if crossed_high:   
                crossed_high = False
                delta_high *= .38  # cut the stepsizes
                delta_low *= .38                      
                print "crossed target.  factor now=%.5f" % (factor)
        else:
            """not enuf points so lower the factor"""
            print "LOOP1.%i: factor too high=%.5f, target=%i, line length = %i" % (count, factor, density*6, xlength)
            crossed_high = True
            high_guesses.append((factor, xlength))
            factor -= delta_high
            if factor < 0:
                lineno = getframeinfo(currentframe())[1]  # Beaz p 157
                print "algorithm failed with factor=%.5f (line %i)" % (factor, lineno)
                break
            if crossed_low:   
                crossed_low = False
                delta_high *= .38  # cut the stepsizes 
                delta_low *= .38                       
                print "crossed target.  factor now=%.5f" % (factor)
        count += 1
        gimp.progress_update(float(count) / failsafe)
        #print "count=%i, factor=%f\nhigh_guesses=%r\nlow_guesses=%r" % (count, factor, high_guesses, low_guesses)
        if count == failsafe:
             print "failsafe: level 1 failed to converge."
             break
    
    if (xlength < density*6.3) and (xlength > density*5.7):
        print "success at density*%1.3f" % (xlength/float(density))
    else:
        pdb.gimp_message("maybe not enuf blue pixels for this algorithm.")

    return bluemask
# end successive_approximation





More information about the NumPy-Discussion mailing list