Categories
Uncategorized

Basic Image Processing: Direct Pixel Modification

While considering and changing individual pixels isn’t the most efficient way of modifying an image, it can certainly help with a person’s understanding of what is truly happening with an image at the pixel level. In this code, we will modify the pixels in such a way to make the image look more “cartoonish”, with solid colors representing all colors within a given range. In this implementation I chose numbers that were suitable for my particular picture, but may not be best for your picture, so I encourage people reading this to change numbers as they see fit, and learn how this changes the image modification.

In the above code, we define a new function called color_pic, taking as input the image that you would like to cartoonify, evaluating each pixel by itself, modifying it, and showing the final image at the end. The first thing we do is copy the image into a separate variable, so that the original values of the image could still be accessed by other parts of the code later. In many cases, this step isn’t necessary, but if you are not constrained for memory it may be worth it to be safe rather than ending up with unexpected values. After this, the for loops begin.

In this code, we make use of 2 “for loops” to consider each pixel in the x and y directions, respectively, which are also the first and second dimensions of the image. The third dimension, again, is to tell which of the three colors (blue, green, or red) you are currently considering. I should note that for loops are generally pretty inefficient, but here they can do a better job of . The for loops are constructed by using the range function, which is native to python, and creates a list of numbers within a range you define. If you type print(range(5)), it will return a list: [0, 1, 2, 3, 4]. If you type print(range(2, 5)), it will return a list: [2, 3, 4]. There are additional options for range, but they aren’t important for the purposes of this exercise. Using the “for loop” essentially just means that it will consider all of the listed cases for a variable. For example, if you type for i in range(5): print(i), the program will print lines listing 0, 1, 2, 3, and 4, as these are the different values that i will represent before the for loop is complete. In our case, we will have i represent all of the numbers between 0 and the height of your input image (which is the first dimension of the image, as can be found by typing my_im.shape[0], or im.shape[0], if you do it within a function. The second dimension of the image (the horizontal direction) can similarly be found by typing my_im.shape[1] or im.shape[1].

So, within the for loops, calling im[i, j] indicates that you are considering a single pixel which is i pixels down from the top of the image and j pixels right from the left of the image. Typing print(im[i, j]) will return 3 values which correspond to the blue, green, and red values that are present in the pixel you are currently considering. Each of these values can additionally be individually called using im[i, j, 0], im[i, j, 1], and im[i, j, 2], respectively. The rest of the code uses these constructions to determine how to modify the image.

Line 38, for example, determines if the currently considered pixel contains B, G, and R values that are all above 200. As the maximum value of each is only 255, this would mean that these pixels are almost completely white (if you’re confused about this, please consult this website again). In line 39, it then makes any pixel meeting this requirement to be exactly white, with maximum values for each of B, G, and R for that pixel. Similarly, line 40 determines if the B value is greater than 165. If so, then it changes this pixel to be a pre-defined color with B, G, and R values of 230, 150, and 20, respectively. Each pixel goes through many similar considerations in lines 38-54, each considering whether it falls within a pre-specified range of B, G, or R values. If the pixel doesn’t meet any of these conditions, it is finally assigned to be a sort of dark grey color with B, G, and R values each equal to 50.

The result of this code (you will notice it is slow compared to the others, due to the inefficiency if the for loop) is shown below. You can imagine how a similar technique (with some tweaking and polishing) could achieve something similar to the previously very popular Obama “HOPE” photo, also shown below: