void brightness_and_constrast_auto(const cv::Mat& src, cv::Mat& dst, float clip_hist_percent)
{
CV_Assert(clip_hist_percent >= 0);
CV_Assert(src.type()==CV_8UC1);
int hist_size = 256;
float alpha=0.0;
float beta = 0.0;
double min_gray = 0;
double max_gray = 0;
if(0 == clip_hist_percent)
{
cv::minMaxLoc(src, &min_gray, &max_gray);
}
else
{
cv::Mat hist; /// the grayscale histogram
float rang[] = {0, 256};
const float* hist_range = {rang};
bool uniform = true;
bool accumulate = false;
cv::calcHist(&src, 1, 0, cv::Mat(), hist, 1, &hist_size, &hist_range, uniform, accumulate);
std::vector<float> accumulator(hist_size);
accumulator[0] = hist.at<float>(0);
for(int i = 1; i < hist_size; i++)
{
accumulator[i] = accumulator[i-1] + hist.at<float>(i);
}
float max = accumulator.back();
clip_hist_percent *= (max/100.0); /// make percent a absolute
clip_hist_percent /= 2.0; /// left and right wings
while(accumulator[min_gray] < clip_hist_percent)
{
min_gray++;
}
max_gray = hist_size - 1;
while (accumulator[max_gray] >= (max - clip_hist_percent))
{
max_gray--;
}
}
alpha = (hist_size - 1)/(float)(max_gray -min_gray);
beta = -min_gray * alpha;
src.convertTo(dst, -1, alpha, beta);
return;
}