Powered by Blogger.

Friday, January 29, 2010

Tag: , , , , , , ,

Pseudocolor implementation with OpenCV.

In Computer Vision works in a lot of cases with gray images because there are a lot of motives. But human vision don't perceives the gray levels so well as color levels.

Then if we need show a image to a person, we can color it. But, how is the best way to coloring gray image?

There are 3 ways to do it: Manually, automatically and colored by ranges.

In this tutorial, i go to develop the way most common automatic for gray image coloring.

To do it we need know we go to receive a gray level and we need return 3 values, one for red, one for blue and other for green.

We go to use this function:

$latex \displaystyle{ s(x,y)=\vert sin(r(x,y)*p*PI + \Theta*PI)\vert}$

And r(x,y) is the gray level and p is the number of repetitions and $latex \displaystyle{ \Theta }$ is the displacement.

Then we only need define the p and $latex \displaystyle{ \Theta }$ for each channel.

If we create a plot with this function with this parameters for red, green and blue ((2,0),(2,-0.1),(2,-0.3)) we get:

[caption id="attachment_253" align="aligncenter" width="300" caption="Pseudocolor Graph with red(p=2,theta=0) green(2,-0.1) and blue(2,-0.3)"]Pseudocolor Graph[/caption]

Then we only need set the gray level in range 0 to 1 and the sine returns values from 0 to 1 we interpret as float image values or we set in range 0 to 255.

To finish this is the result:

[caption id="attachment_255" align="aligncenter" width="387" caption="Pseudocolor Result"]Pseudocolor Result[/caption]

Download the code.

About David Millán Escrivá

David completed his studies in Universidad Politecnica de Valencia in IT with a Master's degree in artificial intelligence, computer graphics, and pattern recognition, focusing on pattern recognition and Computer Vision. David has more than 15 years of experience in IT, with more than ten years of experience in Computer Vision, computer graphics, and pattern recognition, working on different projects and start-ups, applying his knowledge of Computer Vision, optical character recognition, and augmented reality. Co-Author of two OpenCV books and reviewer of few more.

15 comments:

  1. Hi! First of all, nice blog :)

    I am facing the opposite problem. I've a pseudocolor image that represents reflectivity (or energy). From black / blue values (no reflectivity) to red / white values (maximum reflectivity). In fact, my images are exactly the inverse of what you are showing: blue regions come from dark values, red regions come from white values.

    I guess I could use something like your function to map that 3 channel image back to a gray level image (because I'm using OpenCV to analyze it, and thus color is not so important). Right now, I'm simply weighting each channel:

    graylevel = 0.6 * r + 0.4 * g + 0.2 * b

    That way, white/red regions become brighter than blue/black regions.

    But I don't really like that solution. Then I thought I could create a LUT table... but it would be much better with a map function like yours. Any experience with something like that?

    ReplyDelete
  2. Hi Luis, you know the color space and algorithm was encoding this image?. If you know or can determine it, then you can create a reverse function. It's only i can help. It's good you create lut table for better performance.

    Regards David.

    ReplyDelete
  3. It's plain RGB, but no idea about the algorithm. The scale is similar to this one: http://www.efg2.com/Lab/Library/Color/AccuweatherRadarReflectivity.jpg

    So yes, I think I'll prepare a LUT table and that's all :)

    ReplyDelete
  4. The image is plain rgb, but you can use other color space to work, for example Lab space or HSV or similar because have some properties than others.

    The scale is simiar to this? http://en.wikipedia.org/wiki/Color_theory#Warm_vs._cool_colors

    ReplyDelete
  5. Well, something similar. Indeed, the scale is just the same that Hue values take in HSV, more like this:
    http://en.wikipedia.org/wiki/File:HSV-RGB-comparison.svg

    In fact, I also wanted to try those fuzzy logic sets to go from color to HUE. That would work too, I guess. There's no violet (no colors above 240º), so I would have no problem with circling colors...

    ReplyDelete
  6. Ok, just in case you need it, I think I have something useful here. I tried with LUTs, but finding the right bin is not trivial (color distances, you know). So I went back to HSV.

    The thing is, in HSV, that lower and higher V values produce undefined H values. Therefore, H is not enough to map from pseudocolor to gray.

    But you get a nice mapping if the gray value is given by the following expression:

    gray = (240.0 - HUE) * (240.0 - HUE) * V.

    Then you adjust the dynamic range back to 0-255.

    That way, low light values produce low gray values, high light values produce high gray values and middle tones are handled by HUE.

    That's of course if the pseudocolor map is similar to what we talked before: white-red (0 HUE)-yellow-green-cyan-blue (240 HUE)-black :)

    ReplyDelete
  7. Hello,
    What is the of the mapping function?
    Do you have any references for it?

    ReplyDelete
  8. Hi Olu, the mapping function is the above funcion on tutorial. In code i generat under pseudocolor.c a table with this function for all value colors 0..255 and i map the image with pseudocolor function.

    ReplyDelete
  9. hi..i want to map 8bit gray level image to pseudo color...in matlab...but i am not understanding how i determine the values...little what i got and i am not able to understand is this :

    clc;
    clear all;
    im=input('Enter the file name (gray level image) :','s');
    k=imread(im);
    [x y z]=size(k);
    figure, subplot(1,2,1),imshow(k), title('Original gray scale image');
    for i=1:x
    for j=1:y
    if k(i,j)>=0 & k(i,j)=5 & k(i,j)=10 & k(i,j)=15 & k(i,j)=20 & k(i,j)=25 & k(i,j)=30 & k(i,j)=35 & k(i,j)=40 & k(i,j)=45 & k(i,j)=50 & k(i,j)=55 & k(i,j)=60 & k(i,j)=65 & k(i,j)=70 & k(i,j)=75 & k(i,j)=80 & k(i,j)=85 & k(i,j)=90 & k(i,j)=95 & k(i,j)<100
    m(i,j,1)= 0.37;
    m(i,j,2)= 1;
    m(i,j,3)= 0.625;
    end
    please help me in understanding this code...how the values are working here..?

    ReplyDelete
  10. Hi!!!

    I couldn't download the source, is there any way that I can get it?

    Thanks,

    Johanna

    ReplyDelete
  11. HI, it's really nice information to me.
    I've been studying about Pseudo-Colour processing.
    I want to know about the reference of this content.
    please help me. ^^

    ReplyDelete
  12. Hi Damiles...nice blog hah!! especially for a beginner like me.

    Could you please email me the source code for this part?? I can't open the link..404 Not Found.I dont know why.

    mafifaz91@yahoo.com

    Thank you :)

    ReplyDelete
  13. awesome explanation but the link to the code's dead

    ReplyDelete
  14. The code is now in github and link is restored.

    ReplyDelete
  15. hi,I am processing five brown coloured objects ,among them one object is of different intensity (darker shade) than the others. I have to highlight that different object.I am working with HSV colour space.but the results are not accurate with different images taken in different illumination levels.(when the outer room light is less then all objects look similar). In the meanwhile I am looking whether fuzzy works out for my problem.can anyone help me in this problem?

    ReplyDelete