ISP自动白平衡:动态阈值算法Opencv C++实现


前言

最近学习了ISP自动白平衡-动态阈值算法,这里分享给大家。


1. 动态阈值算法步骤

动态阈值算法主要分为两步:白点检测与白点调整。

白点检测:

  1. 将图像转换到YCrCb颜色空间,然后对图像进行分块, 3 × 4 3\times 4 3×4共12块;
  2. 对每块统计Cr, Cb均值 M c r , M c b M_{cr}, M_{cb} Mcr,Mcb;
  3. 根据步骤2计算的均值统计每块Cr, Cb的方差 D c r , D c b D_{cr}, D_{cb} Dcr,Dcb,计算公式:
    D c r = 1 N ∑ ( C r ( i , j ) − M c r ) 2 D_{cr} = \frac{1}{N}\sum(Cr(i,j) - M_{cr})^{2} Dcr=N1(Cr(i,j)Mcr)2
    D c b = 1 N ∑ ( C b ( i , j ) − M c b ) 2 D_{cb} = \frac{1}{N}\sum(Cb(i,j) - M_{cb})^{2} Dcb=N1(Cb(i,j)Mcb)2
    上式 N N N表示当前分块的像素数量, C r ( i , j ) Cr(i,j) Cr(i,j)表示Cr通道像素位置 ( i , j ) (i,j) (i,j)的像素值
  4. 过滤掉 D c r , D c b D_{cr}, D_{cb} Dcr,Dcb数值较小的分块(这里数值为 0.01 0.01 0.01);
  5. 统计所有分块的 M c r , M c b , D c r , D c b M_{cr}, M_{cb}, D_{cr}, D_{cb} Mcr,Mcb,Dcr,Dcb的均值作为图像的均值和方差;
  6. 根据如下条件筛选候选白点并记录该白点的在图像上的索引:
    ∣ C r ( i , j ) − ( 1.5 ∗ M c r + D c r ) ∣ ≤ 1.5 ∗ D c r \lvert Cr(i,j) - (1.5*M_{cr} + D_{cr}) \rvert \leq 1.5*D_{cr} Cr(i,j)(1.5Mcr+Dcr)1.5D
  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
以下是基于OpenCV的灰度图像和彩色图像迭代阈值分割算法C++代码实现: 灰度图像迭代阈值分割: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; double thresholdValue(Mat& img) { double T = 0; double T_last = -1; int rows = img.rows; int cols = img.cols; int total = rows * cols; while(abs(T - T_last) > 1) { double sum1 = 0, sum2 = 0, count1 = 0, count2 = 0; for(int i = 0; i < rows; ++i) { for(int j = 0; j < cols; ++j) { if(img.at<uchar>(i, j) > T) { sum1 += img.at<uchar>(i, j); count1++; } else { sum2 += img.at<uchar>(i, j); count2++; } } } T_last = T; T = (sum1 / count1 + sum2 / count2) / 2; } return T; } int main() { Mat img = imread("lena.jpg", IMREAD_GRAYSCALE); if(img.empty()) { cout << "Could not read the image" << endl; return -1; } double T = thresholdValue(img); Mat dst; threshold(img, dst, T, 255, THRESH_BINARY); namedWindow("Original Image", WINDOW_NORMAL); namedWindow("Thresholded Image", WINDOW_NORMAL); imshow("Original Image", img); imshow("Thresholded Image", dst); waitKey(0); return 0; } ``` 彩色图像迭代阈值分割: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; double thresholdValue(Mat& img) { double T = 0; double T_last = -1; int rows = img.rows; int cols = img.cols; int total = rows * cols; while(abs(T - T_last) > 1) { double sum1 = 0, sum2 = 0, count1 = 0, count2 = 0; for(int i = 0; i < rows; ++i) { for(int j = 0; j < cols; ++j) { Vec3b pixel = img.at<Vec3b>(i, j); int gray = (pixel[0] + pixel[1] + pixel[2]) / 3; if(gray > T) { sum1 += gray; count1++; } else { sum2 += gray; count2++; } } } T_last = T; T = (sum1 / count1 + sum2 / count2) / 2; } return T; } int main() { Mat img = imread("lena.jpg"); if(img.empty()) { cout << "Could not read the image" << endl; return -1; } double T = thresholdValue(img); Mat dst; cvtColor(img, dst, COLOR_BGR2GRAY); threshold(dst, dst, T, 255, THRESH_BINARY); namedWindow("Original Image", WINDOW_NORMAL); namedWindow("Thresholded Image", WINDOW_NORMAL); imshow("Original Image", img); imshow("Thresholded Image", dst); waitKey(0); return 0; } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值