function varargout = figureColors(matFig,n,circles)
% This function is meant to help artists recognize colors on a picture
% Sometimes it is difficults to tell what color some part of a picture is.
% With this function this should be easier. It takes the average color of
% regions in the picture and shows the average in the whole region
% It also shows the colors needed to make that color (in the
% Black-White-Yellow-Red-Blue system). The result uses at the most two of
% the three colors and a combination of white and black if necessary
% By repeatedly clicking on the figure, the color tip appears/dissapears
% Steps:
% - Import a picture into Matlab (e.g. a jpg picture. You can import it
% simply by clicking on it on the current directory in Matlab and
% following the instructions) and save it in the workspace (e.g. MyPict)
% - Write any of the following on the command window
% >> figureColors(MyPict,10)
% >> figureColors(MyPict,20)
% >> figureColors(MyPict,15,0) % this one uses squares instead of circles
%
% Input arguments are
% - 1) matFig: matrix XxYx3 where the third dimension is the RGB of the figure
% and the first two arguments are the height and width of the figure (default
% format Matlab uses for imported figures)
% - 2) n: is the number of circles on the shortest dimension fo the picture
% - 3) circles: flag indicating if the colors fill circles (easier to the
% eye) or squares taking all the available space
% Pablo Borruel - June 08
if nargin<3, circles=1; end
if nargin<2, n=10; end
[r,c,col]=size(matFig); %#ok<NASGU>
pixelSquareWidth = floor(min(r,c)/n);
if pixelSquareWidth==0; return; end
numSqwidth = floor(r/pixelSquareWidth);
numSqHeight = floor(c/pixelSquareWidth);
% circle points
t = (1/64:1/32:1)'*2*pi;
xx = sin(t);
yy = cos(t);
if nargout
varargout{1} = zeros([numSqHeight numSqwidth 3]);
end
showColors(0,0,0)
colordef black
hF = figure('visible','off');
% check average RGV.
for i=1:numSqwidth
for j=1:numSqHeight
tempImg = matFig((i-1)*pixelSquareWidth+1:(i*pixelSquareWidth-1),...
(j-1)*pixelSquareWidth+1:(j*pixelSquareWidth-1),:);
theAvg1 = mean(mean(tempImg(:,:,1)));
theAvg2 = mean(mean(tempImg(:,:,2)));
theAvg3 = mean(mean(tempImg(:,:,3)));
if nargout
varargout{1}(i,j,1) = theAvg1/255;
varargout{1}(i,j,2) = theAvg2/255;
varargout{1}(i,j,3) = theAvg3/255;
end
if circles
x = ((i-1)*pixelSquareWidth+(pixelSquareWidth)/2)+...
(sin(t)*pixelSquareWidth*0.8)/2;
y = ((j-1)*pixelSquareWidth+(pixelSquareWidth)/2)+...
(cos(t)*pixelSquareWidth*0.8)/2;
else
x = [(i-1)*pixelSquareWidth...
(i-1)*pixelSquareWidth...
(i-1)*pixelSquareWidth+(pixelSquareWidth)...
(i-1)*pixelSquareWidth+(pixelSquareWidth)];
y = [(j-1)*pixelSquareWidth...
(j-1)*pixelSquareWidth+(pixelSquareWidth)...
(j-1)*pixelSquareWidth+(pixelSquareWidth)...
(j-1)*pixelSquareWidth];
end
h = fill(y,-x,[theAvg1 theAvg2 theAvg3]/255);
hold on
set(h,'EdgeColor','none')
set(h,'buttondownfcn',{@showColors,[theAvg1 theAvg2 theAvg3]/255})
end
end
set(gca,'XTick',[]);
set(gca,'YTick',[]);
set(gca,'Position',[0 0 1 1]);
axis tight
if nargout
delete(hF)
else
set(hF,'visible','on')
end
%**************************************************************************
function showColors(handle,event,theColor)
persistent hCenterPatch hr hg hb hw hbl
if handle==0 && event==0, clear hCenterPatch; return; end
circles = 1;
t = (1/128:1/64:0.5)*2*pi;
xx = sin(t);
yy = cos(t);
if isempty(hCenterPatch)
theAxis = axis;
x = [theAxis(1)...
theAxis(1)+(theAxis(4)-theAxis(3))*(1/4+xx/4)...
theAxis(1)];
y = [theAxis(3)+(theAxis(4)-theAxis(3))*(3/4)...
theAxis(3)+(theAxis(4)-theAxis(3))*(1/2+yy/4)...
theAxis(3)+(theAxis(4)-theAxis(3))*1/4];
% Convert to BWRYB
minC = min(theColor);
maxC = max(theColor);
R = theColor(1);
G = theColor(2);
B = theColor(3);
theWhite = minC;
theBlack = 1-maxC;
theYellow = (min(R,G)-minC);
theRed = (R-min(R,G)) ;
theBlue = (B-minC) ;
% we may be left with some green which will be yellow and blue
greenLeft = (G-min(R,G)) ;
theYellow = theYellow + greenLeft/2;
theBlue = theBlue + greenLeft/2;
t = (1/128:1/64:1)*2*pi;
% Black
xbl = theAxis(1) + (theAxis(4)-theAxis(3)) * (1/16 + sin(t)/20*(theBlack^0.5 + sqrt(eps)));
ybl = theAxis(3) + (theAxis(4)-theAxis(3)) * (0.35 + cos(t)/20*(theBlack^0.5 + sqrt(eps)));
% White
xw = theAxis(1) + (theAxis(4)-theAxis(3)) * (1/16 + sin(t)/20*(theWhite^0.5 + sqrt(eps)));
yw = theAxis(3) + (theAxis(4)-theAxis(3)) * (0.45 + cos(t)/20*(theWhite^0.5 + sqrt(eps)));
% Red
xr = theAxis(1) + (theAxis(4)-theAxis(3)) * (1/16 + sin(t)/20*(theRed^0.5 + sqrt(eps)));
yr = theAxis(3) + (theAxis(4)-theAxis(3)) * (0.55 + cos(t)/20*(theRed^0.5 + sqrt(eps)));
% Green
xg = theAxis(1) + (theAxis(4)-theAxis(3)) * (1/16 + sin(t)/20*(theYellow^0.5 + sqrt(eps)));
yg = theAxis(3) + (theAxis(4)-theAxis(3)) * (0.65 + cos(t)/20*(theYellow^0.5 + sqrt(eps)));
% Blue
xb = theAxis(1) + (theAxis(4)-theAxis(3)) * (1/16 + sin(t)/20*(theBlue^0.5 + sqrt(eps)));
if theRed==0
bxOff = 0.55;
elseif theYellow==0
bxOff = 0.65;
else
bxOff = 0;
end
yb = theAxis(3) + (theAxis(4)-theAxis(3)) * (bxOff + cos(t)/20*(theBlue^0.5 + sqrt(eps)));
currpoint = get(gca,'currentpoint');
cp1 = currpoint(1,1);
if cp1<((theAxis(2)-theAxis(1))/2)
x = (x - ((theAxis(2)-theAxis(1))*0.51))* -1 + ((theAxis(2)-theAxis(1))/2);
xr = (xr - ((theAxis(2)-theAxis(1))*0.51))* -1 + ((theAxis(2)-theAxis(1))/2);
xg = (xg - ((theAxis(2)-theAxis(1))*0.51))* -1 + ((theAxis(2)-theAxis(1))/2);
xb = (xb - ((theAxis(2)-theAxis(1))*0.51))* -1 + ((theAxis(2)-theAxis(1))/2);
xw = (xw - ((theAxis(2)-theAxis(1))*0.51))* -1 + ((theAxis(2)-theAxis(1))/2);
xbl = (xbl - ((theAxis(2)-theAxis(1))*0.51))* -1 + ((theAxis(2)-theAxis(1))/2);
end
hCenterPatch = fill(x,y,theColor);
%set(hCenterPatch,'ZData',y*0)
set(hCenterPatch,'EdgeColor','none')
set(hCenterPatch,'buttondownfcn',{@showColors,[0 0 0]})
hr = fill(xr,yr,'r');
hg = fill(xg,yg,'y');
hb = fill(xb,yb,'b');
hw = fill(xw,yw,[1 1 1]);
hbl = fill(xbl,ybl,[0 0 0]);
else
delete(hCenterPatch);
delete(hr);
delete(hg);
delete(hb);
delete(hw);
delete(hbl)
hCenterPatch = [];
end