% Color Constancy (MATLAB)
X=double(imread('lobster.jpg'))./255;
for k=0:10:100 % hue 0~100 (0°~360°)
Filter=ones(size(X)); Filter(:,:,1)=Filter(:,:,1)*k/100;
Filter=hsv2rgb(Filter); T=0.5;
XX=X.*T+Filter.*(1-T); figure(1); image(XX);
title(num2str(k/100*360),'fontsize',30); axis off;
LabelX=[char('lobster'), num2str(k,'%02d'),char('.png')];
print('-dpng',LabelX); % imwrite(XX,LabelX); でも可
end
写真中央の太い線(横棒)は全て同じ色の画素からなっていますが左側が赤く見えるのです!!! 紙で隠して横棒だけ見えるようにすると同じ色だとわかります。
FreeMatの場合は計算が遅いので、写真のサイズを1000x1000程度に小さくしてから実行します。hsv2rgb関数は無いので以下の様に作成します。setpathも指定します。
% 光の恒常性 (FreeMat) ConstancyColor.m
setpath('C:\FreeMat\12_01_ConstancyColor');
X=double(imread('C:\FreeMat\12_01_ConstancyColor\lobster.jpg'))./255;
for k=50:10:60 % 100 % hue 0~100 (0°~360°)
Filter=ones(size(X)); Filter(:,:,1)=Filter(:,:,1)*k/100;
Filter=hsv2rgb(Filter); T=0.5;
XX=X.*T+Filter.*(1-T); figure(1); image(XX);
title(num2str(k/100*360),'fontsize',30); axis off;
LabelX=[char('LabelX=[char('C:\FreeMat\12_01_ConstancyColor\lobster'), num2str(k,'%02d'),char('.png')];
lobster'), num2str(k,'%02d'),char('.png')];
imwrite(XX,LabelX);
end
% hsv2rgb hsvの画像データをRGBに変換する (Matrix形式にして計算を早くしました)
% MATLABではこの関数があるので不要
function Z=hsv2rgb(Z)
H=Z(:,:,1)*6; S=Z(:,:,2); V=Z(:,:,3);
R=zeros(size(H)); G=zeros(size(H)); B=zeros(size(H));
C=V.*S; X=zeros(size(H)); VC=V-C; One=ones(size(H));
X=C.*(One-abs(mod(H,2)-One));
Zero=zeros(size(H));
RR=R; GG=G; BB=B;
HH=(H>=Zero && H<1.*One);
R=HH.*(VC+C); G=HH.*(VC+X); B=HH.*VC;
RR=RR+R; GG=GG+G; BB=BB+B;
HH=(H>=1.*One && H<2.*One);
R=HH.*(VC+X); G=HH.*(VC+C); B=HH.*VC;
RR=RR+R; GG=GG+G; BB=BB+B;
HH=(H>=2.*One && H<3.*One);
R=HH.*VC; G=HH.*(VC+C); B=HH.*(VC+X);
RR=RR+R; GG=GG+G; BB=BB+B;
HH=(H>=3.*One && H<4.*One);
R=HH.*VC; G=HH.*(VC+X); B=HH.*(VC+C);
RR=RR+R; GG=GG+G; BB=BB+B;
HH=(H>=4.*One && H<5.*One);
R=HH.*(VC+X); G=HH.*VC; B=HH.*(VC+C);
RR=RR+R; GG=GG+G; BB=BB+B;
HH=(H>=5.*One && H<6.*One);
R=HH.*(VC+C); G=HH.*VC; B=HH.*(VC+X);
RR=RR+R; GG=GG+G; BB=BB+B;
Z(:,:,1)=RR; Z(:,:,2)=GG; Z(:,:,3)=BB;
同様にrgb2hsvは
% rgb2hsv
function Z=rgb2hsv(Z)
R=Z(:,:,1); G=Z(:,:,2); B=Z(:,:,3);
MAX=max(Z,[],3); MIN=min(Z,[],3);
A=(MIN==B); H1=A.*(60*(G-R)./(MAX-MIN)+60);
A=(MIN==R); H2=A.*(60*(B-G)./(MAX-MIN)+180);
A=(MIN==G); H3=A.*(60*(R-B)./(MAX-MIN)+300);
H=H1+H2+H3; V=MAX; S=(MAX-MIN)./MAX;
Z(:,:,1)=H; Z(:,:,2)=S; Z(:,:,3)=V;