Gaussian field consensus论文解读及MATLAB实现

作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/

一、Introduction

论文:Wang G , Chen Y , Zheng X . Gaussian field consensus: A robust nonparametric matching method for outlier rejection[J]. Pattern Recognition, 2018, 74:305-316.

An image pair and its putative correspondences. Blue and red lines represent inliers and outliers respectively.

二、GFC algorithm

三、Experimental results

四、Conclusion

五、Code

results.m

function criterion=results()
% GFC;
% 读取图像及对应关系数据
% church
% ImgName1 = './TestData/church1.jpg' ;
% ImgName2 = './TestData/church2.jpg' ;
% load('./TestData/church.mat');
% eye
ImgName1 = './TestData/14_a.jpg' ;
ImgName2 = './TestData/14_b.jpg' ;
load('./TestData/14_20.mat'); I1 = imread(ImgName1) ;
I2 = imread(ImgName2) ;
t0=cputime;
[precision, recall, accuracy, f1]=demo_GFC(I1, I2, X, Y, CorrectIndex);
run_time=cputime-t0;
criterion=[precision; recall; accuracy; f1; run_time];

demo_GFC.m

function [precision, recall, accuracy, f1]=demo_GFC(I1, I2, X, Y, CorrectIndex)
label=CorrectIndex;
delta =0.5;
[index] = GFC_match(X,Y,delta);
[precision, recall, accuracy, f1] = evaluatePR(label, index, size(X,1)); % Plot results
%原始结果
% N=size(X);
% temp=1:N;
% temp=temp';
% plot_matches(I1, I2, X, Y, temp, label);
%实验结果
plot_matches(I1, I2, X, Y, index, label);

adjacency.m

function A = adjacency(DATA, TYPE, PARAM, DISTANCEFUNCTION);

% Compute the adjacency graph of the data set DATA
%
% A = adjacency(DATA, TYPE, PARAM, DISTANCEFUNCTION);
%
% DATA - NxK matrix. Data points are rows.
% TYPE - string 'nn' or string 'epsballs'.
% PARAM - integer if TYPE='nn', real number if TYPE='epsballs'.
% DISTANCEFUNCTION - function mapping a (DxM) and a (D x N) matrix
% to an M x N distance matrix (D:dimensionality)
% Returns: A, sparse symmetric NxN matrix of distances between the
% adjacent points.
%
% Example:
%
% A = adjacency(X,'nn',6)
% A contains the adjacency matrix for the data
% set X. For each point, the distances to 6 adjacent points are
% stored. N
%
% Note: the adjacency relation is symmetrized, i.e. if
% point a is adjacent to point b, then point b is also considered to be
% adjacent to point a.
%
%
% Author:
%
% Mikhail Belkin
% misha@math.uchicago.edu
%
% Modified by: Vikas Sindhwani
% June 2004 % disp('Computing Adjacency Graph'); if (nargin < 3) | (strcmp(TYPE,'nn') & strcmp(TYPE,'epsballs')) | ~isreal(PARAM) disp(sprintf('ERROR: Too few arguments given or incorrect arguments.\n'));
disp(sprintf('USAGE:\n A = laplacian(DATA, TYPE, PARAM)'));
disp(sprintf('DATA - the data matrix. Data points are rows.'));
disp(sprintf('Nearest neigbors: TYPE =''nn'' PARAM = number of nearest neigbors'));
disp(sprintf('Epsilon balls: TYPE =''epsballs'' PARAM = redius of the ball\n'));
return;
end n = size(DATA,1);
%disp (sprintf ('DATA: %d points in %d dimensional space.',n,size (DATA,2))); switch TYPE
case {'nn'}
% disp(sprintf('Creating the adjacency matrix. Nearest neighbors, N=%d.', PARAM));
case{'eps', 'epsballs'}
%disp(sprintf('Creating the adjacency matrix. Epsilon balls, eps=%f.', PARAM));
end; A = sparse(n,n);
step = 100; if (strcmp(TYPE,'nn'))
for i1=1:step:n
i2 = i1+step-1;
if (i2> n)
i2=n;
end;
XX= DATA(i1:i2,:);
dt = feval(DISTANCEFUNCTION, XX',DATA');
[Z,I] = sort ( dt,2); for i=i1:i2
if ( mod(i, 500) ==0)
%disp(sprintf('%d points processed.', i));
end;
for j=2:PARAM+1
A(i,I(i-i1+1,j))= Z(i-i1+1,j);
A(I(i-i1+1,j),i)= Z(i-i1+1,j);
end;
end end; % epsilon balls
else
for i1=1:step:n
i2 = i1+step-1;
if (i2> n)
i2=n;
end; XX= DATA(i1:i2,:);
dt = feval(DISTANCEFUNCTION, XX',DATA');
[Z,I] = sort ( dt,2 ); for i=i1:i2
% if ( mod(i, 500) ==0) disp(sprintf('%d points processed.', i)); end;
j=2;
while ( (Z(i-i1+1,j) < PARAM))
j = j+1;
jj = I(i-i1+1,j);
A(i,jj)= Z(i-i1+1,j);
A(jj,i)= Z(i-i1+1,j);
end;
end
end;
end;

