当前位置: 首页 > news >正文

ISP算法----AWB总结及源代码

摘要

AWB算法的必要性:对于彩色相机成像而言,AWB算法可以矫正颜色,视觉效果上看,颜色更符合人眼效果。
光学原理:人眼对于颜色具有恒常性。
从数学角度来看:所有AWB算法都是调节R,G,B三通道的增益值;所有手动调节白平衡便是人工输入三通道的增益值。

GW世界灰度法

基于假设:任何一幅图像,R,G,B分量的均值趋于一致;
目标:R_mean=G_mean=B_mean;
具体实现步骤:

  1. 先求R,G,B三通道的均值Rmean,Gmean,Bmean;

  2. 求解rGain,bGain,调节R,B通道趋于Gmean值;(三通道中G通道所占比例尤为重要,也会影响到灰度);

  3. rGain = Gmean/Rmean;
    bGain = Gmean/Bmean;

  4. 使用增益值,更新R,B通道;
    R_new = RrGain;
    B_new = B
    bGain;
    matlab源代码:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代码---AWB算法的灰度世界算法(GW法)
%Author:Zhu
%时间:2022.7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear;
close all;
%%%读取一个RGB图
clc;
image = imread("E:\1.bmp");
[height,width,channels]=size(image);

figure;
imshow(image);
title('Color image');

image_R=image(:,:,1);
image_R=double(image_R);
image_G=image(:,:,2);
image_G=double(image_G);
image_B=image(:,:,3);
image_B=double(image_B);

%%%求解的新通道矩阵
R_image = zeros(height,width);
G_image = zeros(height,width);
B_image = zeros(height,width);

%%%先求三通道R,G,B的平均值
Rmean = mean(mean(image_R));
Gmean = mean(mean(image_G));
Bmean = mean(mean(image_B));

%%%再求三通道与绿色通道的比例关系,这里采用的是全局的比值关系
rGain = Gmean/Rmean;
bGain = Gmean/Bmean;

%%%遍历RGB像素点
for i=1:1:height
    for j=1:1:width
       R_image(i,j) = rGain*image_R(i,j);
       G_image(i,j) = image_G(i,j);
       B_image(i,j) = bGain*image_B(i,j);
    end
end

B_image = uint8(B_image);
R_image = uint8(R_image);
G_image = uint8(G_image);

%%%将三个矩阵叠加显示颜色
figure;
out_image=cat(3,R_image,G_image,B_image);
imshow(cat(3,R_image,G_image,B_image));
title('GW image');

效果图
在这里插入图片描述
在这里插入图片描述

C++ 源代码

void AWB_RGB(unsigned char *srcData,unsigned char *rgbData,int height,int width)
{
   //输入图像的char以RGB排列,输出也以RGB排列(OpenCV中Mat类型三通道呈一维数组排列,排列顺序是BGR)
   //先统计每个通道内的平均值
   unsigned long long R_count = 0;
   unsigned long long G_count = 0;
   unsigned long long B_count = 0;
   for(int i = 0; i<height*width*3;i+=3)
   {
      //r通道总值
      R_count = *(srcData + i);
      //g通道总值
      G_count = *(srcData + i + 1);
      //b通道总值
      B_count = *(srcData + i + 2);
   }
   //求解各通道的Gain
   float R_Gain = G_count*1.0/R_count;
   float B_Gain = G_count*1.0/B_count;
   for(int i = 0; i<height*width*3;i+=3)
   {
      //目前输出以RGB的形式
      //更新R通道的值
      *(rgbData + i) = (R_Gain*(*(srcData + i)))>255?255:(R_Gain*(*(srcData + i)));
      //g通道总值
      *(rgbData + i + 1) = *(srcData + i + 1);
      //b通道总值
      *(rgbData + i + 2) = (B_Gain*(*(srcData + i +2)))>255?255:(B_Gain*(*(srcData + i +2)));
   } 
}

完美反射法

基于假设:一幅图像中最亮的点包含很多场景信息;亮点相当于有光泽或者镜面上的点;镜面点本身不吸收光线,其反射的颜色即为光源真实颜色;
具体实现步骤:

  1. 先求R,G,B三通道最大值Rmax,Gmax,Bmax;

  2. 再求rGain,bGain,gGain,对每个通道调节;

  3. rGain = max(Rmax,Gmax,Bmax)/Rmax;
    gGain = max(Rmax,Gmax,Bmax)/Gmax;
    bGain = max(Rmax,Gmax,Bmax)/Bmax;

  4. 使用增益值,更新R,G,B通道;
    R_new = R * rGain;
    G_new = G * gGain;
    B_new = B * bGain;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代码---AWB算法的完美反射算法
%Author:zhu
%时间:2022.7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear;
close all;
%%%读取一个RGB图
clc;
image = imread("E:\1.bmp");
[height,width,channels]=size(image);

figure;
imshow(image);
title('Color image');

image_R=image(:,:,1);
image_R=double(image_R);
image_G=image(:,:,2);
image_G=double(image_G);
image_B=image(:,:,3);
image_B=double(image_B);

%%%求解的新通道矩阵
R_image = zeros(height,width);
G_image = zeros(height,width);
B_image = zeros(height,width);

%%%先求三通道R,G,B的最大值
Rmax = max(max(image_R));
Gmax = max(max(image_G));
Bmax = max(max(image_B));

%%%再求每个通道最大值与最大值之间的比例关系,这里采用的是通道之间最大比例值关系
Gain_R = max([Rmax,Gmax,Bmax])/Rmax;
Gain_G = max([Rmax,Gmax,Bmax])/Gmax;
Gain_B = max([Rmax,Gmax,Bmax])/Bmax;

