一种非常简单而有效的颜色特征使由Stricker和Orengo所提出的颜色矩(color moments) [7]。这种方法的数学基础在于图像中任何的颜色分布均可以用它的矩来表示。此外,由于颜色分布信息主要集中在低阶矩中,因此仅采用颜色的一阶矩(mean)、二阶矩(variance)和三阶矩(skewness)就足以表达图像的颜色分布。与颜色直方图相比,该方法的另一个好处在于无需对特征进行向量化。因此,图像的颜色矩一共只需要9个分量(3个颜色分量,每个分量上3个低阶矩),与其他的颜色特征相比是非常简洁的。在实际应用中为避免低次矩较弱的分辨能力,颜色矩常和其它特征结合使用,而且一般在使用其它特征前起到过滤缩小范围(narrow down)的作用。
下面是颜色矩的matlab实现:
function cmVec = colorMom(direc) % function cmVec = colorMom(direc) % Input: directory of a JPG image % Output: a color moment feature vector of the input image. The feature % vector is extracted from a 5*5 grid and represented by the first 3 % moments for each grid region in Lab color space as a normalized % 225-dimensional vector. % Function RGB2Lab (By Mr. Ruzon in Stanford U.) is used in this function. jpgfile = imread(direc); % jpgfile = imread('shot141_18_NRKF_1.jpg'); if length(size(jpgfile))==2 jpgfile1=zeros(size(jpgfile,1),size(jpgfile,2),3); jpgfile1(:,:,1)=jpgfile; jpgfile1(:,:,2)=jpgfile; jpgfile1(:,:,3)=jpgfile; jpgfile=jpgfile1; direc end % labfile = RGB2Lab(jpgfile); [a b c] = size(jpgfile); % m, n represent sizes of the grid m = floor(a/5); n = floor(b/5); cmVec = zeros(1,225);% 5x5 x9,9个特征 for i=1:5 for j = 1:5 % subimage = labfile((i-1)*m+1:i*m,(j-1)*n+1:j*n,:); subimage = jpgfile((i-1)*m+1:i*m,(j-1)*n+1:j*n,:); % cal. Mean, ... tmp = (i-1)*5+j-1; % I=imshow(subimage,[]); cmVec(tmp*9+1) = mean(mean(subimage(:,:,1))); cmVec(tmp*9+2) = mean(mean(subimage(:,:,2))); cmVec(tmp*9+3) = mean(mean(subimage(:,:,3))); % cal Moment 2 and 3 for p = 1:m for q = 1:n % === Moment2 cmVec(tmp*9+4) = cmVec(tmp*9+4) + (subimage(p,q,1)-cmVec(tmp*9+1))^2; cmVec(tmp*9+5) = cmVec(tmp*9+5) + (subimage(p,q,2)-cmVec(tmp*9+2))^2; cmVec(tmp*9+6) = cmVec(tmp*9+6) + (subimage(p,q,3)-cmVec(tmp*9+3))^2; % === Moment3 cmVec(tmp*9+7) = cmVec(tmp*9+7) + (subimage(p,q,1)-cmVec(tmp*9+1))^3; cmVec(tmp*9+8) = cmVec(tmp*9+8) + (subimage(p,q,2)-cmVec(tmp*9+2))^3; cmVec(tmp*9+9) = cmVec(tmp*9+9) + (subimage(p,q,3)-cmVec(tmp*9+3))^3; end end cmVec((tmp*9+4):(tmp*9+9)) = cmVec((tmp*9+4):(tmp*9+9))/(m*n); cmVec(tmp*9+4) = cmVec(tmp*9+4)^(1/2); cmVec(tmp*9+5) = cmVec(tmp*9+5)^(1/2); cmVec(tmp*9+6) = cmVec(tmp*9+6)^(1/2); if cmVec(tmp*9+7) >0 cmVec(tmp*9+7) = cmVec(tmp*9+7)^(1/3); else cmVec(tmp*9+7) = -((-cmVec(tmp*9+7))^(1/3)); end if cmVec(tmp*9+8) >0 cmVec(tmp*9+8) = cmVec(tmp*9+8)^(1/3); else cmVec(tmp*9+8) = -((-cmVec(tmp*9+8))^(1/3)); end if cmVec(tmp*9+9) >0 cmVec(tmp*9+9) = cmVec(tmp*9+9)^(1/3); else cmVec(tmp*9+9) = -((-cmVec(tmp*9+9))^(1/3)); end end end % Normalize... if sqrt(sum(cmVec.^2))~=0 cmVec = cmVec / sqrt(sum(cmVec.^2)); end