【圖像檢索】基于 Hu不變矩圖像檢索matlab源碼
一、簡介
幾何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,具有平移、旋轉(zhuǎn)和尺度不變性。


這7個不變矩構(gòu)成一組特征量,Hu.M.K在1962年證明了他們具有旋轉(zhuǎn),縮放和平移不變性。
實際上,在對圖片中物體的識別過程中,只有 和 不變性保持的比較好,其他的幾個不變矩帶來的誤差比較大,有學(xué)者認為只有基于二階矩的不變矩對二維物體的描述才是真正的具有旋轉(zhuǎn)、縮放和平移不變性( 和 剛好都是由二階矩組成的)。不過我沒有證明是否是真的事這樣的。
由Hu矩組成的特征量對圖片進行識別,優(yōu)點就是速度很快,缺點是識別率比較低,我做過手勢識別,對于已經(jīng)分割好的手勢輪廓圖,識別率也就30%左右,對于紋理比較豐富的圖片,識別率更是不堪入眼,只有10%左右。這一部分原因是由于Hu不變矩只用到低階矩(最多也就用到三階矩),對于圖像的細節(jié)未能很好的描述出來,導(dǎo)致對圖像的描述不夠完整。
Hu不變矩一般用來識別圖像中大的物體,對于物體的形狀描述得比較好,圖像的紋理特征不能太復(fù)雜,像識別水果的形狀,或者對于車牌中的簡單字符的識別效果會相對好一些。
定義如下:
① (p+q)階不變矩定義:
② 對于數(shù)字圖像,離散化,定義為:
③ 歸一化中心矩定義:
④Hu矩定義
二、源代碼
clc; clear all; close all;
warning off all;
filename = '待檢索圖像\\im1.bmp';
[I, map] = imread(filename);
I = ind2rgb(I, map);
I1 = Gray_Convert(I, 0);
bw1 = Image_Binary(I1, 0);
Hu = Compute_HuNicolas(bw1);
[resultNames, index] = CoMatrix_Process(filename, 1);
[fresultNames, index] = Hu_Process(filename, Hu, resultNames, index);
D = Analysis(filename, fresultNames, index, 1);
function [resultNames, index] = CoMatrix_Process(filename, flag)
if nargin < 2
? ?flag = 1;
end
if nargin < 1
? ?filename = '待檢索圖像\\im1.bmp';
end
resultValues = [];
resultNames = {};
files = ls('圖片庫\\*.*');
[queryx, querymap] = imread(filename);
if isempty(querymap)
? ?[queryx, querymap] = rgb2ind(queryx, 256);
end
for i = 1 : size(files, 1)
? ?file = fullfile('圖片庫\\', files(i, :));
? ?[pathstr, name, ext] = fileparts(file);
? ?if length(strtrim(ext)) > 3
? ? ? ?[X, RGBmap] = imread(file);
? ? ? ?HSVmap = rgb2hsv(RGBmap);
? ? ? ?D = Compute_QuadDistance(queryx, querymap, X, HSVmap);
? ? ? ?resultValues(end+1) = D;
? ? ? ?resultNames{end+1} = {file};
? ?end
end
[sortedValues, index] = sort(resultValues);
query = ind2rgb(queryx, querymap);
query = rgb2gray(query);
if flag
? ?figure;
? ?imshow(queryx, querymap);
? ?title('待檢索圖像', 'FontWeight', 'Bold');
? ?figure;
? ?set(gcf, 'units', 'normalized', 'position',[0 0 1 1]);
? ?for i = 1 : 10
? ? ? ?tempstr = cell2mat(resultNames{index(i)});
? ? ? ?[X, RGBmap] = imread(tempstr);
? ? ? ?img = ind2rgb(X, RGBmap); ? ? ? ?
? ? ? ?subplot(2, 5, i); imshow(img, []);
? ? ? ?img = rgb2gray(img);
? ? ? ?dm = imabsdiff(query, img);
? ? ? ?df = (1-sum(dm(:))/sum(query(:)))*100;
? ? ? ?xlabel(sprintf('相似度:%.2f%%', abs(df)), 'FontWeight', 'Bold');
? ? ? ?str = sprintf('檢索結(jié)果排序%d', i);
? ? ? ?title(str, 'FontWeight', 'Bold');
? ?end
end
function Hu = Compute_HuNicolas(in_image)
format long
if ndims(in_image) == 3
? ?image = rgb2gray(in_image);
else
? ?image = in_image;
end
image = double(image);
m00=sum(sum(image));
m10=0;
m01=0;
[row,col]=size(image);
for i=1:row
? ?for j=1:col
? ? ? ?m10=m10+i*image(i,j);
? ? ? ?m01=m01+j*image(i,j);
? ?end
end
u10=m10/m00;
u01=m01/m00;
n20 = 0;
n02 = 0;
n11 = 0;
n30 = 0;
n12 = 0;
n21 = 0;
n03 = 0;
for i=1:row
? ?for j=1:col
? ? ? ?n20=n20+i^2*image(i,j);
? ? ? ?n02=n02+j^2*image(i,j);
? ? ? ?n11=n11+i*j*image(i,j);
? ? ? ?n30=n30+i^3*image(i,j);
? ? ? ?n03=n03+j^3*image(i,j);
? ? ? ?n12=n12+i*j^2*image(i,j);
? ? ? ?n21=n21+i^2*j*image(i,j);
? ?end
end
n20=n20/m00^2;
n02=n02/m00^2;
n11=n11/m00^2;
n30=n30/m00^2.5;
n03=n03/m00^2.5;
n12=n12/m00^2.5;
n21=n21/m00^2.5;
h1 = n20 + n02;
h2 = (n20-n02)^2 + 4*(n11)^2;
h3 = (n30-3*n12)^2 + (3*n21-n03)^2;
h4 = (n30+n12)^2 + (n21+n03)^2;
h5 = (n30-3*n12)*(n30+n12)*((n30+n12)^2-3*(n21+n03)^2)+(3*n21-n03)*(n21+n03)*(3*(n30+n12)^2-(n21+n03)^2);
h6 = (n20-n02)*((n30+n12)^2-(n21+n03)^2)+4*n11*(n30+n12)*(n21+n03);
h7 = (3*n21-n03)*(n30+n12)*((n30+n12)^2-3*(n21+n03)^2)+(3*n12-n30)*(n21+n03)*(3*(n30+n12)^2-(n21+n03)^2);
Hu = [h1 h2 h3 h4 h5 h6 h7];
三、運行結(jié)果



?