數字圖像基本處理——白平衡(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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM