实现函数代码:
1 /****************************************/ 2 /* 实现自动对比度的函数 */ 3 /* 目前只有前后中通道调用 */ 4 /* 彩色的已经加入到了函数内部 */ 5 /*****************************************/ 6 void BrightnessAndContrastAuto(const cv::Mat &src, cv::Mat &dst, float clipHistPercent) 7 { 8 CV_Assert(clipHistPercent >= 0); 9 CV_Assert((src.type() == CV_8UC1) || (src.type() == CV_8UC3) || (src.type() == CV_8UC4)); 10 11 int histSize = 256; 12 float alpha, beta; 13 double minGray = 0, maxGray = 0; 14 15 //to calculate grayscale histogram 16 cv::Mat gray; 17 if (src.type() == CV_8UC1) gray = src; 18 else if (src.type() == CV_8UC3) cvtColor(src, gray, CV_BGR2GRAY); 19 else if (src.type() == CV_8UC4) cvtColor(src, gray, CV_BGRA2GRAY); 20 if (clipHistPercent == 0) 21 { 22 // keep full available range 23 cv::minMaxLoc(gray, &minGray, &maxGray); 24 } 25 else 26 { 27 cv::Mat hist; //the grayscale histogram 28 29 float range[] = { 0, 256 }; 30 const float* histRange = { range }; 31 bool uniform = true; 32 bool accumulate = false; 33 cv::calcHist(&gray, 1, 0, cv::Mat (), hist, 1, &histSize, &histRange, uniform, accumulate); 34 35 // calculate cumulative distribution from the histogram 36 std::vector<float> accumulator(histSize); 37 accumulator[0] = hist.at<float>(0); 38 for (int i = 1; i < histSize; i++) 39 { 40 accumulator[i] = accumulator[i - 1] + hist.at<float>(i); 41 } 42 43 // locate points that cuts at required value 44 float max = accumulator.back(); 45 clipHistPercent *= (max / 100.0); //make percent as absolute 46 clipHistPercent /= 2.0; // left and right wings 47 // locate left cut 48 minGray = 0; 49 while (accumulator[minGray] < clipHistPercent) 50 minGray++; 51 52 // locate right cut 53 maxGray = histSize - 1; 54 while (accumulator[maxGray] >= (max - clipHistPercent)) 55 maxGray--; 56 } 57 58 // current range 59 float inputRange = maxGray - minGray; 60 61 alpha = (histSize - 1) / inputRange; // alpha expands current range to histsize range 62 beta = -minGray * alpha; // beta shifts current range so that minGray will go to 0 63 64 // Apply brightness and contrast normalization 65 // convertTo operates with saurate_cast 66 src.convertTo(dst, -1, alpha, beta); 67 68 // restore alpha channel from source 69 if (dst.type() == CV_8UC4) 70 { 71 int from_to[] = { 3, 3}; 72 cv::mixChannels(&src, 4, &dst,1, from_to, 1); 73 } 74 return; 75 }