数字图像基本处理——白平衡(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_processing\Lecture_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