Ask Your Question
3

Improve contrast of a 16U image

asked Oct 15 '12

andrea.delbravo gravatar image

updated Oct 17 '12

Kirill Kornyakov gravatar image

Hello, I'm very new to OpenCV. My question is: I need to enhance contrast of an IR image. I tried to use the cvEqualizeHist C function and the equalizeHist C++ function, but I understood they both work on 8 bit data, whilst my pixel data (one channel) are 16 bit (CV_16UC1). Is it possible to improve contrast in my image in some other way? Thanks a lot Andrea

Update: Thanks a lot, I followed the suggestion but still I've some problems. The source matrix had all values in a very small interval (so the results was an almost gray image). I expected that after applying the normalize function, the values were scaled between the min and max, but the result was similar to the source matrix: the values are still in a very small interval (shifted at a higher value respect the original matrix); the result is a similar image but a little bit brighter. Where am I wrong?

Preview: (hide)

2 answers

Sort by » oldest newest most voted
3

answered Oct 15 '12

Michael Burdinov gravatar image

If I am not mistaken image normalization in OpenCV is not limited to 8 bit data. See its description here. In your case call to function should look like:

normalize(src_image, dst_image, 0, 65535, NORM_MINMAX);

Anyway, if you are trying to improve contrast of image first try normalization and only if this is not working try equalization. Normalization is faster and less destructive.

Preview: (hide)

Comments

It's worth noting that equalizeHist() takes advantage of the limited char resolution and greatly improves the processing time. normalize() does the same thing on any image depth, but it's significantly slower.

sammy gravatar imagesammy (Oct 16 '12)edit

Thanks a lot, I followed the suggestion but still I've some problems. The source matrix had all values in a very small interval (so the results was an almost gray image). I expected that after applying the normalize function, the values were scaled between the min and max, but the result was similar to the source matrix: the values are still in a very small interval (shifted at a higher value respect the original matrix); the result is a similar image but a little bit brighter.
Where am I wrong?

andrea.delbravo gravatar imageandrea.delbravo (Oct 16 '12)edit
1

I guess your original image is not in small interval but also have values near 0 or 65535. Thus normalization can't stretch it too much. Check borders of your image, because they are often set to zero by many cameras.

Michael Burdinov gravatar imageMichael Burdinov (Oct 16 '12)edit
1

I solved the problem providing a simple algorithm: most of the data where in a very narrow interval but very few pixels outside the interval, as you correctly supposed. I set two threshold, min and max, and for every pixel below min I set the value to zero, and for every pixel upper than max I set the value to max (just to increase the dynamic of image). After this process only pixel between min and max are present. After that, I scaled their values between 0 and 65535. I put also two sliders to set up min and max, and the results was really fantastic....For sure there is some automatic functio in openCv to do that....I wiil learn it in the future, but openCV is really superb. It allowed me with a minimum trainig to achieve a real valuable results

andrea.delbravo gravatar imageandrea.delbravo (Oct 16 '12)edit
0

answered Oct 16 '12

elmiguelao gravatar image

If the image looks very grey, you could also try applying the equalizeHist on YUV image - Y channel, note that this will change the colours of the image but it might make it visually/computationally better (in some sense). A code snippet to try quickly (all _ptr are pointers to IplImage):

cvCvtColor( RGB_image_ptr, YUV_image_ptr, CV_RGB2YUV );
cvSplit( YUV_image_ptr, Ychannel_image_ptr, Uchannel_image_ptr, Vchannel_image_ptr, NULL);

cvEqualizeHist(Ychannel_image_ptr, Ychannel_image_ptr);

cvMerge( Ychannel_image_ptr, Uchannel_image_ptr, Vchannel_image_ptr, NULL, YUV_image_ptr);
cvCvtColor( YUV_image_ptr, RGB_image_ptr, CV_YUV2RGB );
Preview: (hide)

Question Tools

Stats

Asked: Oct 15 '12

Seen: 7,831 times

Last updated: Oct 17 '12