2

I want to take an image and (somehow) read it as an array of pixels. Meaning each element of the 2d array would be either a hex code or RGB 3-tuple that represent the color of that pixel.

I have looked into image processing and found things like Pillow or SciPy but I only found overly simple things such as adding a filter or changing the general color properties of the image(making it generally greener by multiplying the read and blue values of every pixel by something like 0.3 - 0.5 while multiplying the green value by 1, effectively keeping it the same). What I need to do is to be able to examine every pixel individually based on its color.

After that I need to convert the image into one that uses less colors, (something like 4 or 8). I think the best way to do this would be to define some "thresholds" for these desired colors and when the color of a pixel is within the range of a certain color from those defined, then the pixel gets that respective color.

I have also not found too much about this, both in the way of actual information or people trying to do the same.

I would like to ask for any information or resources regarding to this kind of problem: - Library(libraries) to use? - Methods?(are there any widely used algorithms for this kind of problem?) - Am I using the wrong programming language?(is there one that offers this kind of functionality but easier to use?)

Any kind of help or information would be greatly appreciated, thank you in advance!

EDIT: I have found this question that refers to getting the values of a pixel, but I still need to split them into less colors.

Rares Dima
  • 1,575
  • 1
  • 15
  • 38
  • 1
    From my experience, it can be quite tricky to get good results when doing this kind of work with color processing. I found [this](https://www.alanzucconi.com/2015/09/30/colour-sorting/) useful reading on the subject and I hope it gives you some idea as approaches you could take – Tom Jan 12 '18 at 09:23
  • 1
    KMeans clustering would be a possible choice. – MaxPowers Jan 12 '18 at 09:29
  • @TCouch thank you, that actually shed some light on the matter! The step ordering is actually almost exactly what I am looking for. – Rares Dima Jan 12 '18 at 09:43
  • `scikit-learn` has a tutorial/demo on that: [link](http://scikit-learn.org/stable/auto_examples/cluster/plot_color_quantization.html) – Imanol Luengo Jan 12 '18 at 09:44
  • @MaxPowers I also thought of that, I actually recently made a rather detailed implementation of that, but KMeans needs a well defined distance function between 2 data points, and as the article given by TCouch mentioned, that is not exactly... feasible when dealing with colors. – Rares Dima Jan 12 '18 at 09:45

2 Answers2

7

Library (libraries) to use?

scikit-image or OpenCV would be my preferred choices.

Methods? (Are there any widely used algorithms for this kind of problem?)

K-means clustering is a popular approach to color quantization.

Am I using the wrong programming language? (Is there one that offers this kind of functionality but easier to use?)

Python is arguably the "easiest" language for this task.

DEMO

Consider this image:

original

The following code reduces the number of colors from +500K to only 6:

import numpy as np
from skimage import io
from sklearn.cluster import KMeans

original = io.imread('https://i.stack.imgur.com/QCl8D.jpg')
n_colors = 6

arr = original.reshape((-1, 3))
kmeans = KMeans(n_clusters=n_colors, random_state=42).fit(arr)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
less_colors = centers[labels].reshape(original.shape).astype('uint8')

io.imshow(less_colors)

And this is how the color quantized image looks:

less_colors

Tonechas
  • 13,398
  • 16
  • 46
  • 80
  • 1
    I figured out the k-means approach in parallel before seeing this answer but it was EXACTLY what i was hoping for. Thank you! – Rares Dima Jan 22 '18 at 07:55
2

What you are after is called color quantization. Several algorihtms have been designed, such as the Median Cut or the Popularity algorithm. They allow you to build an "optimal" color table with the desired number of entries.

These methods were popular in the times of expensive graphics cards, but have lost fame since the generalization of true color.

Complementarily to color quantization, one often uses color dithering, a method that restores some of the smoothness of color gradients and avoids banding effects.

https://nl.mathworks.com/help/images/reduce-the-number-of-colors-in-an-image.html?requestedDomain=true