avatarSalvatore Raieli

Summary

The provided content discusses the utilization of Python for extracting and analyzing color information from images, including identifying predominant colors, color clustering for image segmentation, and recoloring black and white images using machine learning techniques.

Abstract

The article delves into the intricacies of color perception and representation in digital images, emphasizing the importance of color in image analysis. It explains the concept of color in the context of human vision and the RGB color model, and how these concepts are applied in Python to manipulate and interpret color data within images. The author provides practical Python code examples to illustrate how to extract and visualize color information, perform color clustering to identify dominant colors, and segment images using k-means clustering. Additionally, the article touches on the potential of deep learning to recolor black and white images, highlighting the intersection of artificial intelligence and image processing. The article concludes with a reflection on the significance of color in various applications and invites readers to explore further resources and the author's GitHub repository for comprehensive tutorials and code.

Opinions

  • The author suggests that color information in images can reveal more details than what is immediately visible, implying its importance in image analysis.
  • There is an appreciation for the complexity of color perception, acknowledging that it varies from person to person due to genetic differences in cone cells.
  • The article conveys enthusiasm for the practical applications of color analysis in Python, such as matching color templates or recoloring old photographs.
  • The author expresses a forward-looking perspective on the capabilities of artificial intelligence, particularly convolutional neural networks, in enhancing image processing tasks like colorization.
  • The author encourages engagement with the machine learning community by subscribing to newsletters, following on social media, and contributing to collaborative projects.
  • There is an underlying assumption that readers have a foundational understanding of Python programming and are interested in expanding their knowledge in machine learning and image processing.

|ARTIFICIAL INTELLIGENCE| COMPUTER VISION| PYTHON|

Harnessing the power of colors in Python

Color images have more hidden information than you think

the image source: Jeremy Thomas at unsplash.com

In this journey into image analysis, we will look at how to exploit the information in images.

In this article we will discuss about:

  • What is a color
  • How to identify the predominant colors in an image
  • How to use color clustering to segment images
  • How to recolor an image that is in black and white
  • How to all do that in Python

What is a color?

Photo by Pawel Czerwinski on Unsplash

Life is a painting, and you are the artist. You have on your palette all the colors in the spectrum — the same ones available to Michaelangelo and DaVinci. — Paul J. Meyer

The definition of color is not an easy task. We can say that the visible light hits something and absorbs some wavelength and then what is not absorbed is reflected. Notice, that visible light is actually a very narrow range of frequencies/wavelengths which is called the visible spectrum and it ranges from 380 to 750 nanometers. This tiny range of frequencies is actually special since it is something that a typical human eye can capture. The magic happens when our eyes collect the reflected wavelengths of an object and this light excites the human photoreceptors.

image source: here

In the human eye, the cone is specialized nerve cells that act as photoreceptors. There are three types of cone cells, and each type is sensitive to a different wavelength. There are also rods, which are more sensitive to light and support vision at a low-light level. But cones are perceiving the colors and they are much better at perceiving details. The color perception changes from individual to individual, since the percentage of the cones, can change and there are different genetic mutations (thus, we all perceive color differently).

image source: here

As a curiosity, human eyes perceive red as being 2.6 times as bright as blue and green, that’s why a single red dot can capture our eye at first glance (yes, like a cat when you use a laser).

image source: here

All the code used for the image in this article (and in the previous one) can be found here:

Color images

In a color image, we have three values for each pixel: one for the Red, Blue, and Green (or RGB). We can represent each pixel as a 3-dimensional vector, and therefore an image as a three-different array. Normally each color is encoded with 8-bit (meaning 256 shades) and a pixel could represent more than 16 million colors. We can image a pixel as a point in a 3d space, with RGB color axes starting from black (0,0,0).

Notice, that by loading an image in Python we can easily slice it in the color components:

#slicing channels 
im1 = im[:,:,0]
im2 = im[:,:,1]
im3 = im[:,:,2]
original image from Mark Harpur at Unsplash. Modified version by the author.

The line connecting black (0,0,0) to white (255, 255, 255) is called gray-vector. Theoretically, all the colors on the line from black (0,0,0) to red (255, 0, 0) are the same color but just different shades (different levels of illumination). This can be generalized also for the other colors, and we can define the chromaticity plane where the colors on the edge are defined as pure and moving to the center becoming gray (or polluted by the light). This concept is used to normalize the RGB color or to transform it into a large format (color plus intensity).

image by the author

Dramatic black and white

Photo by Cristina Gottardi on Unsplash

Black and white creates a strange dreamscape that color never can. — Jack Antonoff

A color image can be converted in grayscale, the transformation is not invertible. The conversion is done by multiplying each channel for weight and summing up:

The weights have a value of 1/3 or in some contexts (for analysis purposes, if you are more interested in plant classification the green is more important) they can have different values. In visualization often, these weights are used:

The threshold on color images is more complex since you need to consider for each color a minimum and maximum value (a range). Since color changes with the intensity of light, this can also be problematic. Often the image is converted to zero before the threshold.

