实现函数代码:
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 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)