con_K.m

function K=con_K(x,y,beta)
if nargin<3
error('Error! Not enough input parameters.');
end
ks=-2 * beta^2;
[n, d]=size(x);
[m, d]=size(y);
K=repmat(x,[1 1 m])-permute(repmat(y,[1 1 n]),[3 2 1]);
K=squeeze(sum(K.^2,2));
K=K/ks;
K=exp(K);

costfun_GFC.m

function [E, G] = costfun_GFC(param, X, Y,  U, beta,lambda,sigma2)
[N, D] = size(X);
M = size(U, 2);
Alpha = reshape(param, [M D]);
options=ml_options('Kernel','rbf', 'KernelParam', beta,'NN',5);
options.GraphWeights= 'heat';
options.GraphWeightParam=sqrt(sigma2);
L=laplacian(X,'nn',options);
E=lambda * trace(Alpha'*U'*L*U*Alpha);
V = Y-(X+ U*Alpha);
a = -2 / N / (2*sigma2)^(D/2);
F = exp(-sum(V.^2, 2) / (2*sigma2));
E = E + a * sum(F);
G = -a * U' * ( V .* repmat(F, [1 D]) / sigma2 ) + 2*lambda * U'* L * U *Alpha;

euclidean.m

function d = euclidean(a,b,df)
% EUCLIDEAN - computes Euclidean distance matrix
%
% E = euclidean(A,B)
%
% A - (DxM) matrix
% B - (DxN) matrix
% df = 1, force diagonals to be zero; 0 (default), do not force
%
% Returns:
% E - (MxN) Euclidean distances between vectors in A and B
%
%
% Description :
% This fully vectorized (VERY FAST!) m-file computes the
% Euclidean distance between two vectors by:
%
% ||A-B|| = sqrt ( ||A||^2 + ||B||^2 - 2*A.B )
%
% Example :
% A = rand(400,100); B = rand(400,200);
% d = distance(A,B); % Author : Roland Bunschoten
% University of Amsterdam
% Intelligent Autonomous Systems (IAS) group
% Kruislaan 403 1098 SJ Amsterdam
% tel.(+31)20-5257524
% bunschot@wins.uva.nl
% Last Rev : Wed Oct 20 08:58:08 MET DST 1999
% Tested : PC Matlab v5.2 and Solaris Matlab v5.3 % Copyright notice: You are free to modify, extend and distribute
% this code granted that the author of the original code is
% mentioned as the original author of the code. % Fixed by JBT (3/18/00) to work for 1-dimensional vectors
% and to warn for imaginary numbers. Also ensures that
% output is all real, and allows the option of forcing diagonals to
% be zero. if (nargin < 2)
error('Not enough input arguments');
end if (nargin < 3)
df = 0; % by default, do not force 0 on the diagonal
end if (size(a,1) ~= size(b,1))
error('A and B should be of same dimensionality');
end if ~(isreal(a)*isreal(b))
disp('Warning: running distance.m with imaginary numbers. Results may be off.');
end if (size(a,1) == 1)
a = [a; zeros(1,size(a,2))];
b = [b; zeros(1,size(b,2))];
end aa=sum(a.*a); bb=sum(b.*b); ab=a'*b;
d = sqrt(repmat(aa',[1 size(bb,2)]) + repmat(bb,[size(aa,2) 1]) - 2*ab); % make sure result is all real
d = real(d); % force 0 on the diagonal?
if (df==1)
d = d.*(1-eye(size(d)));
end

evaluatePR.m

function [precision, recall, accuracy, f1] = evaluatePR(CorrectIndex, Index, siz)
tmp=zeros(1, siz);
tmp(Index) = 1;
tmp(CorrectIndex) = tmp(CorrectIndex)+1;
GFCCorrect = find(tmp == 2);
NumCorrectIndex = length(CorrectIndex);
NumGFCIndex = length(Index);
NumGFCCorrect = length(GFCCorrect);
% corrRate = NumCorrectIndex/siz;
precision = NumGFCCorrect/NumGFCIndex;
TP=NumGFCCorrect;
FP=NumGFCIndex-TP;
recall = NumGFCCorrect/NumCorrectIndex;
FN=NumCorrectIndex-TP;
TN=siz-NumGFCIndex-FN;
accuracy=(TP+TN)/(TP+TN+FP+FN);
f1=(2*precision*recall)/(precision+recall);

GFC.m

function [idt, V , param] = GFC(X, Y, delta)
[N1, D] = size(X);
eta=0.98;
history.x = [ ];
history.fval = [ ];
beta =1.5;
lambda = 3;
sigma2=power(det(X'*X/N1), 1/(2^D));
M=round(sqrt(N1));
x0 = zeros(M*D, 1);
options = optimset( 'display','iter');
options = optimset(options, 'outputfcn',@GFCoutfun);
options = optimset( options, 'LargeScale','off');
options = optimset(options, 'MaxFunEvals', 100);
options = optimset(options, 'MaxIter', 100);
options = optimset(options, 'GradObj', 'on');
U=get_U(X,beta,M);
param = fminunc(@(x)costfun_GFC(x, X, Y, U, beta, lambda, sigma2), x0, options);
Alpha = reshape(param, [M D]);
V=X+U*Alpha;
Pb = exp(-sum((Y-V).^2, 2) / (sigma2)) ;
idt = find(Pb > delta);
function stop = GFCoutfun(x,optimValues,state,varargin)
stop = false;
switch state
case 'init'
case 'iter'
history.fval = [history.fval; optimValues.fval];
history.x = [history.x; reshape(x,1,length(x))];
Alpha = reshape(x, [M D]);
V=X+U*Alpha;
sigma2=sigma2 * eta;
case 'done'
otherwise
end
end
end function U=get_U(X,beta,M)
tmp_X = unique(X, 'rows');
idx = randperm(size(tmp_X,1));
idx = idx(1:min(M,size(tmp_X,1)));
ctrl_pts=tmp_X(idx,:);
U = con_K(X, ctrl_pts, beta);
end

GFC_match.m

function [idt]=GFC_match(X,Y,delta)
Ni=2;
Xk=X;
k=1;
s=1;
while s
X2=Xk;Y2=Y;
normal.xm=0; normal.ym=0;
normal.xscale=1; normal.yscale=1;
[nX, nY, normal]=norm2s(X2,Y2);
[idt, trans] = GFC(nX,nY,delta);
trans=(trans)*normal.yscale+repmat(normal.ym,size(Y2,1),1);
Xk = trans;
if k==Ni
s=0;
else
k=k+1;
end
end
end

laplacian.m

function L = laplacian(DATA, TYPE, options)  

% Calculate the graph laplacian of the adjacency graph of data set DATA.
%
% L = laplacian(DATA, TYPE, PARAM)
%
% DATA - NxK matrix. Data points are rows.
% TYPE - string 'nn' or string 'epsballs'
% options - Data structure containing the following fields
% NN - integer if TYPE='nn' (number of nearest neighbors),
% or size of 'epsballs'
%
% DISTANCEFUNCTION - distance function used to make the graph
% WEIGHTTYPPE='binary' | 'distance' | 'heat'
% WEIGHTPARAM= width for heat kernel
% NORMALIZE= 0 | 1 whether to return normalized graph laplacian or not
%
% Returns: L, sparse symmetric NxN matrix
%
% Author:
%
% Mikhail Belkin
% misha@math.uchicago.edu
%
% Modified by: Vikas Sindhwani (vikass@cs.uchicago.edu)
% June 2004 % disp('Computing Graph Laplacian.'); NN=options.NN;
DISTANCEFUNCTION=options.GraphDistanceFunction;
WEIGHTTYPE=options.GraphWeights;
WEIGHTPARAM=options.GraphWeightParam;
NORMALIZE=options.GraphNormalize; % calculate the adjacency matrix for DATA
A = adjacency(DATA, TYPE, NN, DISTANCEFUNCTION); W = A; % disassemble the sparse matrix
[A_i, A_j, A_v] = find(A); switch WEIGHTTYPE case 'distance'
for i = 1: size(A_i)
W(A_i(i), A_j(i)) = A_v(i);
end; case 'binary'
disp('Laplacian : Using Binary weights ');
for i = 1: size(A_i)
W(A_i(i), A_j(i)) = 1;
end; case 'heat'
% disp(['Laplacian : Using Heat Kernel sigma : ' num2str(WEIGHTPARAM)]);
t=WEIGHTPARAM;
for i = 1: size(A_i)
W(A_i(i), A_j(i)) = exp(-A_v(i)^2/(2*t*t));
end; otherwise
error('Unknown Weighttype');
end D = sum(W(:,:),2); if NORMALIZE==0
L = spdiags(D,0,speye(size(W,1)))-W;
else % normalized laplacian
D=diag(sqrt(1./D));
L=eye(size(W,1))-D*W*D;
end

ml_options.m

function options = ml_options(varargin)

% ML_OPTIONS - Generate/alter options structure for training classifiers
% ----------------------------------------------------------------------------------------%
% options = ml_options('PARAM1',VALUE1,'PARAM2',VALUE2,...)
%
% Creates an options structure "options" in which the named parameters
% have the specified values. Any unspecified parameters are set to
% default values specified below.
% options = ml_options (with no input arguments) creates an options structure
% "options" where all the fields are set to default values specified below.
%
% Example:
% options=ml_options('Kernel','rbf','KernelParam',0.5,'NN',6);
%
% "options" structure is as follows:
%
% Field Name: Description : default
% -------------------------------------------------------------------------------------
% 'Kernel': 'linear' | 'rbf' | 'poly' : 'linear'
% 'KernelParam': -- | sigma | degree : 1
% 'NN': number of nearest neighbor : 6
%'GraphDistanceFuncion': distance function for graph: 'euclidean' | 'cosine' : 'euclidean'
% 'GraphWeights': 'binary' | 'distance' | 'heat' : 'binary'
% 'GraphWeightParam': e.g For heat kernel, width to use : 1
% 'GraphNormalize': Use normalized Graph laplacian (1) or not (0) : 1
% 'ClassEdges': Disconnect Edges across classes:yes(1) no (0) : 0
% 'gamma_A': RKHS norm regularization parameter (Ambient) : 1
% 'gamma_I': Manifold regularization parameter (Intrinsic) : 1
% -------------------------------------------------------------------------------------
%
% Acknowledgement: Adapted from Anton Schwaighofer's software:
% http://www.cis.tugraz.at/igi/aschwaig/software.html
%
% Author: Vikas Sindhwani (vikass@cs.uchicago.edu)
% June 2004
% ----------------------------------------------------------------------------------------% % options default values
options = struct('Kernel','linear', ...
'KernelParam',1, ...
'NN',6,...
'GraphDistanceFunction','euclidean',...
'GraphWeights', 'binary', ...
'GraphWeightParam',1, ...
'GraphNormalize',1, ...
'ClassEdges',0,...
'gamma_A',1.0,...
'gamma_I',1.0); numberargs = nargin; Names = fieldnames(options);
[m,n] = size(Names);
names = lower(Names); i = 1;
while i <= numberargs
arg = varargin{i};
if isstr(arg)
break;
end
if ~isempty(arg)
if ~isa(arg,'struct')
error(sprintf('Expected argument %d to be a string parameter name or an options structure.', i));
end
for j = 1:m
if any(strcmp(fieldnames(arg),Names{j,:}))
val = getfield(arg, Names{j,:});
else
val = [];
end
if ~isempty(val)
[valid, errmsg] = checkfield(Names{j,:},val);
if valid
options = setfield(options, Names{j,:},val);
else
error(errmsg);
end
end
end
end
i = i + 1;
end % A finite state machine to parse name-value pairs.
if rem(numberargs-i+1,2) ~= 0
error('Arguments must occur in name-value pairs.');
end
expectval = 0;
while i <= numberargs
arg = varargin{i};
if ~expectval
if ~isstr(arg)
error(sprintf('Expected argument %d to be a string parameter name.', i));
end
lowArg = lower(arg);
j = strmatch(lowArg,names);
if isempty(j)
error(sprintf('Unrecognized parameter name ''%s''.', arg));
elseif length(j) > 1
% Check for any exact matches (in case any names are subsets of others)
k = strmatch(lowArg,names,'exact');
if length(k) == 1
j = k;
else
msg = sprintf('Ambiguous parameter name ''%s'' ', arg);
msg = [msg '(' Names{j(1),:}];
for k = j(2:length(j))'
msg = [msg ', ' Names{k,:}];
end
msg = sprintf('%s).', msg);
error(msg);
end
end
expectval = 1;
else
[valid, errmsg] = checkfield(Names{j,:}, arg);
if valid
options = setfield(options, Names{j,:}, arg);
else
error(errmsg);
end
expectval = 0;
end
i = i + 1;
end function [valid, errmsg] = checkfield(field,value)
% CHECKFIELD Check validity of structure field contents.
% [VALID, MSG] = CHECKFIELD('field',V) checks the contents of the specified
% value V to be valid for the field 'field'.
% valid = 1;
errmsg = '';
if isempty(value)
return
end
isFloat = length(value==1) & isa(value, 'double');
isPositive = isFloat & (value>=0);
isString = isa(value, 'char');
range = [];
requireInt = 0;
switch field
case 'NN'
requireInt = 1;
range=[1 Inf];
case 'GraphNormalize'
requireInt = 1;
range=[0 1];
case 'ClassEdges'
requireInt = 1;
range=[0 1];
case {'Kernel', 'GraphWeights', 'GraphDistanceFunction'}
if ~isString,
valid = 0;
errmsg = sprintf('Invalid value for %s parameter: Must be a string', field);
end
case {'gamma_A', 'gamma_I','GraphWeightParam'}
range = [0 Inf];
case 'KernelParam'
valid = 1;
otherwise
valid = 0;
error('Unknown field name for Options structure.')
end if ~isempty(range),
if (value<range(1)) | (value>range(2)),
valid = 0;
errmsg = sprintf('Invalid value for %s parameter: Must be scalar in the range [%g..%g]', ...
field, range(1), range(2));
end
end if requireInt & ((value-round(value))~=0),
valid = 0;
errmsg = sprintf('Invalid value for %s parameter: Must be integer', ...
field);
end

norm2s.m

function  [X, Y, normal] =norm2s(x,y)
x = double(x);
y = double(y); n=size(x,1);
m=size(y,1); normal.xm=mean(x);
normal.ym=mean(y); x=x-repmat(normal.xm,n,1);
y=y-repmat(normal.ym,m,1); normal.xscale=sqrt(sum(sum(x.^2,2))/n);
normal.yscale=sqrt(sum(sum(y.^2,2))/m); X=x/normal.xscale;
Y=y/normal.yscale;

plot_matches.m

function plot_matches(I1, I2, X, Y, VFCIndex, CorrectIndex)
% PLOT_MATCHES(I1, I2, X, Y, VFCINDEX, CORRECTINDEX)
% only plots the ture positives with blue lines, false positives with red
% lines, and false negatives with green lines. For visibility, it plots at
% most NUMPLOT (Default value is 50) matches proportionately.
%
% Input:
% I1, I2: Tow input images.
%
% X, Y: Coordinates of intrest points in I1, I2 respectively.
%
% VFCIndex: Indexes preserved by VFC.
%
% CorrectIndex: Ground truth indexes.
%
% See also:: VFC(), FastVFC(), SparseVFC(). % Authors: Jiayi Ma (jyma2010@gmail.com)
% Date: 04/17/2012 % Define the maximum number of matches to plot %blue = true positive+true negative, green = false negative, red = false positive
NumPlot = 50; TruePos = intersect(VFCIndex, CorrectIndex);%Ture positive
FalsePos = setdiff(VFCIndex, CorrectIndex); %False positive
FalseNeg = setdiff(CorrectIndex, VFCIndex); %False negative NumPos = length(TruePos)+length(FalsePos)+length(FalseNeg);
if NumPos > NumPlot
t_p = length(TruePos)/NumPos;
n1 = round(t_p*NumPlot);
f_p = length(FalsePos)/NumPos;
n2 = ceil(f_p*NumPlot);
f_n = length(FalseNeg)/NumPos;
n3 = ceil(f_n*NumPlot);
else
n1 = length(TruePos);
n2 = length(FalsePos);
n3 = length(FalseNeg);
end per = randperm(length(TruePos));
TruePos = TruePos(per(1:n1));
per = randperm(length(FalsePos));
FalsePos = FalsePos(per(1:n2));
per = randperm(length(FalseNeg));
FalseNeg = FalseNeg(per(1:n3)); interval = 20;
WhiteInterval = 255*ones(size(I1,1), interval, 3);
figure;imagesc(cat(2, I1, WhiteInterval, I2)) ;
hold on ;
line([X(FalsePos,1)'; Y(FalsePos,1)'+size(I1,2)+interval], [X(FalsePos,2)' ; Y(FalsePos,2)'],'linewidth', 1, 'color', 'r') ;
line([X(FalseNeg,1)'; Y(FalseNeg,1)'+size(I1,2)+interval], [X(FalseNeg,2)' ; Y(FalseNeg,2)'],'linewidth', 1, 'color', 'g') ;
line([X(TruePos,1)'; Y(TruePos,1)'+size(I1,2)+interval], [X(TruePos,2)' ; Y(TruePos,2)'],'linewidth', 1, 'color', 'b') ;
axis equal ;axis off ;
drawnow;

实验数据:TestData.rar

实验结果

criterion =

    0.9259
1.0000
0.9604
0.9615
0.8125

六、Reference

Gaussian field consensus论文解读及MATLAB实现的更多相关文章

  1. zz扔掉anchor!真正的CenterNet——Objects as Points论文解读

    首发于深度学习那些事 已关注写文章   扔掉anchor!真正的CenterNet——Objects as Points论文解读 OLDPAN 不明觉厉的人工智障程序员 ​关注他 JustDoIT 等 ...

  2. 论文解读第三代GCN《 Deep Embedding for CUnsupervisedlustering Analysis》

    Paper Information Titlel:<Semi-Supervised Classification with Graph Convolutional Networks>Aut ...

  3. 论文解读(IDEC)《Improved Deep Embedded Clustering with Local Structure Preservation》

    Paper Information Title:<Improved Deep Embedded Clustering with Local Structure Preservation>A ...

  4. itemKNN发展史----推荐系统的三篇重要的论文解读

    itemKNN发展史----推荐系统的三篇重要的论文解读 本文用到的符号标识 1.Item-based CF 基本过程: 计算相似度矩阵 Cosine相似度 皮尔逊相似系数 参数聚合进行推荐 根据用户 ...

  5. CVPR2019 | Mask Scoring R-CNN 论文解读

    Mask Scoring R-CNN CVPR2019 | Mask Scoring R-CNN 论文解读 作者 | 文永亮 研究方向 | 目标检测.GAN 推荐理由: 本文解读的是一篇发表于CVPR ...

  6. AAAI2019 | 基于区域分解集成的目标检测 论文解读

    Object Detection based on Region Decomposition and Assembly AAAI2019 | 基于区域分解集成的目标检测 论文解读 作者 | 文永亮 学 ...

  7. NIPS2018最佳论文解读:Neural Ordinary Differential Equations

    NIPS2018最佳论文解读:Neural Ordinary Differential Equations 雷锋网2019-01-10 23:32     雷锋网 AI 科技评论按,不久前,NeurI ...

  8. [论文解读] 阿里DIEN整体代码结构

    [论文解读] 阿里DIEN整体代码结构 目录 [论文解读] 阿里DIEN整体代码结构 0x00 摘要 0x01 文件简介 0x02 总体架构 0x03 总体代码 0x04 模型基类 4.1 基本逻辑 ...

  9. 【抓取】6-DOF GraspNet 论文解读

    [抓取]6-DOF GraspNet 论文解读 [注]:本文地址:[抓取]6-DOF GraspNet 论文解读 若转载请于明显处标明出处. 前言 这篇关于生成抓取姿态的论文出自英伟达.我在读完该篇论 ...

随机推荐

  1. jQuery实现回车触发登录按钮的功能

    jQuery实现回车触发登录按钮的功能,代码如下: $('body').keyup(function(e){ if(e.keyCode===13){ $('.login').click() } }) ...

  2. IT兄弟连 HTML5教程 CSS3属性特效 文字阴影

    文字阴影是可以叠加的.最基本可以给出四个值,用法如下: text-shadow:x y blur color 文字阴影的参数说明如表1所示. 表1  CSS3文字阴影参数说明 横向偏移量和纵向偏移量可 ...

  3. WebMvcConfigurationSupport 避坑指南

    通过返回WebMvcConfigurationSupport 的方式, 默认会覆盖 Spring boot的自动配置, 导致配置失效静态资源无法访问:但是在WebMvcConfigurationadp ...

  4. 测试人员必备之 mysql 常用命令学习指南

    1.数据库连接 1.通过命令行连接数据库 [root@localhost ~]# mysql -u root -p Enter password: 输入以上命令,回车后输入密码,回车,出现 mysql ...

  5. C# 使用TopShelf实现Windows服务部署

    一.TopShelf介绍 topShelf是创建Windows服务的一种方式,可以方便管理应用服务,最大广泛应用于,数据实时接收,定时推送等. 二.TopShelf使用 1.安装 TopShelf程序 ...

  6. ECMAScript 5 特性

    ECMAScript 5 也称为 ES5 和 ECMAScript 2009. ECMAScript 5 特性 这些是 2009 年发布的新特性: "use strict" 指令 ...

  7. JavaWeb入门——在Windows环境下安装Tomcat服务器

    JavaWeb入门——在Windows环境下安装Tomcat服务器 摘要:本文主要学习如何在Windows环境中下载并安装Tomcat服务器. 下载 获取安装包 推荐去官网上下载Tomcat: htt ...

  8. 大数据环境下mongoDB要加索引

    mongodb在存储大数据时,对查询的字段需要添加索引,我测试的是阿里云30多万的数据量,不加索引查询已经到8秒,而添加索引之后是毫秒级! 为集合加索引 mongodb支持内嵌属性添加索引 db.ag ...

  9. VO(视图模型) 与 DTO(数据传输对象)的区别

    目录 VO(视图模型) 与 DTO(数据传输对象)的区别 1.VO与DTO概念 2.VO 视图模型的必要性与解耦 2.1 视图模型 2.2 视图模型存在的必要性 2.3 视图模型的解耦 3.DTO 存 ...

  10. IDEA编译报错Error:java: Compilation failed: internal java compiler error

    根据报错可以知道是编译某个模块报错, 接下来就是检查这个模块的编译版本 解决办法很简单:File-->Setting...-->Build,Execution,Deployment--&g ...