[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