Levels with opencv

Hi, i want to do something similar to the levels function in Photoshop, but can’t find the right openCV functions.

Basically I want to crop the bottom end and top end, and have the remaining colors stretched to fill the full spectrum. So similar to this:

cvThreshold(greyNow.getCvImage(), greyNow.getCvImage(), bottomThreshold, 255, CV_THRESH_TOZERO);  
cvThreshold(greyNow.getCvImage(), greyNow.getCvImage(), topThreshold, 255, CV_THRESH_TRUNC);  

I guess I could do it with the above two thresholds, then a subtraction, then a scale… but thats 4 passes, is there a function that does this in fewer passes?

maybe a look up table is good for you?

void cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );  

basically, allows you to precompute a transform for all pixels in a look up table, etc

unsigned char LUT [] = {3,4,7....  

a pixel with a value of 0, after the LUT will have a value of 3, a pixel with a value of 1 will have a value of 4, 2 will have a value of 7, etc…

downside is you do it yourself, the upside is that it’s one pass

take care!

HI Zach, I just found cvNormalize and was playing with that

void cvNormalize( const CvArr* src, CvArr* dst,  
                  double a=1, double b=0, int norm_type=CV_L2,  
                  const CvArr* mask=NULL )  

Which kind of works when you give wide a and b values and CV_MINMAX for norm_type… but cvLut looks a lot more powerful and can probably do all kinds of gamma and curves adjustments, thanks!

I’ve been looking for something that does levels too :slight_smile:

Thanks zach!

Memo, if you settle on a final version can you post your code/results?

nice – I’m glad that’s helpful ! I’ve found look up tables very useful for doing pixel adjustments.

fyi, there is a good example of using the LUT approach for brightness contrast here:


take care!

The LUT stuff is brilliant. I started implementing a photoshop-curves type thing but got carried away with the UI and put it on hold as I found myself digressing - but will revisit that when I get a chance. I normally use ofxSimpleGUI for all tweaking and calibration, but there is no callback when a slider changes, so to not calculate the LUT everyframe but only when an input value changes is a bit of a problem for me right now.

This is my code right now (before using a LUT) which does pretty much everything I need to, but in loads of passes (if they are all on). Using a LUT you could do all of these in one go.

if(params.brightness) cvScale(greyNow.getCvImage(), greyNow.getCvImage(), params.brightness * params.brightness);	// brightness 0...1  
if(params.bottomThreshold) cvThreshold(greyNow.getCvImage(), greyNow.getCvImage(), params.bottomThreshold, 255, CV_THRESH_TOZERO);  
if(params.topThreshold) cvThreshold(greyNow.getCvImage(), greyNow.getCvImage(), 255-params.topThreshold, 255, CV_THRESH_TRUNC);  
if(params.normalize) cvNormalize(greyNow.getCvImage(), greyNow.getCvImage(), 255+10*params.topThreshold, -10*params.bottomThreshold, CV_MINMAX, NULL);	// the 10* is just an empirical hack  
if(params.adaptiveThreshold) cvAdaptiveThreshold(greyNow.getCvImage(), greyNow.getCvImage(), 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, params.adaptiveBlockSize, params.adaptiveThreshold);  
if(params.invert) greyNow.invert();