Python merges two transformations

Combining two transformations: Combining multiple transformations can create complex mappings, transforming raw data into intermediate values and then producing a final result. Here’s how to combine color truncation and mapping.

Truncation is difficult in some problem domains, but simple in others. For example, truncating a 9-digit US ZIP code by truncating five digits, or even three digits, to determine the approximate geographic location of the ZIP code.

For color, we can use the bit masking technique described earlier to convert the three 8-bit values (24 bits for 16 million colors) into three 3-bit values (9 bits for 512 colors).

Create a set of color maps that contain the distances to a given set of colors and the cutoffs for the source colors, as shown below:

bit3 = range(0, 256, 0b100000)
best = (min((euclidean(rgb, c), rgb, c) for c in colors)
for rgb in product(bit3, bit3, bit3))
color_map = dict((b[1], b[2].rgb) for b in best)

Create the object bit3 using range to iterate over all 8 values of the 3-bit color. Using the binary value 0b100000 helps us better understand how to use bits, ignoring the unsignificant 5 bits and using only the most significant 3 bits.

Unlike ordinary iterable objects, the range object can be reused, so here we use the product(bit3, bit3, bit3) expression to generate all 512 color combinations as the output color.

For each truncated RGB color, we create a triple containing the elements: (0) the distance to all crayon colors, (1) the RGB color itself, and (2) the Color object representing the crayon color. Taking the minimum value of this set, we get the crayon color object that is closest to the truncated RGB color.

Now we have a mapping object from any truncated RGB color to the crayon color that is closest to it. Before finding the crayon color that best matches the source color, the source color is first truncated. This truncation calculation is combined with a pre-calculated color map to create a mapping technique.

The code for image replacement is as follows:

mask = 0b11100000
clone = img.copy()
for xy, rgb in pixel_iter(img):
r, g, b = rgb
repl = color_map[(mask&r, mask&g, mask&b)]
clone.putpixel(xy, repl.rgb)
clone.show()

This replaces pixels in the image using the putpixel() function from the PIL library. The mask value retains the highest three bits of the original color value, resulting in a color that is a subset of the original color set.

As you can see, functional programming tools can generate concise, yet inefficient, algorithms. Therefore, the primary tool for measuring algorithm complexity (also known as Big O analysis) is equally important for functional and imperative programming.

The key issue here is not that the product() function is inefficient, but that the algorithm created using it is inefficient.

Leave a Reply

Your email address will not be published. Required fields are marked *