%%%遍历RGB像素点
for i=1:1:height
    for j=1:1:width
       R_image(i,j) = Gain_R*image_R(i,j);
       G_image(i,j) = Gain_G*image_G(i,j);
       B_image(i,j) = Gain_B*image_B(i,j);
    end
end

B_image = uint8(B_image);
R_image = uint8(R_image);
G_image = uint8(G_image);

%%%将三个矩阵叠加显示颜色
figure;
out_image=cat(3,R_image,G_image,B_image);
imshow(cat(3,R_image,G_image,B_image));
title('PR image');

效果图
在这里插入图片描述
在这里插入图片描述

GCPR算法

融合GW算法和完美反射法,采用正交分解的思路,对两种算法计算参数
在这里插入图片描述

  1. 先求R,G,B三通道最大值和平均值Rmax,Gmax,Bmax,Rmean,Gmean,Bmean

  2. Kmean = (Rmean+Gmean+Bmean)/3;
    Kmax = (Rmax+Gmax+Bmax)/3;

  3. 再求三通道对应的u,v值;
    在这里插入图片描述

  4. 更新R,G,B通道
    在这里插入图片描述

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代码---AWB算法的GCPR算法
%Author:zhu
%时间:2022.7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
clear;
close all;
%%%读取一个RGB图
clc;
image = imread("E:\1.bmp");
[height,width,channels]=size(image);

figure;
imshow(image);
title('Color image');

image_R=image(:,:,1);
image_R=double(image_R);
image_G=image(:,:,2);
image_G=double(image_G);
image_B=image(:,:,3);
image_B=double(image_B);

%%%求解的新通道矩阵
R_image = zeros(height,width);
G_image = zeros(height,width);
B_image = zeros(height,width);

%%%先求解每个通道的最大值和平均值
R_mean = mean(mean(image_R));
G_mean = mean(mean(image_G));
B_mean = mean(mean(image_B));

R_max = max(max(image_R));
G_max = max(max(image_G));
B_max = max(max(image_B));

K_mean = (R_mean + G_mean + B_mean)/3;
K_max = (R_max + G_max + B_max)/3;

%%%R通道下正交分解求解u,v
X = [R_mean*R_mean,R_mean;R_max*R_max,R_max]\[K_mean,K_max]';
U_r = X(1);
V_r = X(2);
%%%G通道下正交分解求解u,v
X = [G_mean*G_mean,G_mean;G_max*G_max,G_max]\[K_mean,K_max]';
U_g = X(1);
V_g = X(2);
%%%B通道下正交分解求解u,v
X = [B_mean*B_mean,B_mean;B_max*B_max,B_max]\[K_mean,K_max]';
U_b = X(1);
V_b = X(2);

%%%遍历RGB像素点,求解新的R,G,B值
for i=1:1:height
    for j=1:1:width
       R_image(i,j)=U_r*image_R(i,j)*image_R(i,j)+V_r*image_R(i,j);
       G_image(i,j)=U_g*image_G(i,j)*image_G(i,j)+V_g*image_G(i,j);
       B_image(i,j)=U_b*image_B(i,j)*image_B(i,j)+V_b*image_B(i,j);
    end
end

R_image = uint8(R_image);
G_image = uint8(G_image);
B_image = uint8(B_image);

%%%将三个矩阵叠加显示颜色
figure;
imshow(cat(3,R_image,G_image,B_image));
title('QCGP image');

图像效果
在这里插入图片描述
在这里插入图片描述

相关文章:

  • 【Java基础(六)】面向对象与类的基础知识
  • Python爬虫——BeautifulSoup的基本使用
  • Acwing 802. 区间和
  • 传统方式连接数据库的弊端和数据库连接池原理
  • 什么叫 “雪碧图”?
  • 公众号网课搜题题库使用方法
  • Excel中身份证号码相关操作详解
  • 如何用4行 C 代码实现一个跨平台的命令行 mp3 播放器
  • ES 查询用法
  • golang泛型
  • 如何快速安装JDK 1.8 以及配置环境变量
  • DataGrip 如何导出和恢复整个数据库数据,使用单个 SQL 文件
  • 基于SpringBoot+MyBatisPlus+DynamicDatasource+mysql的多数据源本地事务方案
  • 计算机毕业设计ssm+vue基本微信的健康食谱交流 论坛小程序
  • 天龙八部科举答题问题和答案(全5/8)
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 2017-09-12 前端日报
  • egg(89)--egg之redis的发布和订阅
  • happypack两次报错的问题
  • Yii源码解读-服务定位器(Service Locator)
  • 大快搜索数据爬虫技术实例安装教学篇
  • 对象引论
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 那些年我们用过的显示性能指标
  • 日剧·日综资源集合(建议收藏)
  • 设计模式走一遍---观察者模式
  • 使用 Docker 部署 Spring Boot项目
  • 我的zsh配置, 2019最新方案
  • 与 ConTeXt MkIV 官方文档的接驳
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 回归生活:清理微信公众号
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #QT(串口助手-界面)
  • $GOPATH/go.mod exists but should not goland
  • $refs 、$nextTic、动态组件、name的使用
  • ()、[]、{}、(())、[[]]命令替换
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (4.10~4.16)
  • (a /b)*c的值
  • (C语言)fread与fwrite详解
  • (windows2012共享文件夹和防火墙设置
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (三)uboot源码分析
  • (译) 函数式 JS #1:简介
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • *1 计算机基础和操作系统基础及几大协议