function LPQdesc = lpq(img,winSize,decorr,freqestim,mode)
% Funtion LPQdesc=lpq(img,winSize,decorr,freqestim,mode) computes the Local Phase Quantization (LPQ) descriptor
% for the input image img. Descriptors are calculated using only valid pixels i.e. size(img)-(winSize-1).
%
% Inputs: (All empty or undefined inputs will be set to default values)
% img = N*N uint8 or double, format gray scale image to be analyzed.
% winSize = 1*1 double, size of the local window. winSize must be odd number and greater or equal to 3 (default winSize=3).
% decorr = 1*1 double, indicates whether decorrelation is used or not. Possible values are:
% 0 -> no decorrelation,
% (default) 1 -> decorrelation
% freqestim = 1*1 double, indicates which method is used for local frequency estimation. Possible values are:
% (default) 1 -> STFT with uniform window (corresponds to basic version of LPQ)
% 2 -> STFT with Gaussian window (equals also to Gaussian quadrature filter pair)
% 3 -> Gaussian derivative quadrature filter pair.
% mode = 1*n char, defines the desired output type. Possible choices are:
% (default) 'nh' -> normalized histogram of LPQ codewords (1*256 double vector, for which sum(result)==1)
% 'h' -> un-normalized histogram of LPQ codewords (1*256 double vector)
% 'im' -> LPQ codeword image ([size(img,1)-r,size(img,2)-r] double matrix)
%
% Output:
% LPQdesc = 1*256 double or size(img)-(winSize-1) uint8, LPQ descriptors histogram or LPQ code image (see "mode" above)
%
% Example usage:
% img=imread('cameraman.tif');
% LPQhist = lpq(img,3);
% figure; bar(LPQhist);
%
% Version published in 2010 by Janne Heikkil?, Esa Rahtu, and Ville Ojansivu
% Machine Vision Group, University of Oulu, Finland
%% Defaul parameters
% Local window size
if nargin<2 || isempty(winSize)
winSize=3; % default window size 3默认窗口大小3
end
% Decorrelation
if nargin<3 || isempty(decorr)
decorr=1; % use decorrelation by default默认情况下使用的去相关
end
rho=0.90; % Use correlation coefficient rho=0.9 as default采用相关系数ρ= 0.9为默认
% Local frequency estimation (Frequency points used [alpha,0], [0,alpha], [alpha,alpha], and [alpha,-alpha]) 局部频率估计(频率点[α,0 ],[ 0 ],[α,α,α],和[α,α])
if nargin<4 || isempty(freqestim)
freqestim=1; %use Short-Term Fourier Transform (STFT) with uniform window by default利用短时傅立叶变换(STFT)与均匀窗口默认
end
STFTalpha=1/winSize; % alpha in STFT approaches (for Gaussian derivative alpha=1) 在STFT方法α(高斯衍生物α= 1)
sigmaS=(winSize-1)/4; % Sigma for STFT Gaussian window (applied if freqestim==2)对短时傅立叶变换高斯窗σ(如果freqestim = = 2)
sigmaA=8/(winSize-1); % Sigma for Gaussian derivative quadrature filters (applied if freqestim==3)高斯导数的正交滤波器∑(如果freqestim = = 3)
% Output mode
if nargin<5 || isempty(mode)
mode='nh'; % return normalized histogram as default返回的归一化直方图作为默认
end
% Other
convmode='valid'; % Compute descriptor responses only on part that have full neigborhood. Use 'same' if all pixels are included (extrapolates image with zeros).计算部分,有充分的邻居描述反应。如果使用“相同”的所有像素都包括(推断的图像零)。
%% Check inputs
if size(img,3)~=1
error('Only gray scale image can be used as input');%唯一的灰度图像可以作为输入
end
if winSize<3 || rem(winSize,2)~=1
error('Window size winSize must be odd number and greater than equal to 3');%winSize是奇数窗口大小大于等于3
end
if sum(decorr==[0 1])==0
error('decorr parameter must be set to 0->no decorrelation or 1->decorrelation. See help for details.');%decorr参数必须设置为0或1 > >没有去相干解相关。请参阅帮助的细节
end
if sum(freqestim==[1 2 3])==0
error('freqestim parameter must be 1, 2, or 3. See help for details.');%freqestim参数必须是1,2,或3。请参阅帮助的细节
end
if sum(strcmp(mode,{'nh','h','im'}))==0
error('mode must be nh, h, or im. See help for details.');%模式必须NH,H,或IM。请参阅帮助的细节
end
%% Initialize
img=double(img); % Convert image to double图像转换到双
r=(winSize-1)/2; % Get radius from window size从窗口的大小半径
x=-r:r; % Form spatial coordinates in window在窗体的空间坐标
u=1:r; % Form coordinates of positive half of the Frequency domain (Needed for Gaussian derivative)对频率域正半形式的坐标(高斯导数需要)
%% Form 1-D filters形成1-D滤波器
if freqestim==1 % STFT uniform windowSTFT均匀窗口
% Basic STFT filters基本的STFT滤波器
w0=(x*0+1);
w1=exp(complex(0,-2*pi*x*STFTalpha));
w2=conj(w1);
end
%% Run filters to compute the frequency response in the four points. Store real and imaginary parts separately运行过滤器来计算在四点的频率响应。分开存储的实部和虚部
% Run first filter首先运行过滤器
filterResp=conv2(conv2(img,w0.',convmode),w1,convmode);
% Initilize frequency domain matrix for four frequency coordinates (real and imaginary parts for each frequency).initilize频域矩阵四频率坐标(每个频率的实部和虚部)
freqResp=zeros(size(filterResp,1),size(filterResp,2),8);
% Store filter outputs存储滤波器输出
freqResp(:,:,1)=real(filterResp);
freqResp(:,:,2)=imag(filterResp);
% Repeat the procedure for other frequencies对于其它频率重复的程序
filterResp=conv2(conv2(img,w1.',convmode),w0,convmode);
freqResp(:,:,3)=real(filterResp);
freqResp(:,:,4)=imag(filterResp);
filterResp=conv2(conv2(img,w1.',convmode),w1,convmode);
freqResp(:,:,5)=real(filterResp);
freqResp(:,:,6)=imag(filterResp);
filterResp=conv2(conv2(img,w1.',convmode),w2,convmode);
freqResp(:,:,7)=real(filterResp);
freqResp(:,:,8)=imag(filterResp);
% Read the size of frequency matrix阅读频率矩阵大小
[freqRow,freqCol,freqNum]=size(freqResp);
%% If decorrelation is used, compute covariance matrix and corresponding whitening transform如果去相关的应用,计算协方差矩阵和相应的白化变换
if decorr == 1
% Compute covariance matrix (covariance between pixel positions x_i and x_j is rho^||x_i-x_j||)计算协方差矩阵(协方差之间的像素位置x_i和x_j是Rho ^ | | x_i-x_j | |)
[xp,yp]=meshgrid(1:winSize,1:winSize);
pp=[xp(:) yp(:)];
dd=dist(pp,pp');
C=rho.^dd;
% Form 2-D filters q1, q2, q3, q4 and corresponding 2-D matrix operator M (separating real and imaginary parts)形成二维滤波器Q1,Q2,Q3,Q4和相应的二维矩阵算子M(分离的实部和虚部)
q1=w0.'*w1;
q2=w1.'*w0;
q3=w1.'*w1;
q4=w1.'*w2;
u1=real(q1); u2=imag(q1);
u3=real(q2); u4=imag(q2);
u5=real(q3); u6=imag(q3);
u7=real(q4); u8=imag(q4);
M=[u1(:)';u2(:)';u3(:)';u4(:)';u5(:)';u6(:)';u7(:)';u8(:)'];
% Compute whitening transformation matrix V计算白化变换矩阵V
D=M*C*M';
A=diag([1.000007 1.000006 1.000005 1.000004 1.000003 1.000002 1.000001 1]); % Use "random" (almost unit) diagonal matrix to avoid multiple eigenvalues.使用“随机”(基本单元)以避免多个特征值对角矩阵
[U,S,V]=svd(A*D*A);
% Reshape frequency response重塑的频率响应
freqResp=reshape(freqResp,[freqRow*freqCol,freqNum]);
% Perform whitening transform进行白化变换
freqResp=(V.'*freqResp.').';
% Undo reshape撤消重塑
freqResp=reshape(freqResp,[freqRow,freqCol,freqNum]);
end
%% Perform quantization and compute LPQ codewords进行量化和计算LPQ码字
LPQdesc=zeros(freqRow,freqCol); % Initialize LPQ code word image (size depends whether valid or same area is used)初始化代码字(LPQ图像大小取决于是否有效或同一地区使用)
for i=1:freqNum
LPQdesc=LPQdesc+(double(freqResp(:,:,i))>0)*(2^(i-1));
end
%% Switch format to uint8 if LPQ code image is required as output交换格式的卡片如果LPQ编码图像所输出
if strcmp(mode,'im')
LPQdesc=uint8(LPQdesc);
end
%% Histogram if needed如果所需的直方图
if strcmp(mode,'nh') || strcmp(mode,'h')
LPQdesc=hist(LPQdesc(:),0:255);
end
%% Normalize histogram if needed如果需要直方图