系统的大体流程和介绍在(一)~(三)中大致介绍完了。
该系统采用的方法主要有两种,一种是全参考(RF),另一种是无参考(NF)
贴出的算法代码是用于系统调用的返回值版:
一、全参考(RF)
RF中主要包括了MSE\PSNR\JND\PDM\SSIM\SIExt\QILV\VIF几个算法,在这里就不逐个介绍了。
(1)MSE(Mean Square Error)均方误差
该算法直接比较得到两幅图像 I、J 每一个像素位置对应的绝对差值,最后总平均差值即为 MSE。
(2)PSNR(Peak Signal to Noise Ratio)峰值信噪比
可由MSE值计算得到。
function [PSNR, MSE] = mseandpsnr(X, Y)
D = X-Y;
[m n d]=size(D);
MSE = sum(D(:).^2)/(m*n*d);
PSNR = 10*log10(258^2/MSE);
(3)JND(Just Noticeable Difference)最小可觉差/差别感知阈限
这个在网上找到了一个版本的代码,但是无法搬到系统中,搜了半天看到有说这个算法基于mallat,于是就用mallat替代了。
%离散快速正交小波变换——Mallat算法
function [psnr]=mallat(I)
order = 3; %变换级数为3
I=rgb2gray(I);
I=imresize(I,[256,256]);
wname = 'db2';
ordata=double(I);
data=ordata;
[row,col]=size(data);
imdata=zeros(size(data,1),size(data,2));
%分解
[lo_d,hi_d]=wfilters(wname,'d');
for i=1:order
data=decomp(lo_d,hi_d,i,data);
MIN=min(min(data));
MAX=max(max(data));
for j=1:size(data,1)
for k=1:size(data,2)
imdata(j,k)=((data(j,k)-MIN)/(MAX-MIN))*255;
end
end
%figure;
%imshow(uint8(imdata));
end
%计算最后一级分解后能量分布
energy=zeros(1,4);
energy=cal_energy(data,order);
%阈值化处理
[thr,sorh]=ddencmp('den','wv',ordata); %获得阈值
ddata=wthresh(data,sorh,thr); %阈值化处理
MIN=min(min(ddata));
MAX=max(max(ddata));
for j=1:size(ddata,1)
for k=1:size(ddata,2)
imdata(j,k)=((ddata(j,k)-MIN)/(MAX-MIN))*255;
end
end
%figure;
%imshow(uint8(imdata));
%统计0的个数
sum=0;
for i=1:row
for j=1:col
if (ddata(i,j)==0)
sum=sum+1;
end
end
end
Zero=sum/(row*col);
%重建
[lo_r,hi_r]=wfilters(wname,'r');
redata=zeros(size(data,1),size(data,2));
data=ddata;
for i=order:-1:1
data=reconstrn(lo_r,hi_r,i,data);
MIN=min(min(data));
MAX=max(max(data));
for j=1:size(data,1)
for k=1:size(data,2)
redata(j,k)=((data(j,k)-MIN)/(MAX-MIN))*255;
end
end
%figure;
%imshow(uint8(redata));
end
%计算重构后的均值和方差
[mean,var]=cal_mv(data);
%峰值信噪比PSNR
[row,col]=size(data);
mse=0;
for i=1:row
for j=1:col
mse=mse+(data(i,j)-ordata(i,j))^2;
end
end
mse=mse/(row*col);
psnr=10*log10(255^2/mse);
end
调用到的其他函数:
cal_mv.m
%求均值、方差
function [mean var]=cal_mv(data)
[row col]=size(data);
sum=0;
for i=1:row
for j=1:col
sum=sum+data(i,j);
end
end
mean = sum/(row*col);
sum=0;
for i=1:row
for j=1:col
sum=sum+(data(i,j)-mean)^2;
end
end
var = sum/(row*col);
decomp.m
%分解变换
function data_d=decomp(lo_d,hi_d,order,data)
[row,col]=size(data);
%一维行变换
firowlen=size(lo_d,2);
l=fix(firowlen/2);
%excoldata=wextend('ac','sym',data(1:row/2^(order-1),1:col/2^(order-1)),l);
excoldata=wextend('ac','ppd',data(1:row/2^(order-1),1:col/2^(order-1)),firowlen-1,'r');%往右周期延拓
for i=1:row/2^(order-1);
for j=1:row/2^order;
data(i,j)=lo_d*excoldata(i,(2*j-1):(2*j+firowlen-2))';
data(i,j+row/2^order)=hi_d*excoldata(i,(2*j-1):(2*j+firowlen-2))';
end
end
%一维列变换
ficollen=size(hi_d,2);
l=fix(ficollen/2);
%exrowdata=wextend('ar','sym',data(1:row/2^(order-1),1:col/2^(order-1)),l);
exrowdata=wextend('ar','ppd',data(1:row/2^(order-1),1:col/2^(order-1)),ficollen-1,'d');%往下周期延拓
for i=1:col/2^(order-1);
for j=1:col/2^order;
data(j,i)=lo_d*exrowdata((2*j-1):(2*j+ficollen-2),i);
data(j+col/2^order,i)=hi_d*exrowdata((2*j-1):(2*j+ficollen-2),i);
end
end
data_d= data;
reconstrn.m
%重建
function data_r=reconstrn(lo_r,hi_r,order,data)
[row,col]=size(data);
lo_ro=lo_r(1:2:end);%提取lo_r奇数位上的值
lo_re=lo_r(2:2:end);%提取lo_r偶数位上的值
hi_ro=hi_r(1:2:end);%提取hi_r奇数位上的值
hi_re=hi_r(2:2:end);%提取hi_r偶数位上的值
leno=size(lo_ro,2);
lene=size(lo_re,2);
%列重构
exloodata=wextend('ar','ppd',data(1:row/2^order,1:col/2^(order-1)),(leno-1),'u');%向上周期延拓
exloedata=wextend('ar','ppd',data(1:row/2^order,1:col/2^(order-1)),(lene-1),'u');%向上周期延拓
exhiodata=wextend('ar','ppd',data((row/2^order+1):row/2^(order-1),1:col/2^(order-1)),(leno-1),'u');%向上周期延拓
exhiedata=wextend('ar','ppd',data((row/2^order+1):row/2^(order-1),1:col/2^(order-1)),(lene-1),'u');%向上周期延拓
for i=1:row/2^(order-1);
for j=1:col/2^(order-1);
k=fix((i+1)/2);
if(mod(i,2)==0)
lodata=lo_ro*exloodata(k:k+leno-1,j);
hidata=hi_ro*exhiodata(k:k+leno-1,j);
data(i,j)=lodata+hidata;
else
lodata=lo_re*exloedata(k:k+lene-1,j);
hidata=hi_re*exhiedata(k:k+lene-1,j);
data(i,j)=lodata+hidata;
end
end
end
%行重构
exloodata=wextend('ac','ppd',data(1:row/2^(order-1),1:col/2^order),(leno-1),'l');%向左周期延拓
exloedata=wextend('ac','ppd',data(1:row/2^(order-1),1:col/2^order),(lene-1),'l');%向左周期延拓
exhiodata=wextend('ac','ppd',data(1:row/2^(order-1),(col/2^order+1):col/2^(order-1)),(leno-1),'l');%向左周期延拓
exhiedata=wextend('ac','ppd',data(1:row/2^(order-1),(col/2^order+1):col/2^(order-1)),(lene-1),'l');%向左周期延拓
for i=1:row/2^(order-1);
for j=1:row/2^(order-1);
k=fix((j+1)/2);
if(mod(j,2)==0)
lodata=lo_ro*exloedata(i,k:k+lene-1)';
hidata=hi_ro*exhiedata(i,k:k+lene-1)';
data(i,j)=lodata+hidata;
else
lodata=lo_re*exloodata(i,k:k+leno-1)';
hidata=hi_re*exhiodata(i,k:k+leno-1)';
data(i,j)=lodata+hidata;
end
end
end
data_r=data;
cal_energy.m
%计算最后一级分级高低频能量分布
function energy=cal_energy(data,order)
result=zeros(1,4);
[row,col]=size(data);
%求低频C(order)的能量
sum=0;
for i=1:row/2^order;
for j=1:row/2^order;
sum=sum+data(i,j)^2;
end
end
result(1,1)=sum;
%求d(order,1)的能量
sum=0;
for i=(row/2^order+1:row/2^(order-1))
for j=1:row/2^order;
sum=sum+data(i,j)^2;
end
end
result(1,2)=sum;
%求d(order,2)的能量
sum=0;
for i=1:row/2^order;
for j=(row/2^order+1:row/2^(order-1))
sum=sum+data(i,j)^2;
end
end
result(1,3)=sum;
%求d(order,3)的能量
sum=0;
for i=(row/2^order+1:row/2^(order-1))
for j=(col/2^order+1:col/2^(order-1))
sum=sum+data(i,j)^2;
end
end
result(1,4)=sum;
energy=result;
(4)PDM(Perceptual Distortion Metric)感知失真度量
没找到合适的代码。。。
(5)SSIM(Structural SIMilarity index)结构相似指数
SSIM 算法以图像的亮度(灰度均值)、对比度(灰度方差)、结构(两个图像灰度协方差)作为质量评估的三个因素。加入块形窗口计算局部ssim,同时使用高斯函数避免块效应。
function [mssim, ssim_map] = ssim(img1, img2, K, window, L)
% ========================================================================
% SSIM Index with automatic downsampling, Version 1.0
% Copyright(c) 2009 Zhou Wang
% All Rights Reserved.
%
% ----------------------------------------------------------------------
% Permission to use, copy, or modify this software and its documentation
% for educational and research purposes only and without fee is hereby
% granted, provided that this copyright notice and the original authors'
% names appear on all copies and supporting documentation. This program
% shall not be used, rewritten, or adapted as the basis of a commercial
% software or hardware product without first obtaining permission of the
% authors. The authors make no representations about the suitability of
% this software for any purpose. It is provided "as is" without express
% or implied warranty.
%----------------------------------------------------------------------
%
% This is an implementation of the algorithm for calculating the
% Structural SIMilarity (SSIM) index between two images
%
% Please refer to the following paper and the website with suggested usage
%
% Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image
% quality assessment: From error visibility to structural similarity,"
% IEEE Transactios on Image Processing, vol. 13, no. 4, pp. 600-612,
% Apr. 2004.
%
% http://www.ece.uwaterloo.ca/~z70wang/research/ssim/
%
% Note: This program is different from ssim_index.m, where no automatic
% downsampling is performed. (downsampling was done in the above paper
% and was described as suggested usage in the above website.)
%
% Kindly report any suggestions or corrections to zhouwang@ieee.org
%
%----------------------------------------------------------------------
%
%Input : (1) img1: the first image being compared
% (2) img2: the second image being compared
% (3) K: constants in the SSIM index formula (see the above
% reference). defualt value: K = [0.01 0.03]
% (4) window: local window for statistics (see the above
% reference). default widnow is Gaussian given by
% window = fspecial('gaussian', 11, 1.5);
% (5) L: dynamic range of the images. default: L = 255
%
%Output: (1) mssim: the mean SSIM index value between 2 images.
% If one of the images being compared is regarded as
% perfect quality, then mssim can be considered as the
% quality measure of the other image.
% If img1 = img2, then mssim = 1.
% (2) ssim_map: the SSIM index map of the test image. The map
% has a smaller size than the input images. The actual size
% depends on the window size and the downsampling factor.
%
%Basic Usage:
% Given 2 test images img1 and img2, whose dynamic range is 0-255
%
% [mssim, ssim_map] = ssim(img1, img2);
%
%Advanced Usage:
% User defined parameters. For example
%
% K = [0.05 0.05];
% window = ones(8);
% L = 100;
% [mssim, ssim_map] = ssim(img1, img2, K, window, L);
%
%Visualize the results:
%
% mssim %Gives the mssim value
% imshow(max(0, ssim_map).^4) %Shows the SSIM index map
%========================================================================
if (nargin < 2 | nargin > 5)
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
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
if (nargin == 3)
if ((M < 11) | (N < 11))
ssim_index = -Inf;
ssim_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5);
L = 255;
if (length(K) == 2)
if (K(1) < 0 | K(2) < 0)
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
else
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
end
if (nargin == 4)
[H W] = size(window);
if ((H*W) < 4 | (H > M) | (W > N))
ssim_index = -Inf;
ssim_map = -Inf;
return
end
L = 255;
if (length(K) == 2)
if (K(1) < 0 | K(2) < 0)
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
else
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
end
if (nargin == 5)
[H W] = size(window);
if ((H*W) < 4 | (H > M) | (W > N))
ssim_index = -Inf;
ssim_map = -Inf;
return
end
if (length(K) == 2)
if (K(1) < 0 | K(2) < 0)
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
else
ssim_index = -Inf;
ssim_map = -Inf;
return;
end
end
img1 = double(img1);
img2 = double(img2);
% automatic downsampling
f = max(1,round(min(M,N)/256));
%downsampling by f
%use a simple low-pass filter
if(f>1)
lpf = ones(f,f);
lpf = lpf/sum(lpf(:));
img1 = imfilter(img1,lpf,'symmetric','same');
img2 = imfilter(img2,lpf,'symmetric','same');
img1 = img1(1:f:end,1:f:end);
img2 = img2(1:f:end,1:f:end);
end
C1 = (K(1)*L)^2;
C2 = (K(2)*L)^2;
window = window/sum(sum(window));
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
(6)SIExt(Structural Information Extraction)结构信息提取
见https://blog.csdn.net/qq_36614557/article/details/86763655
(7)QILV(Quality of Image assessment based on Local Value)基于局部对比度的图像质量评估
见https://blog.csdn.net/qq_36614557/article/details/86764086
(8)PCQI(patch-based contrast quality index)基于小片的对比度质量评估
function [mpcqi, pcqi_map]= PCQI(img1, img2, window, L)
img1=double(rgb2gray(img1));
img2=double(rgb2gray(img2));
%========================================================================
%PCQI Index, Version 1.0, Sep. 2015
%
%This is an implementation of the algorithm for calculating the patch-based contrast
%quality index (PCQI) between two images. Please refer to the following paper:
%
%S. Wang, K. Ma, H. Yeganeh, Z. Wang and W. Lin, A Patch-Structure Representation
%Method for Quality Assessment of Contrast Changed Images, IEEE Signal Processing
%Letter, 2015.
%
%Kindly report any suggestions or corrections to sqwang1986@gmail.com
%
%----------------------------------------------------------------------
%
%Input : (1) img1: the first image being compared
% (2) img2: the second image being compared
% (4) window: local window for statistics (see the above
% reference). default widnow is Gaussian given by
% window = fspecial('gaussian', 11, 1.5);
% (5) L: dynamic range of the images. default: L = 256
%
%Output: (1) mpcqi : the mean PCQI index value between 2 images.
% (2) pcqi_map: the PCQI map of the test image.
%Default Usage:
% Given 2 test images img1 and img2, whose dynamic range is 0-255
% [mpcqi pcqi_map] = PCQI(img1, img2);
%
%Advanced Usage:
% User defined parameters. For example
% window = ones(8);
% L = 100;
% [mpcqi pcqi_map] = PCQI(img1, img2, window, L);
%========================================================================
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (nargin < 2 || nargin > 4)
mpcqi = -Inf;
pcqi_map = -Inf;
return;
end
if (size(img1) ~= size(img2))
mpcqi = -Inf;
pcqi_map = -Inf;
return;
end
[M N] = size(img1);
if (nargin == 2)
if ((M < 11) || (N < 11))
mpcqi = -Inf;
pcqi_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5); %
L = 256; %
end
if (nargin == 3)
[H W] = size(window);
if ((H*W) < 4 || (H > M) || (W > N))
mpcqi = -Inf;
pcqi_map = -Inf;
return
end
L = 255;
end
if (nargin == 4)
[H W] = size(window);
if ((H*W) < 4 || (H > M) || (W > N))
mpcqi = -Inf;
pcqi_map = -Inf;
return
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
window = window/sum(sum(window));
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;
sigma1_sq = max(0, sigma1_sq);
sigma2_sq = max(0, sigma2_sq);
C=3;
pcqi_map = (4/pi) *atan((sigma12 + C )./(sigma1_sq + C ));
pcqi_map = pcqi_map .*((sigma12 + C) ./(sqrt(sigma1_sq).*sqrt(sigma2_sq) + C));
pcqi_map = pcqi_map .*exp(-abs(mu1-mu2)/L);
mpcqi = mean2(pcqi_map);
return
(9)VIF(Visual Information Fidelity)视觉信息保真度
代码有点多,不列了,最后会统一放在一个包里的。
二、无参考(NF)
NF一共用了BRISQUE、CNR_NSS、UCIQE、UIQM四种。
三、自己瞎提出的算法
最后自己提出了一个基于多特征的全参考算法:
其中包括颜色特征、纹理特征、平滑度、一致性、清晰度、饱和度、熵、特征点、兴趣点等。
(1)颜色特征使用颜色矩表示(miu,signa,s分别为在R/G/B层的一阶矩、二阶矩、三阶矩):
颜色矩计算:
function colormom=getcolormom(I)
I_r=I(:,:,1);
I_g=I(:,:,2);
I_b=I(:,:,3);
colormom=zeros(1,9);
colormom(1)=mean(mean(I_r));
colormom(2)=sqrt(mean(mean((I_r-colormom(1)).^2)));
colormom(3)=(mean(mean(((I_r-colormom(1))/colormom(2)).^3)))^(1/3);
colormom(4)=mean(mean(I_g));
colormom(5)=sqrt(mean(mean((I_g-colormom(4)).^2)));
colormom(6)=(mean(mean(((I_g-colormom(4))/colormom(5)).^3)))^(1/3);
colormom(7)=mean(mean(I_b));
colormom(8)=sqrt(mean(mean((I_b-colormom(7)).^2)));
colormom(9)=(mean(mean(((I_b-colormom(7))/colormom(8)).^3)))^(1/3);
end
两个图像颜色矩的比较:(归一化后使用mse)
function fd=cal_colormom(I1,I2)%0 最好 1最差
w=zeros(1,9);
colormom1=getcolormom(I1);
colormom2=getcolormom(I2);
fd=0;
for i=1:9
w(i)=max(colormom1(i),colormom2(i));
fd=fd+abs(colormom1(i)-colormom2(i))/(9*w(i));
end
disp('Difference in Color Moment:');
disp(fd);
end
(2)纹理特征由Laws纹理能量和灰度共生矩阵表示:
灰度共生矩阵计算使用系统函数graycomatrix,并通过下式计算分数:
%% gray co-matrix
function fd=cal_gcm(I1,I2)
gcm1=graycomatrix(rgb2gray(I1));
gcm1=normalization2(gcm1);
gcm2=graycomatrix(rgb2gray(I2));
gcm2=normalization2(gcm2);
fd=MSE(gcm1,gcm2);
end
其中,normalization2为对二阶矩阵归一化的自定义函数:
function matrix=normalization2(matrix) %归一化到0~1
maxi=max(max(matrix));
mini=min(min(matrix));
for i=1:size(matrix,1)
for j=1:size(matrix,2)
matrix(i,j)=(matrix(i,j)-mini)/(maxi-mini);
end
end
end
Laws:
Laws计算:
function Laws=getLaws(i,j)%第i和第j个
L=[1,4,6,4,1];
E=[-1,-2,0,2,1];
S=[-1,0,2,0,1];
R=[1,-4,6,-4,1];
W=[-1,2,0,-2,1];
matrix=[L;E;S;R;W];
Laws=matrix(i,:)'*matrix(j,:);
end
两个图像Laws的比较:(每个算子卷积后图像归一化后的mse)
function fd=cal_Laws(I1,I2)
fd=0;
for i=1:5
for j=1:5
Laws=getLaws(i,j);
I1_conv=conv2(rgb2gray(I1),Laws);
I1_conv=normalization2(I1_conv);
I2_conv=conv2(rgb2gray(I2),Laws);
I2_conv=normalization2(I2_conv);
fd=fd+MSE(I1_conv,I2_conv);
end
end
fd=fd/25;
disp('Difference in all-kinds Laws Conv:');
disp(fd);
end
(3)清晰度Definition、平滑度Smoothness、一致性Uniformity、饱和度Saturation、熵Entropy:
分别计算如下:
%% definition
function difinition=getDifinition(I)
difinition=0;
I=rgb2gray(I);
[m,n]=size(I);
for i=1:m-1
for j=1:n-1
difinition=difinition+double(abs(I(i,j)-I(i+1,j))*abs(I(i,j)-I(i,j+1)));
end
end
end
%% smoothness
function smoothness=getSmoothness(I)
I=rgb2gray(I);
m=mean(mean(I));
var=sqrt(mean(mean((I-m).^2)));
smoothness=1-1/(1+var/255);
end
%% uniformity
function uniformity=getUniformity(I)
[p,~]=imhist(I);
p=p/sum(p);%每个灰度值的概率
uniformity=sum(p.^2);
end
%% saturation
function saturation=getSaturation(I)
saturation=0;
I_gray=rgb2gray(I);
[m,n,d]=size(I);
for i=1:m
for j=1:n
for k=1:d
saturation=saturation+double(abs(I(i,j,k)-I_gray(i,j)));
end
end
end
end
%% entropy
function entropy=getEntropy(I)
[p,~]=imhist(I);
p=p/sum(p);%每个灰度值的概率
entropy=0;
for i=1:256
if p(i)~=0
entropy=entropy+p(i)*log(p(i))/log(2);
end
end
entropy=-entropy;
end
两个图像各个属性的分数综合:(两者之差除以两者最大)
%% Property
function fd=cal_property(I1,I2)
difinition1=getDifinition(I1);
smoothness1=getSmoothness(I1);
uniformity1=getUniformity(I1);
saturation1=getSaturation(I1);
entropy1=getEntropy(I1);
difinition2=getDifinition(I2);
smoothness2=getSmoothness(I2);
uniformity2=getUniformity(I2);
saturation2=getSaturation(I2);
entropy2=getEntropy(I2);
property1={difinition1,smoothness1,uniformity1,saturation1,entropy1};
property2={difinition2,smoothness2,uniformity2,saturation2,entropy2};
disp('the Property of I1 in Difinition,Smoothness,Uniformity,Saturation and Entropy is as:');
disp(property1);
disp('the Property of I2 in Difinition,Smoothness,Uniformity,Saturation and Entropy is as:');
disp(property2);
fd=cell(5,1);
for i=1:5
fd{i}=abs(property2{i}-property1{i})/max(property2{i},property1{i});
end
disp('the Difference in Difinition,Smoothness,Uniformity,Saturation and Entropy is:');
disp(fd);
end
(4)特征点、兴趣点
特征点获取:使用sift,比较慢,获得该图像的特征点坐标和特征向量。
兴趣点获取:使用最简单的moravec检测器:
function MO=getMoravec(I)
I=rgb2gray(I);
[m,n,~]=size(I);
MO=zeros(m,n);
for i=2:m-1
for j=2:n-1
for k=i-1:i+1
for l=j-1:j+1
MO(i,j)=MO(i,j)+0.125*double(abs(I(k,l)-I(i,j)));
end
end
end
end
MO=normalization2(MO);
end
两个图像特征点比较(1-匹配到的点数乘2除以两个图像所有特征点数相加)
%% sift
function fd=cal_sift(I1,I2)
addpath('sift2')
scale=1;
[M,N]=size(I1);
I1_s=imresize(I1,[M/scale,N/scale]);
I2_s=imresize(I2,[M/scale,N/scale]);
[des1,~] = getFeatures(I1_s);
[des2,~] = getFeatures(I2_s);
matched = match(des1,des2);
[mx,my]=size(matched);
count=0;
for i=1:my
if matched(i)~=0
count=count+1;
end
end
fd=1-2*count/(size(des1,1)+size(des2,1));
disp('Features matched:');
disp(fd);
end
两个图像兴趣点比较:(手动写的匹配算法,计算和sift类似)
%% Moravec
function fd=cal_Moravec(I1,I2)
MO1=getMoravec(I1);
I1_gray=rgb2gray(I1);
MO2=getMoravec(I2);
I2_gray=rgb2gray(I2);
thresold_MO=0.2;
thresold_ditance=3;
MO1_mask=MO1>thresold_MO;
MO2_mask=MO2>thresold_MO;
num1=sum(sum(MO1_mask==1));
num2=sum(sum(MO2_mask==1));
[M,N]=size(MO1_mask);
% range for all pixels that I1 and I2's mask is 1 ,
% and distance of gray image is less than thresold
num_matched=0;
for i=1:M
for j=1:N
if MO1_mask(i,j)==1 && MO2_mask(i,j)==1 && abs(I1_gray(i,j)-I2_gray(i,j))<=thresold_ditance
num_matched=num_matched+1;
end
end
end
fd=1-2*num_matched/(num1+num2);
disp('Interest matched in global threshold 0.2:');
disp(fd);
end
(5)哈希值:
将图像调整为8*8大小,将大于(等于)均值的点置1,小于置0,然后将只有10的矩阵展开成一维。
function [string]=gethash(I)
I=imresize(I,[8,8]);
[m,n,d]=size(I);
I=I/4;
m3=zeros(1,3);
if d==3
for i=1:d
m3(i)=mean(mean(I(:,:,d)));
end
else
m=mean(mean(I));
end
string=zeros(1,64*d);
if d==1
for i=1:8
for j=1:8
if I(i,j)>=m
string(8*(i-1)+j)=1;
else
string(8*(i-1)+j)=0;
end
end
end
else
for deep=1:3
for i=1:8
for j=1:8
if I(i,j,deep)>=m3(deep)
string(64*(deep-1)+8*(i-1)+j)=1;
else
string(64*(deep-1)+8*(i-1)+j)=0;
end
end
end
end
end
end
计算两个图像的哈希值差:(二维时候中间的权值大,两边最小,判断每个一维的哈希,如果不相等那么就累加对应的mask)
%% hash
function fd=cal_hash(I1,I2)
string1=gethash(I1);
string2=gethash(I2);
[m,n]=size(string1);
length=m*n;
mask=zeros(8,8);
fd=0;
for i=1:8
for j=1:8
if i<=2 || i>=7 || j<=2 || j>=7
mask(i,j)=0.2;
elseif i<=3 || i>=6 || j<=3 || j>=6
mask(i,j)=0.4;
else
mask(i,j)=1;
end
end
end
mask=reshape(mask,[1,64]);
index=0;
for i=1:length
index=index+1;
if index>=65
index=index-64;
end
if string1(i)~=string2(i)
fd=fd+mask(index);
end
end
disp('Hash Value:');
disp(fd);
end
svd奇异值分解:
使用系统函数svd。分解得到奇异值,加权计算两个图像对应奇异值的差。
%% svd
function fd=cal_SVD(I1,I2)
[M,N,~]=size(I1);
[U1,S1,V1]=svd(double(rgb2gray(I1)));
[U2,S2,V2]=svd(double(rgb2gray(I2)));%奇异值分解后求每个奇异值不同的加权值
fd=0;
for i=1:min(M,N)
fd=fd+abs(S1(i,i)-S2(i,i))*(S1(i,i)+S2(i,i))/(sum(sum(S1))+sum(sum(S2)));
end
fd=fd/(max(sum(sum(S1)),sum(sum(S1))));
disp('Singular Value Using SVD:');
disp(fd);
end
最后总得分:w为权值(没时间通过神经网络去计算了,就瞎编的权值)
function fd_out=FD(I1,I2)
fd1=cal_hash(I1,I2);
fd2=cal_SVD(I1,I2);
fd3=cal_colormom(I1,I2);
fd4=cal_gcm(I1,I2);
fd5=cal_Laws(I1,I2);
fd6=cal_property(I1,I2);
fd7=cal_sift(I1,I2);
fd8=cal_Moravec(I1,I2);
fd={fd1,fd2,fd3,fd4,fd5,fd6{1},fd6{2},fd6{3},fd6{4},fd6{5},fd7,fd8};
w=[0.0121,0.0263,0.1003,0.1127,0.036,0.057,0.052,0.063,0.089,0.022,0.2556,0.1440];
fd_out=0;
for i=1:12
fd_out=w(i)*fd{i}+fd_out;
end
fd_out=1-fd_out;
end
以上所有代码:
链接:https://pan.baidu.com/s/19Tqvq1OQSF40uQSJ3OSR-A
提取码:4abi
复制这段内容后打开百度网盘手机App,操作更方便哦