数字图像基本处理——白平衡(color balance)

下面介绍两种简单的处理图像色彩平衡问题的算法,色彩平衡就是说将一张图片中RGB三个通道的值处理的相对均衡,也就是将图像中物体原本的颜色恢复出来,而不是在光照或者阳光下变色。

算法1:White Balance

 matlab实现如下:

function res = WhiteBalance(img)
RGB=imread(img);
R=RGB(:,:,1);
G=RGB(:,:,2);
B=RGB(:,:,3);
I=0.299*R+0.587*G+0.114*B;
kr=mean(I(:))/mean(R(:));
kg=mean(I(:))/mean(G(:));
kb=mean(I(:))/mean(B(:));
% res(:,:,1)=kr*R;
% res(:,:,2)=kg*G;
% res(:,:,3)=kb*B;
res=cat(3,kr*R,kg*G,kb*B);
end

算法2:Maximum Value Balance

TR,TG,TB的含义:首先统计三个通道中高于SRGB的强度的个数,找到最大个数为Nmax,最后在每个通道中找到第Nmax个最大的强度值(也就是从大到小排序第Nmax个值)分别为TR,TG,TB

 matlab实现如下:

function res = MaxValueBalance(img)
RGB=imread(img);
R=RGB(:,:,1);
% figure, imhist(R);
G=RGB(:,:,2);
% figure, imhist(G);
B=RGB(:,:,3);
% figure, imhist(B);
Srgb=min([max(R(:)) max(G(:)) max(B(:))]);
Nmax=max([sum(sum(R>=Srgb)) sum(sum(G>=Srgb)) sum(sum(B>=Srgb))]);
Tr_temp=sort(R(:),'descend');
Tr=Tr_temp(Nmax);
Tg_temp=sort(G(:),'descend');
Tg=Tg_temp(Nmax);
Tb_temp=sort(B(:),'descend');
Tb=Tb_temp(Nmax);
kr=Srgb/Tr;
kg=Srgb/Tg;
kb=Srgb/Tb;
% res(:,:,1)=kr*R;
% res(:,:,2)=kg*G;
% res(:,:,3)=kb*B;
res=cat(3,kr*R,kg*G,kb*B);
end

最后主函数测试一些示例图片,主函数如下:

clear;close all;clc;
addpath('E:Digital_img_processingLecture_3_dicussion_color_balance');
fig1='BW1.png';
fig2='BW2.png';
fig3='BW3.jpg';
wb_algorithm3=WhiteBalance(fig3);
% wb_algorithm2=WhiteBalance(fig2);
% wb_algorithm1=WhiteBalance(fig1);
% 
figure, imshow(wb_algorithm3);
title('White Balance algorithm 3');
% figure, imshow(wb_algorithm2);
% title('White Balance algorithm 2');
% figure, imshow(wb_algorithm1);
% title('White Balance algorithm 1');

% mvb_algorithm3=MaxValueBalance(fig3);
% mvb_algorithm2=MaxValueBalance(fig2);
% mvb_algorithm1=MaxValueBalance(fig1);

% figure, imshow(mvb_algorithm3);
% title('Max Value Balance algorithm 3');
% figure, imshow(mvb_algorithm2);
% title('Max Value Balance algorithm 2');
% figure, imshow(mvb_algorithm1);
% title('Max Value Balance algorithm 1');

测试结果如下:

算法1(输入->输出):

 

 

 值得注意的是,后面两个测试图片有白色的边框,这在平衡后的图像中也可以看出,如果去掉这些白色的边框效果会更好,如下:

算法2(输入->输出):

 

 

 


需要注意的问题:(这些问题是一些使用matlab或者是处理数字图像的基本问题,查了一些其他资料,予以总结)

①变量清除的问题:如果重复执行某一脚本命令文件,需要在最前面加上在前面clc; close all; clear all; 为了清除工作空间中之前的变量,否则会影响后续的变量值。(clc: 清空命令窗口内容,不影响变量;close all: 关闭所有figure窗口;clear all: 清除工作空间所有变量,函数,MEX文件)

本实验没有加...作为一个好习惯以后都应该加上。

②数据类型的问题:

matlab中读取图片后保存的数据是uint8类型(8位无符号整数,即1个字节),而matlab默认数据类型双精度浮点double(64位,8个字节)。虽然matlab中读入图像的数据类型是uint8,但图像矩阵运算时的数据类型是double类型(这是因为精度及计算溢出问题)。

将图像转为double格式:
(1) im2double()函数:参数为uint8型时,转化结果矩阵元素取值位于(0,1)。
(2) double()函数:参数为uint8型时,转化结果矩阵元素取值位于(0,255)。

图像显示:
matlab处理完图像矩阵后,用imshow()显示图像或用inwrite()写入图片。如果参数数据类型是double型,认为double型数据位于(0,1),对于数组中大于1的元素,会将其归为1,显示为白色。而imshow显示uint8型时是0~255范围。所以对double类型的图像显示的时候,要么归一化到0~1之间,要么将double类型的0~255数据转为uint8类型。解决方法如下:

imshow(I/255); % 将图像矩阵转化到0-1之间
imshow(I,[]); % 自动调整数据的范围以便于显示
inshow(uint8(I)); % 转成uint8

另外如果矩阵数据图像是double类型(0~1之间)可直接im2uint8,这样不仅完成数据类型转换,而且将0~1之间映射为了0~255之间的数据。但是如果图像矩阵数据是double类型的0~255,直接im2uint8转换的话,matlab会将大于1的数据都转换为255,0~1之间的数据才会映射到0~255之间整型的数据。

mat2gray()和im2double()区别

这两个如果都是对uint8数据操作,区别就在于前者是归一化操作,归一化后也在0~1之间,自然结果也是double类型,后者是将数据从0~255映射到0~1。计算公式如下(I 代表强度,也就是像素值):

 mat2gray:

im2double:

总结:(均考虑uint8)

int->double:(读入图像并进行运算)

im2double: 映射 (0,1)

double: (0,255)

mat2gray: 归一化 (0,1)

double->int:(输出图像)

① double类型在(0,255)之间

imshow(I/255):  (0,1)

imshow(I,[]): (0,255)

imshow(uint8(I)) : (0,255)

② double类型在(0,1)之间

im2uint8(): (0,255)

uint8(round(I*255))

总之,就像是一个解码-编码的过程,im_和im_ 配合食用,其他类似。

ref:

matlab中clc,close,close all,clear,clear all作用区别: https://blog.csdn.net/majinlei121/article/details/46605783

Matlab图像数据类型unit8,double关系: https://blog.csdn.net/cymy001/article/details/78038324

matlab图像类型转换以及uint8、double、im2double、im2uint8和mat2gray等说明: https://blog.csdn.net/FX677588/article/details/53301740?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

原文地址:https://www.cnblogs.com/pear-linzhu/p/12453985.html