【图像增强】自适应亮度对比度调节算法C++

参考

亮度和对比度调节公式,其中alpha负责对比度,beta负责亮度。

O(x,y) = alpha * I(x,y) + beta

如果想要自动调节亮度和对比度,意味着自动调节 alphabeta
假如想要将最小值变到0,最大值变为255,则计算公式如下。

input range = max(I) - min(I)
wanted output range = 255;
alpha = output range / input range = 255 / ( max(I) - min(I) )
min(O) = alpha * min(I) + beta
beta = -min(I) * alpha

直方图剪枝平移

  • 平移 -> 亮度
  • 剪枝 -> 重定义直方图的范围

下面的图以供理解
在这里插入图片描述

代码实现

这里我增加了两个参数,用以调节亮度最低值和直方图的范围

// clipHistPercent 剪枝(剪去总像素的多少百分比)
// histSize 最后将所有的灰度值归到多大的范围
// lowhist 最小的灰度值
void BrightnessAndContrastAuto(const cv::Mat &src, cv::Mat &dst, float clipHistPercent=0, int histSize = 255, int lowhist = 0)
{
    
    CV_Assert(clipHistPercent >= 0);
    CV_Assert((src.type() == CV_8UC1) || (src.type() == CV_8UC3) || (src.type() == CV_8UC4));
    
    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 (clipHistPercent == 0)
    {
        // keep full available range
        cv::minMaxLoc(gray, &minGray, &maxGray);
    }
    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, cv::Mat (), 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();
        
        int clipHistPercent2;
        clipHistPercent2 = clipHistPercent * (max / 100.0); //make percent as absolute
        clipHistPercent2 /= 2.0; // left and right wings
        // locate left cut
        minGray = 0;
        while (accumulator[minGray] < clipHistPercent2)
            minGray++;
        
        // locate right cut
        maxGray = histSize - 1;
        while (accumulator[maxGray] >= (max - clipHistPercent2))
            maxGray--;
    }
    
    // current range
    float inputRange = maxGray - minGray;
    
    alpha = (histSize - 1) / inputRange;   // alpha expands current range to histsize range
    beta = -minGray * alpha + lowhist;             // beta shifts current range so that minGray will go to 0
    
    // 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);
    }
}
  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
相机自适应曝光调节算法是一种用于调整相机曝光时间的算法。该算法根据当前场景的亮度来自动调整相机的曝光时间,以确保拍摄出的图像亮度对比度良好。 以下是C++实现该算法的示例代码: ```c++ #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main(int argc, char** argv) { // 打开摄像头 VideoCapture cap(0); if (!cap.isOpened()) { cerr << "Failed to open camera!" << endl; return -1; } // 设定曝光时间范围 int minExposure = cap.get(CAP_PROP_EXPOSURE); int maxExposure = cap.get(CAP_PROP_EXPOSURE) * 4; int exposure = minExposure; // 设定目标亮度范围 int targetBrightness = 128; int minBrightness = targetBrightness - 20; int maxBrightness = targetBrightness + 20; while (true) { Mat frame; cap >> frame; if (frame.empty()) { break; } // 计算当前帧的亮度 Mat gray; cvtColor(frame, gray, COLOR_BGR2GRAY); int brightness = static_cast<int>(mean(gray)[0]); // 根据亮度调整曝光时间 if (brightness < minBrightness) { exposure += 10; } else if (brightness > maxBrightness) { exposure -= 10; } exposure = max(min(exposure, maxExposure), minExposure); cap.set(CAP_PROP_EXPOSURE, exposure); // 显示当前帧 imshow("Frame", frame); // 按 'q' 键退出程序 if (waitKey(1) == 'q') { break; } } cap.release(); destroyAllWindows(); return 0; } ``` 在该示例代码中,我们首先打开了摄像头,并设定了曝光时间和目标亮度范围。然后,在每一帧图像中,我们计算了当前场景的亮度,并根据当前亮度来调整曝光时间。最后,我们显示了当前帧,并等待用户按下 'q' 键退出程序。 需要注意的是,相机自适应曝光调节算法是一种简单的算法,在实际应用中可能需要根据实际情况进行调整和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值