这里采用量化的方法,简要介绍下量化提取的步骤:
(1)对颜色空间(比如HSV)的各个分量分成若干段,可以均匀,也可以不均匀
(2)扫描一遍图像,对所有像素点,按其颜色分量归类
(3)统计每个颜色类的像素点总数
(4)按颜色类的像素点总数从大到小排序,取前面m种即可作为主色(或者算比例达到多少也可以)
程序里,把H分为8份(取0~7),S和V分为三份(取0~2),量化颜色C=9*H+3*S+V,便量化到72种。
main.m如下
%图像主色提取-量化
OrImage=imread('7.bmp');%读入原图像
hsv_image=rgb2hsv(OrImage);%注意这个rgb2hsv函数,这是MATLAB自带的,但是使用它做RGB到HSV颜色空间的转化后,H,S,V这三个分量的值域都是[0,1]
[h,w,~]=size(OrImage);
T=zeros(4,72);%这里定义了一个4行72列的零矩阵,第一行表示我们划分的72种颜色类,每一列的2,3,4行即将用来存储对应的H,S,V三个分量分类后的值
for i=1:w
for j=1:h
if(hsv_image(j,i,1)>=316/360||hsv_image(j,i,1)<20/360)%把H分量分成8份
H=0;
else if(hsv_image(j,i,1)>=20/360&&hsv_image(j,i,1)<40/360)
H=1;
else if(hsv_image(j,i,1)>=40/360&&hsv_image(j,i,1)<75/360)
H=2;
else if(hsv_image(j,i,1)>=75/360&&hsv_image(j,i,1)<155/360)
H=3;
else if(hsv_image(j,i,1)>=155/360&&hsv_image(j,i,1)<190/360)
H=4;
else if(hsv_image(j,i,1)>=190/360&&hsv_image(j,i,1)<270/360)
H=5;
else if(hsv_image(j,i,1)>=270/360&&hsv_image(j,i,1)<295/360)
H=6;
else H=7;
end
end
end
end
end
end
end
if(hsv_image(j,i,2)<0.2)%把S分量分成3份
S=0;
else if(hsv_image(j,i,2)>=0.2&&hsv_image(j,i,2)<0.7)
S=1;
else S=2;
end
end
if(hsv_image(j,i,3)<0.2)%把V分量分成3份
V=0;
else if(hsv_image(j,i,3)>=0.2&&hsv_image(j,i,3)<0.7)
V=1;
else V=2;
end
end
C=9*H+3*S+V+1;%这个函数可以让C的值得到72种
T(1,C)=T(1,C)+1;%矩阵第一行的值存储每类颜色的像素点总数,每划分一次像素点,归一次类并累加计数
T(2,C)=H;
T(3,C)=S;%存储对应的三个分量归类的值(0~7,0~2,0~2)
T(4,C)=V;
end
end
for i=1:72%对累加后的分类后的各像素点总数冒泡排序
for j=i+1:71
if(T(1,j)>T(1,i))
t=T(:,i);T(:,i)=T(:,j);T(:,j)=t;
end
end
end
for i=1:8%取前面分段时候各个区间的中心为颜色类的各分量的值(为了后面把主色画出来)
if(T(2,i)==0)
T(2,i)=348/360;
else if(T(2,i)==1)
T(2,i)=30/360;
else if(T(2,i)==2)
T(2,i)=58/360;
else if(T(2,i)==3)
T(2,i)=110/360;
else if(T(2,i)==4)
T(2,i)=175/360;
else if(T(2,i)==5)
T(2,i)=230/360;
else if(T(2,i)==6)
T(2,i)=282/360;
else
T(2,i)=305/360;
end
end
end
end
end
end
end
if(T(3,i)==0)
T(3,i)=0.1;
else if(T(3,i)==1)
T(3,i)=0.45;
else
T(3,i)=0.85;
end
end
if(T(4,i)==0)
T(4,i)=0.1;
else if(T(4,i)==1)
T(4,i)=0.45;
else
T(4,i)=0.85;
end
end
end
for j=1:8%这里取m=8,即取前面8种颜色类作为主色
for i=round(w/8)*(j-1):round(w/8)*j%按原图的大小,把主色画出来
if(i==0)
i=1;
end
hsv_image(:,i,1)=T(2,j);
hsv_image(:,i,2)=T(3,j);
hsv_image(:,i,3)=T(4,j);
end
end
DCImage=hsv2rgb(hsv_image);
figure,imshow(OrImage)
figure,imshow(DCImage);
原始图像
主色提取图
由效果图可以看到,这种方法还是有些问题的,该算法思想来源于IEEE2008年轻计算机科学家国际会议。