目录
基础功能
- 基础功能
- 进阶功能
- 完整代码
换唇色!,大部分功能可以自行探索,当更改储存色号框内名称后,可以将当前在颜色展示框的颜色储存。
通过左上角的设置按钮可以打开隐藏操作栏
- 选中色号数据重存 : 在下图所示处 [选择色号] 后,
通过此处更改颜色:
再点击选中色号数据重存,即可将 [选择色号] 对应颜色修改。
- 选中色号重命名: 只需 [选择色号] 后,在此 [存储色号] 框内对名称进行更改后点击 选中色号重命名按钮即可
- 唇色下限重设\恢复: 唇色下限:能够被认为是红色的最低限度颜色,初始值为[125 88 88];通过颜色调整兰调整后点击按钮即可。
function lipstickApp
global LSFig LSAxes
global LoadPicButton RePicButton ChangeColorButton
global Label16 Datal16 LabelR NumericR LabelG NumericG LabelB NumericB
global saveDataLabel searchDataLabel
global ColorDisplay LSlistbox saveDataButton searchDataButton
global oriPic presentPic presentColor lipstickData averageColor
global Rratio Gratio Bratio RArea redLim
global changeDataButton changeNameButton deleteColorButton reSortButton reSetRedButton reCoverRedButton getOriColorButton
%------------------------------------------------------------------------------------------------------------
LSFig=uifigure('units','pixels',...
'position',[300 100 760 500],...
'Numbertitle','off',...
'menubar','none',...
'resize','off',...
'name','唇色更改器 1.0',...
'color',[1,1,1].*0.97);
LSFig.AutoResizeChildren = 'off';
LSAxes=uiaxes('Units','pixels',...
'parent',LSFig,...
'PlotBoxAspectRatio',[1 1 1],...
'Position',[10 10 480 480],...
'Color',[0.99 0.99 0.99],...
'Box','on', ...
'XLim',[0 1],'YLim',[0 1],...
'XTick',[],'YTick',[]);
%----------------------------------------------------------------------------------------------------------------------------
LoadPicButton=uibutton(LSFig,'Text','导 入 图 片','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[500,450,120,35],'FontSize',13,'ButtonPushedFcn',@loadPic);
RePicButton=uibutton(LSFig,'Text','还 原 图 片','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[630,450,120,35],'FontSize',13,'ButtonPushedFcn',@rePic);
ChangeColorButton=uibutton(LSFig,'Text','开 始 换 色','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[500,230,100,35],'FontSize',13,'ButtonPushedFcn',@changeColor);
%----------------------------------------------------------------------------------------------------------------------------
Label16=uilabel(LSFig,'Text',' 16进制码','HorizontalAlignment','left',...
'BackgroundColor',[1 1 1].*0.85,'Position',[500,400,230,35],'FontSize',15);
Datal16=uieditfield(LSFig,'Value','#FFAEB9','HorizontalAlignment','center','FontSize',16,'ValueChangedFcn',@edit16Data,'Position',[575,400,175,35]);
%----------------------------------------------------------------------------------------------------------------------------
LabelR=uilabel('parent',LSFig,'Text',' R',...
'FontSize',15,'BackgroundColor',[1 1 1].*0.9,'position',[500,360,80,30]);
NumericR=uispinner(LSFig,'Value',255,'limit',[0 255],...
'ValueDisplayFormat','%.0f','FontSize',16,'ValueChangedFcn',@editRGBData,'position',[520,360,80,30]);
LabelG=uilabel('parent',LSFig,'Text',' G',...
'FontSize',15,'BackgroundColor',[1 1 1].*0.9,'position',[500,320,80,30]);
NumericG=uispinner(LSFig,'Value',174,'limit',[0 255],...
'ValueDisplayFormat','%.0f','FontSize',16,'ValueChangedFcn',@editRGBData,'position',[520,320,80,30]);
LabelB=uilabel('parent',LSFig,'Text',' B',...
'FontSize',15,'BackgroundColor',[1 1 1].*0.9,'position',[500,280,80,30]);
NumericB=uispinner(LSFig,'Value',185,'limit',[0 255],...
'ValueDisplayFormat','%.0f','FontSize',16,'ValueChangedFcn',@editRGBData,'position',[520,280,80,30]);
%----------------------------------------------------------------------------------------------------------------------------
ColorDisplay=uiaxes('Units','pixels',...
'parent',LSFig,...
'Position',[610 230 140 160],...
'Color',[255 174 185]./255,...
'Box','on', ...
'XLim',[0 1],'YLim',[0 1],...
'XTick',[],'YTick',[]);
ColorDisplay.Toolbar.Visible='off';
%----------------------------------------------------------------------------------------------------------------------------
saveDataLabel=uieditfield(LSFig,'Value','','HorizontalAlignment','left','FontSize',12,'Position',[500,180,170,30]);
searchDataLabel=uieditfield(LSFig,'Value','','HorizontalAlignment','left','FontSize',12,'Position',[500,140,170,30]);
saveDataButton=uibutton(LSFig,'Text','存 储 色 号','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[675,180,80,30],'FontSize',13,'ButtonPushedFcn',@saveData);
searchDataButton=uibutton(LSFig,'Text','搜 索 色 号','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[675,140,80,30],'FontSize',13,'ButtonPushedFcn',@searchData);
LSlistbox=uilistbox(LSFig,'Position',[500,15,250,120],'Items',{''},'ValueChangedFcn',@selectedColor);
%============================================================================================================================
LSMenu=uimenu(LSFig);
LSMenu.Text='设置';
LSMenu_1=uimenu(LSMenu);
LSMenu_1.Text='显示操作栏';
set(LSMenu_1,'MenuSelectedFcn',@MenuSelected)
LSPanel=uipanel(LSFig);
LSPanel.AutoResizeChildren='off';
LSPanel.Position=[760 0 150 510];
%============================================================================================================================
changeDataButton=uibutton(LSFig,'Text','选中色号数据重存','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,450,120,35],'FontSize',13,'ButtonPushedFcn',@changeData);
changeNameButton=uibutton(LSFig,'Text','选中色号重命名','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,400,120,35],'FontSize',13,'ButtonPushedFcn',@changeName);
deleteColorButton=uibutton(LSFig,'Text','选中色号删除','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,350,120,35],'FontSize',13,'ButtonPushedFcn',@deleteColor);
reSortButton=uibutton(LSFig,'Text','色号信息重排序','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,300,120,35],'FontSize',13,'ButtonPushedFcn',@reSort);
reSetRedButton=uibutton(LSFig,'Text','唇色搜索下限重设','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,250,120,35],'FontSize',13,'ButtonPushedFcn',@reSetRed);
reCoverRedButton=uibutton(LSFig,'Text','唇色搜索下限恢复','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,200,120,35],'FontSize',13,'ButtonPushedFcn',@reCoverRed);
getOriColorButton=uibutton(LSFig,'Text','原图唇色提取','BackgroundColor',[0.31 0.58 0.80],'FontColor',[1 1 1],...
'FontWeight','bold','Position',[775,150,120,35],'FontSize',13,'ButtonPushedFcn',@getOriColor);
%==================================================================================================================
function changeData(~,~)
for i=1:size(lipstickData,1)
if strcmp(lipstickData{i,1},LSlistbox.Value)
break
end
end
lipstickData(i,2)={[NumericR.Value,NumericG.Value,NumericB.Value]};
save('.\lipstickData.mat','lipstickData')
end
function changeName(~,~)
tempName=saveDataLabel.Value;
tempFlag=0;
for i=1:size(lipstickData,1)
if strcmp(lipstickData{i,1},LSlistbox.Value)
break
end
end
for j=1:size(lipstickData,1)
if (~isempty(regexpi(lipstickData{j,1},tempName)))&&i~=j
tempFlag=1;
end
end
if tempFlag==0&&~isempty(tempName)
lipstickData(i,1)={saveDataLabel.Value};
LSlistbox.Items=lipstickData(:,1);
save('.\lipstickData.mat','lipstickData')
end
end
function deleteColor(~,~)
for i=1:size(lipstickData,1)
if strcmp(lipstickData{i,1},LSlistbox.Value)
break
end
end
lipstickData(i,:)=[];
LSlistbox.Items=lipstickData(:,1);
save('.\lipstickData.mat','lipstickData')
end
function reSort(~,~)
tempList=lipstickData;
for i=1:size(tempList,1)
for j=i+1:size(tempList,1)
if compareStr(tempList{i,1},tempList{j,1})==1
tempElement=tempList(j,:);
tempList{j,1}=tempList{i,1};
tempList{j,2}=tempList{i,2};
tempList{i,1}=tempElement{1};
tempList{i,2}=tempElement{2};
end
end
end
lipstickData=tempList;
LSlistbox.Items=lipstickData(:,1);
save('.\lipstickData.mat','lipstickData')
end
function reSetRed(~,~)
redLim(1)=(NumericR.Value)./(NumericG.Value);
redLim(2)=(NumericR.Value)./(NumericB.Value);
redLim(3)=NumericR.Value;
RChannel=double(oriPic(:,:,1));
GChannel=double(oriPic(:,:,2));
BChannel=double(oriPic(:,:,3));
RArea=RChannel>redLim(1).*GChannel&RChannel>redLim(2).*BChannel&RChannel>=redLim(3);
RArea_S=sum(sum(RArea));
RArea=bwareaopen(RArea,round(RArea_S*0.3));
RArea_S=sum(sum(RArea));
RChannel=double(oriPic(:,:,1));
GChannel=double(oriPic(:,:,2));
BChannel=double(oriPic(:,:,3));
WArea=imclearborder(~RArea);
RArea=imclearborder(~RArea)|RArea;
averageColor(1,1)=sum(RChannel(RArea))./RArea_S;
averageColor(1,2)=sum(GChannel(RArea))./RArea_S;
averageColor(1,3)=sum(BChannel(RArea))./RArea_S;
Rratio=RChannel./averageColor(1,1);
Gratio=GChannel./averageColor(1,2);
Bratio=BChannel./averageColor(1,3);
Rratio(WArea)=Rratio(WArea).*1.25;
Gratio(WArea)=Gratio(WArea).*1.25;
Bratio(WArea)=Bratio(WArea).*1.25;
changeColor()
end
function reCoverRed(~,~)
redLim=[1.42,1.42,125];
RChannel=double(oriPic(:,:,1));
GChannel=double(oriPic(:,:,2));
BChannel=double(oriPic(:,:,3));
RArea=RChannel>redLim(1).*GChannel&RChannel>redLim(2).*BChannel&RChannel>=redLim(3);
RArea_S=sum(sum(RArea));
RArea=bwareaopen(RArea,round(RArea_S*0.3));
RArea_S=sum(sum(RArea));
RChannel=double(oriPic(:,:,1));
GChannel=double(oriPic(:,:,2));
BChannel=double(oriPic(:,:,3));
WArea=imclearborder(~RArea);
RArea=imclearborder(~RArea)|RArea;
averageColor(1,1)=sum(RChannel(RArea))./RArea_S;
averageColor(1,2)=sum(GChannel(RArea))./RArea_S;
averageColor(1,3)=sum(BChannel(RArea))./RArea_S;
Rratio=RChannel./averageColor(1,1);
Gratio=GChannel./averageColor(1,2);
Bratio=BChannel./averageColor(1,3);
Rratio(WArea)=Rratio(WArea).*1.25;
Gratio(WArea)=Gratio(WArea).*1.25;
Bratio(WArea)=Bratio(WArea).*1.25;
presentColor=[125 88 88];
NumericR.Value=presentColor(1);
NumericG.Value=presentColor(2);
NumericB.Value=presentColor(3);
Datal16.Value=ten2sixteen(presentColor);
ColorDisplay.Color=presentColor./255;
changeColor()
end
function getOriColor(~,~)
presentColor=round(averageColor);
presentColor(presentColor>255)=255;
presentColor(presentColorstrB(i)
bool=1;break
case strA(i)length(strB(i))
bool=1;
case length(strA(i))redLim(1).*GChannel&RChannel>redLim(2).*BChannel&RChannel>=redLim(3);
RArea_S=sum(sum(RArea));
RArea=bwareaopen(RArea,round(RArea_S*0.3));
RArea_S=sum(sum(RArea));
RChannel=double(oriPic(:,:,1));
GChannel=double(oriPic(:,:,2));
BChannel=double(oriPic(:,:,3));
WArea=imclearborder(~RArea);
RArea=imclearborder(~RArea)|RArea;
averageColor(1,1)=sum(RChannel(RArea))./RArea_S;
averageColor(1,2)=sum(GChannel(RArea))./RArea_S;
averageColor(1,3)=sum(BChannel(RArea))./RArea_S;
Rratio=RChannel./averageColor(1,1);
Gratio=GChannel./averageColor(1,2);
Bratio=BChannel./averageColor(1,3);
Rratio(WArea)=Rratio(WArea).*1.25;
Gratio(WArea)=Gratio(WArea).*1.25;
Bratio(WArea)=Bratio(WArea).*1.25;
Lim=max(size(oriPic));
LSAxes.XLim=[0 Lim];
LSAxes.YLim=[0 Lim];
presentPic=oriPic;
imshow(presentPic,'parent',LSAxes)
catch
end
end
function rePic(~,~)
presentPic=oriPic;
imshow(presentPic,'parent',LSAxes)
end
function changeColor(~,~)
RChannel=oriPic(:,:,1);
GChannel=oriPic(:,:,2);
BChannel=oriPic(:,:,3);
RChannel(RArea)=Rratio(RArea).*presentColor(1);
GChannel(RArea)=Gratio(RArea).*presentColor(2);
BChannel(RArea)=Bratio(RArea).*presentColor(3);
presentPic(:,:,1)=RChannel;
presentPic(:,:,2)=GChannel;
presentPic(:,:,3)=BChannel;
imshow(presentPic,'parent',LSAxes)
end
function editRGBData(~,~)
presentColor=[NumericR.Value,NumericG.Value,NumericB.Value];
ColorDisplay.Color=presentColor./255;
string=ten2sixteen(presentColor);
Datal16.Value=string;
end
function edit16Data(~,~)
string=Datal16.Value;
presentColor=sixteen2ten(string);
NumericR.Value=presentColor(1);
NumericG.Value=presentColor(2);
NumericB.Value=presentColor(3);
ColorDisplay.Color=presentColor./255;
end
function num=sixteen2ten(string)
exchange_list='0123456789ABCDEF#';
num=zeros(1,3);
if all(ismember(string,exchange_list))
for ii=1:3
tempCoe1=find(ismember(exchange_list,string(ii*2))==1)-1;
tempCoe2=find(ismember(exchange_list,string(ii*2+1))==1)-1;
num(ii)=16*tempCoe1+tempCoe2;
end
else
num=nan;
end
end
function string=ten2sixteen(num)
%the num should be a 1x3 Integer mat limited in [0 255]
exchange_list={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
string='#';
for ii=1:3
temp_num=num(ii);
string(1+ii*2-1)=exchange_list{(temp_num-mod(temp_num,16))/16+1};
string(1+ii*2)=exchange_list{mod(temp_num,16)+1};
end
end
end