Showing posts with label RGB. Show all posts
Showing posts with label RGB. Show all posts

Monday, July 20, 2015

Reducing Color part III


Recently I found a few hours to pick my project of reducing colors in a color image. In my previous post I explained how I take a color image and let Matlab search for 12 colors (or any number of my choosing) that best represent the original. I was quite pleased with the result as it was, but there was still plenty of room for improvement. Letting the algorithm run longer was one of them.

One thing another that I thought was missing was naming the colors found. I am colorblind. For me it's sometimes hard to name green or orange. The author of XKCD once held an interesting experiment where he let people name colors. The results are interesting and funny. For me most important is the list with 954 named colors. I thought would be cool to see if I could first find the most dominant colors in an image and then find the name of that color (or something very close).

All the colors in the table were in Hex codes so I converted them with the help of a function I found on the Matlab File Exchange site.

Since my reduced color image only has 12 different RGB colors it's not too much effort to compare each of these values with the list of 954 colors. I took the Cartesian distance between two numbers.

I'm not sure if that is the best way of finding the right color name. We humans are pretty picky when it comes to colors. So a shade of gray shifted a bit darker will still look gray. But shift it in one direction (i.e. blue) and all of a sudden it's a color.


Two Shades of Gray


Gray and some Color

Ok, it's not a very distinct color, but it's not completely gray. Maybe you'd call it shadow blue or air force blue (people think of a lot of names).

Anyway I added the XKCD list to my algorithm and found colors close to the dominant colors and finally to see how well it worked I used those colors to paint the picture. Behold the three images: original photo, reduced colors and XKCD colors.
Original


Reduced to 12 colors

XKCD colors

And the colors are:
    'eggplant'
    'beige'
    'bubblegum pink'
    'piss yellow'
    'deep lilac'
    'brownish orange'
    'rusty red'
    'very light pink'
    'darkish pink'
    'brick red'
    'light burgundy'
    'dried blood'

I don't think the colors are an exact match. And my reducing colors algorithm still has varying results, but it sort of work.

If I ever learn how to make this into a smartphone app I can walk through the supermarket and I will finally be able to pick the yellow banana's (#ffff7e apparently).
Questions are always welcome.

Sunday, April 5, 2015

Reducing the Number of Colors (Part II)

A while ago I made an algorithm in Matlab to reduce the number of grayscales in a black&white image (link). And after that I tried to do the same with a color image (link) which didn't work out that well.

Image of flowers with only 12 colors


I was kinda busy with a lot of things, but the wish to try again was always somewhere in the back of my head. A couple of weeks ago I reviewed an online course I followed on Coursera on Machine Learning. This is probably the one of the best courses I have followed, but like with all things, if you don't use the skills learned frequently you loose the skills. But still I remembered some of the topics and what I in particular wanted to learn again was clustering.

In the topic of clustering you let the algorithm you make search for groups of points lying close together. I don't want to explain the whole subject here, and since the course explains it so perfectly I would suggest to watch the movies there.
I believe they have opened the course in such a way now that you can follow it at any moment now and don't have to wait for a new session to start. If you ever want to learn about fitting data, computer learning, Matlab/Octave programming this is a great place to start.

Back to my small project.

Finding Clusters in RGB space

The colors in an image have three values red,green and blue for every pixel. I view these as point in a cube which has sides going from 0 to 255. If there is i.e. a lot of sky in an image there will be lot of points with a light blue color close to each other in this cube. I want to find that cluster of points.
Time for an example.

original picture
picture with only 12 colors

In the pictures you can see the result of my algorithm. I have looked for clusters in the RGB cube, 12 in this case. In the end every pixel belongs to one of the clusters and the original color is replaced with the mean color of the cluster.
The result looks pretty good in my opinion. I could make a nice paint by numbers picture with this :)
But how does it preform on other images? And does it always give the same result?
That second question is not a trivial one. I choose my start point (the average point of the clusters) at random by taking points from the image (the RGB value of pixels in the original image).

Example 2: Room for improvement


The top image is the original image and the three images after that are from three different runs. When you inspect them closely you notice that they are quite different. Why is this happening?
First of all, I only let the algorithm run for a short time, and I'm not even checking if it has in any way finished. With finished I mean that a new step in the calculation doesn't change the answer.
Second of all the starting point determine the outcome. I would have do do this calculation a lot of times and then take a sort of average of the end results and maybe throw away bad results.

Hope to come back soon with a Part III to this topic. 







Monday, July 7, 2014

Reducing the Number of Colors (Part I)

In my last post I discussed a way to reduce the number of colors in grayscale image. So the natural step was to proceed to a color image. Let's start with a nice color image.




The color image is just a collection of a red, a green and a blue image.


The Ignorant Approach


The first thing I tried, just to see what would happen, was to try the algorithm I made for the grayscale image. That means repeating the process for the individual channels and later merging the result.
That works, but it doesn't give the result I am really looking for.


For some colors this approach works. The sky is a nice color blue, some bright yellow accents on the plane come out as I wanted, but some color like on the right wing seem wrong.
What the program found were 6,6 and 7 peaks for the color channels. That means that if a certain value of blue is very dominant that value will be picked. But the area that belongs to that color might not be purely blue.

Similar But Different

Here's an example of 6 colors with the same maximum blue value of 255, but with different red and green values.

Square with different RGB values, but the same blue value.

You can imagine that one of these colors is not found as a dominant. If a certain color is found it has to give rise to a peak in he histogram of all three colors.


The picture above is an example in two color dimensions, the x-axis representing green and the y-axis blue. The dots are both colors that occur in some image. But perhaps the one in the top is found in way more pixels then the one in the bottom. In the end the green value which is the same for both colors will be found probably. But the blue value of the lowest color might not be found. Every pixel with a color close to that bottom color will be assigned a green value that is correct, but the new blue value could be miles off.

3D RGB Space


For me the problem was beginning look a bit clearer, also a bit more difficult. When you look at all the colors that occur in an image there are thousands. Some are quite similar, like all those colors blue in the sky of our example image. Let's see what all these colors look like in the 3D RGB space.

3D RGB Space of the Spitfire image

What I have drawn here is all the pixels in the image placed in the RGB space. Easily understandable points are (0,0,0) which is black in the front and (255,255,255) as white in the back. Along the diagonal axis are all the gray colors. Off diagonal RGB values are the other colors, and you can see some groups, and a lot of empty space. What you can't see how many identical RGB points there are, and how many of are all alone.
That is why I made the same image but here I changed the size of the circles to show how many pixels have that color.




We are looking at it from a different angle, but it shows one thing; there are a lot of blue pixels.

That's about as far as I've come right now. What I intend to do next is to find the regions of this image where a lot colors are found close together (like that blue area in the top). So this is similar to finding a peak in 1D histogram, but than more like finding a 3D peak (a blob with the highest density).
I am still thinking of what the best approach is going to be for this. 

Stay tuned!