Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

/* Do you want to cut (collapse to black) dark regions or remove (restore image) shadows ?

Shadow removal is a complex task. Use "shadow" in the search box here to read about this subject .

I don't know if @thienlamnhan 's code for detect shadow works. In addiction read this:

Use histEqualization to enhance bright vs dark region.

To collapse dark regions to full black you could use same principle of brightness and contrast normalization */

cvtColor(src, gray, CV_BGR2GRAY);
// get full available range
double minGray,maxGray;
cv::minMaxLoc(gray, &minGray, &maxGray);
//suppose current range is 30...220

bool useRelative = true;
if(useRelative)
{
    // Relative clipping dark range to black
    double clipPercent = 10; 
    minGray = cvRound(minGray * (1 + clipPercent/100.0) );
    //all below minGray+10% will become black
}
else
{
    //absolute clipping. Use a fixed lower bound for dark regions
    double minGrayWanted = 50; 
    minGray = minGrayWanted;
    //all below 50 will become black
}

// current range
float inputRange = maxGray - minGray;

alpha = 255.0 / inputRange; // alpha expands current range. MaxGray will be 255
beta = -minGray * alpha;    // beta shifts current range so that minGray will go to 0

src.convertTo(dst, -1, alpha, beta);

Result will be:

src[0...minGray] -> dst[0]
src[minGray...maxGray] -> src[0...255]

/* Do you want to cut (collapse to black) dark regions or remove (restore image) shadows ?

Shadow removal is a complex task. Use "shadow" in the search box here to read about this subject .

I don't know if @thienlamnhan 's code for detect shadow works. In addiction read this:

Use histEqualization to enhance bright vs dark region.

To collapse dark regions to full black you could use same principle of brightness and contrast normalization */normalization

cvtColor(src, gray, CV_BGR2GRAY);
// get full available range
double minGray,maxGray;
cv::minMaxLoc(gray, &minGray, &maxGray);
//suppose current range is 30...220

bool useRelative = true;
if(useRelative)
{
    // Relative clipping dark range to black
    double clipPercent = 10; 
    minGray = cvRound(minGray * (1 + clipPercent/100.0) );
    //all below minGray+10% will become black
}
else
{
    //absolute clipping. Use a fixed lower bound for dark regions
    double minGrayWanted = 50; 
    minGray = minGrayWanted;
    //all below 50 will become black
}

// current range
float inputRange = maxGray - minGray;

alpha = 255.0 / inputRange; // alpha expands current range. MaxGray will be 255
beta = -minGray * alpha;    // beta shifts current range so that minGray will go to 0

src.convertTo(dst, -1, alpha, beta);

Result will be:

src[0...minGray] -> dst[0]
src[minGray...maxGray] -> src[0...255]

[EDIT] from user comment It seems needs is to correct nonuniform illumination. In this case MORPH_TOPHAT can do the job. See my answer on this subject.

Do you want to cut (collapse to black) dark regions or remove (restore image) shadows ?

Shadow removal is a complex task. Use "shadow" in the search box here to read about this subject .

I don't know if @thienlamnhan 's code for detect shadow works. In addiction read this:

Use histEqualization to enhance bright vs dark region.

To collapse dark regions to full black you could use same principle of brightness and contrast normalization

cvtColor(src, gray, CV_BGR2GRAY);
// get full available range
double minGray,maxGray;
cv::minMaxLoc(gray, &minGray, &maxGray);
//suppose current range is 30...220

bool useRelative = true;
if(useRelative)
{
    // Relative clipping dark range to black
    double clipPercent = 10; 
    minGray = cvRound(minGray * (1 + clipPercent/100.0) );
    //all below minGray+10% will become black
}
else
{
    //absolute clipping. Use a fixed lower bound for dark regions
    double minGrayWanted = 50; 
    minGray = minGrayWanted;
    //all below 50 will become black
}

// current range
float inputRange = maxGray - minGray;

alpha = 255.0 / inputRange; // alpha expands current range. MaxGray will be 255
beta = -minGray * alpha;    // beta shifts current range so that minGray will go to 0

src.convertTo(dst, -1, alpha, beta);

Result will be:

src[0...minGray] -> dst[0]
src[minGray...maxGray] -> src[0...255]

[EDIT] from user comment It seems that needs is to correct nonuniform illumination. illumination. In this case MORPH_TOPHAT can do the job. See my answer on this subject.