mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-10 21:40:19 +08:00
Updated detect more loop closures with optimization check to accept (like in dbviewer). DBViewer: added Depth image edition dialog. GainCompensator: now doing it on 3 channels separatly. Export: removed gain's alpha option, added max polygons option, added brightness/contrast auto balance option
This commit is contained in:
@@ -1909,6 +1909,89 @@ cv::Mat fastBilateralFiltering(const cv::Mat & depth, float sigmaS, float sigmaR
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Automatic brightness and contrast optimization with optional histogram clipping
|
||||
* \param [in]src Input image GRAY or BGR or BGRA
|
||||
* \param [out]dst Destination image
|
||||
* \param clipHistPercent cut wings of histogram at given percent typical=>1, 0=>Disabled
|
||||
* \note In case of BGRA image, we won't touch the transparency
|
||||
* See http://answers.opencv.org/question/75510/how-to-make-auto-adjustmentsbrightness-and-contrast-for-image-android-opencv-image-correction/
|
||||
*/
|
||||
cv::Mat brightnessAndContrastAuto(const cv::Mat &src, const cv::Mat & mask, float clipLowHistPercent, float clipHighHistPercent)
|
||||
{
|
||||
|
||||
CV_Assert(clipLowHistPercent >= 0 && clipHighHistPercent>=0);
|
||||
CV_Assert((src.type() == CV_8UC1) || (src.type() == CV_8UC3) || (src.type() == CV_8UC4));
|
||||
|
||||
int histSize = 256;
|
||||
float alpha, beta;
|
||||
double minGray = 0, maxGray = 0;
|
||||
|
||||
//to calculate grayscale histogram
|
||||
cv::Mat gray;
|
||||
if (src.type() == CV_8UC1) gray = src;
|
||||
else if (src.type() == CV_8UC3) cvtColor(src, gray, CV_BGR2GRAY);
|
||||
else if (src.type() == CV_8UC4) cvtColor(src, gray, CV_BGRA2GRAY);
|
||||
if (clipLowHistPercent == 0 && clipHighHistPercent == 0)
|
||||
{
|
||||
// keep full available range
|
||||
cv::minMaxLoc(gray, &minGray, &maxGray, 0, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat hist; //the grayscale histogram
|
||||
|
||||
float range[] = { 0, 256 };
|
||||
const float* histRange = { range };
|
||||
bool uniform = true;
|
||||
bool accumulate = false;
|
||||
calcHist(&gray, 1, 0, mask, hist, 1, &histSize, &histRange, uniform, accumulate);
|
||||
|
||||
// calculate cumulative distribution from the histogram
|
||||
std::vector<float> accumulator(histSize);
|
||||
accumulator[0] = hist.at<float>(0);
|
||||
for (int i = 1; i < histSize; i++)
|
||||
{
|
||||
accumulator[i] = accumulator[i - 1] + hist.at<float>(i);
|
||||
}
|
||||
|
||||
// locate points that cuts at required value
|
||||
float max = accumulator.back();
|
||||
clipLowHistPercent *= (max / 100.0); //make percent as absolute
|
||||
clipHighHistPercent *= (max / 100.0); //make percent as absolute
|
||||
// locate left cut
|
||||
minGray = 0;
|
||||
while (accumulator[minGray] < clipLowHistPercent)
|
||||
minGray++;
|
||||
|
||||
// locate right cut
|
||||
maxGray = histSize - 1;
|
||||
while (accumulator[maxGray] >= (max - clipHighHistPercent))
|
||||
maxGray--;
|
||||
}
|
||||
|
||||
// current range
|
||||
float inputRange = maxGray - minGray;
|
||||
|
||||
alpha = (histSize - 1) / inputRange; // alpha expands current range to histsize range
|
||||
beta = -minGray * alpha; // beta shifts current range so that minGray will go to 0
|
||||
|
||||
UINFO("minGray=%f maxGray=%f alpha=%f beta=%f", minGray, maxGray, alpha, beta);
|
||||
|
||||
cv::Mat dst;
|
||||
// Apply brightness and contrast normalization
|
||||
// convertTo operates with saurate_cast
|
||||
src.convertTo(dst, -1, alpha, beta);
|
||||
|
||||
// restore alpha channel from source
|
||||
if (dst.type() == CV_8UC4)
|
||||
{
|
||||
int from_to[] = { 3, 3};
|
||||
cv::mixChannels(&src, 4, &dst,1, from_to, 1);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user