im = io.imread(url)
im1 = (0.2125 * im[:, :, 0]) + (0.7154 * im[:, :, 1]) + (0.0721* im[:, :, 2])
im2 = (0.7 * im[:, :, 0]) + (0.2 * im[:, :, 1]) + (0.1* im[:, :, 2])
im3 = (0.2 * im[:, :, 0]) + (0.2 * im[:, :, 1]) + (0.7* im[:, :, 2])
image source from Wikipedia.

Counting color in an image

Many times, I was asked to match the color template when preparing a PowerPoint. The eternal struggle in trying to understand if the colors are similar. How we can know which are the predominant colors inside an image? It looks like a simple question, but using Pantone’s master book is not a feasible solution.

As you may know, RGB colors have assigned a hexadecimal code that is used to display on web pages. The hex color code is also recognized widely by Python libraries, so the idea is to obtain a list of the most represented hex colors and their count. The idea is to use a clustering algorithm to find color clusters and we transform the cluster center (centroid) into hexadecimal colors. In this way, since we are forming clusters of color we will extract the most prominent colors. Then we will plot using a bar plot.

def extract_colors(image, n_colors, resize = 0.5):
    """
    count colors in an image
    """
    def RGB2HEX(color):
      "RGB color to HEX colors"
      return "#{:02x}{:02x}{:02x}".format(int(color[0]), int(color[1]), int(color[2]))
    
    #scaling if too big
    if resize is not None:
      "note: in the next version  multichannel argument is changed"
      image = rescale(image, resize, anti_aliasing = True, multichannel= True)
      image = image *255

    image = image.reshape(image.shape[0]*image.shape[1], 3)
    #clustering step
    clf = KMeans(n_clusters = n_colors)
    labels = clf.fit_predict(image)
    #counting step
    counts = Counter(labels)
    counts = dict(sorted(counts.items()))
    #obtaining HEX colors
    center_colors = clf.cluster_centers_
    ordered_colors = [center_colors[i] for i in counts.keys()]
    hex_colors = [RGB2HEX(ordered_colors[i]) for i in counts.keys()]
    #save in a pdf
    df = pd.DataFrame(columns= ["colors", "value_count"])
    df["colors"], df["value_count"] = hex_colors, counts.values()
    return df

Let’s start with this aerial picture

original image from Mark Harpur at Unsplash

We run our function, which is basically returning a data frame:

Then we can use seaborn to plot the bar plot:

ax = sns.barplot(x="colors", y="value_count", data=df, palette = df["colors"])
plt.xticks(rotation = 45)
bar plot representing the most represented colors in the image. Each column is a color.

Notice what’s happening using different pictures:

Bar plots of the picture’s extracted colors. original images: from Mark Harpur at Unsplash (left), from Tijs van Leur at Unsplash (middle), and from Cassie Matias at Unsplash (right). Bar plots generated by the author.

Another application is the use of k-means to segment the image. In fact, using clusters we can divide the image into segments. This approach also has the advantage that we can quickly do tests by changing the number of clusters

def segment_image_kmeans(im = None, K =3):
  '''
  segment an image with k-means
  '''
  # converting to HSV space
  img_hsv=cv2.cvtColor(im,cv2.COLOR_BGR2RGB)
  vectorized = np.float32(img_hsv.reshape((-1,3)))
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)
  K = 3
  attempts=10
  ret,label,center=cv2.kmeans(vectorized,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS)
  center = np.uint8(center)
  res = center[label.flatten()]
  result_image = res.reshape((img_hsv.shape))
  return img_hsv, result_image

  
k=3
img_hsv, result_image = segment_image_kmeans(im = img, K =K)
image source for the code: here

Coloring black and white images

An interesting application is to make images that are black and white into color. Especially for old photographs, thanks to deep learning today it is possible to recolor images

In future articles, we will discuss convolutional neural networks and other models. For now, suffice it for us to know that there is an artificial intelligence model behind this process that has been trained to color images. The code is in the notebook.

image from here

Concluding remarks

Colors, like features, follow the changes of the emotions. — Pablo Picasso

There is a lot of information hidden in the colors that can be used in many downstream tasks. For instance, extracting colors can be used to search images for their similarity in the color footprint. We can also couple this information with shapes and other features we can extract from the images.

A more efficient way can be extracting features that consider colors, shape, and texture. As an example, we could use a pre-trained model to build a feature extractor and based on this calculate the similarity between images. In other words, as you can obtain text embedding you can do the same with images.

The previous article of the series is here. To be concise here I showed the essential code, but all the codes used are present here

If you have found this interesting:

You can look for my other articles, and you can also connect or reach me on LinkedIn. Check this repository containing weekly updated ML & AI news. I am open to collaborations and projects and you can reach me on LinkedIn. You can also subscribe for free to get notified when I publish a new story.

Here is the link to my GitHub repository, where I am collecting code and many resources related to machine learning, artificial intelligence, and more.

or you may be interested in one of my recent articles:

Additional resources

In Plain English 🚀

Thank you for being a part of the In Plain English community! Before you go:

Machine Learning
Artificial Intelligence
Data Science
Programming
Computer Vision
Recommended from ReadMedium