我正在寻找一个算法来找到两个图像之间的相似性,我发现了SSIM,甚至代码如下:
function [mssim, ssim_map] = SSIM(img1, img2, K, window, L)
if (size(img1) ~= size(img2))
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
[M N] = size(img1);
if (nargin == 2)
if ((M < 11) || (N < 11))
ssim_index = -Inf;
ssim_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5); %
K(1) = 0.01; % default settings
K(2) = 0.03; %
L = 255; %
end
C1 = (K(1)*L)^2;
C2 = (K(2)*L)^2;
window = window/sum(sum(window));
img1 = double(img1);
img2 = double(img2);
mu1 = filter2(window, img1, 'valid');
mu2 = filter2(window, img2, 'valid');
mu1_sq = mu1.*mu1;
mu2_sq = mu2.*mu2;
mu1_mu2 = mu1.*mu2;
sigma1_sq = filter2(window, img1.*img1, 'valid') - mu1_sq;
sigma2_sq = filter2(window, img2.*img2, 'valid') - mu2_sq;
sigma12 = filter2(window, img1.*img2, 'valid') - mu1_mu2;
if (C1 > 0 && C2 > 0)
ssim_map = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))./((mu1_sq + mu2_sq + C1).*(sigma1_sq + sigma2_sq + C2));
else
numerator1 = 2*mu1_mu2 + C1;
numerator2 = 2*sigma12 + C2;
denominator1 = mu1_sq + mu2_sq + C1;
denominator2 = sigma1_sq + sigma2_sq + C2;
ssim_map = ones(size(mu1));
index = (denominator1.*denominator2 > 0);
ssim_map(index) = (numerator1(index).*numerator2(index))./(denominator1(index).*denominator2(index));
index = (denominator1 ~= 0) & (denominator2 == 0);
ssim_map(index) = numerator1(index)./denominator1(index);
end
mssim = mean2(ssim_map);
return
img1=imread (image1);
img2=imread (image2);
[mssim ssim_map] = SSIM(img1, img2);
我可以从这个源代码中获取一些值,但是我可以知道这个方法是否适用于旋转情况,例如我旋转到一定程度的一张图片并且这种方法实际上会检测旋转的图像和原始图像相同的形状?
非常感谢,请帮助我!
答案 0 :(得分:2)
SSIM不是旋转不变的。也就是说,如果ImgA是ImgB的旋转版本,则SSIM(ImgA,ImgB)不太可能为高。
因此,如果要检测ImgA和ImgB之间的相对旋转角度,则必须将ImgA旋转到所有可能的角度,并将旋转的版本与ImgB进行比较。
这不是一种非常有效的方法,您可能会发现其他方法可以更有效地检测旋转。
如果我没记错的话,你主要处理封闭曲线的二元掩模。我相信在你的情况下更好的旋转检测选择是使用旋转invariane版本的形状上下文描述符结合在一些强大的刚性变换估计方法(如Ransac)。