📄 build_knn.m
字号:
function [index,distance] = build_knn(T,ov,k,retain,mode)
%
% |----------------------------------------------------------|
% | Hybrid Texture Synthesis MATLAB package |
% | |
% | Author: Andrew Nealen |
% | Discrete Geometric Modeling Group |
% | Technische Universitaet Darmstadt, Germany |
% | |
% | Note: This is part of the prototype implementation |
% | accompanying our paper/my thesis |
% | |
% | Hybrid Texture Synthesis. A. Nealen and M. Alexa |
% | Eurographics Symposium on Rendering 2003 |
% | |
% | Hybrid Texture Synthesis. A. Nealen |
% | Diplomarbeit (MSc), TU Darmstadt, 2003 |
% | |
% | See the paper/thesis for further details. |
% |----------------------------------------------------------|
%
% BUILD_KNN build k-nearest neighbors for all pixels of input texture T
%
% [index, distance] = build_knn(T,ov,k,retain,mode)
%
% NOTE: this function requires openTSTool's nn_search and nn_prepare, both
% avilable under the GPL from http://www.physik3.gwdg.de/tstool/
% where detailed installation instructions are available
%
% input:
% T - the input texture of size RxC=N (boundaries wrap in 2D)
% ov - the pixel overlap (the nxn neighborhood for feature vector
% construction with n = 2*ov + 1)
% k - number of nearest neighbors to search for (and return)
% retain - amount of variance to retain during PCA (in %) (optional)
% mode - set to 1 for grayscale reduction (optional)
%
% output:
% index - an (Nxk) sized matrix with the k-nearest neighbor indices
% for each sample in SCANLINE (row major) order
% distance - an (Nxk) sized matrix with the corresponding euclidian
% distances
%
% NOTE: the result is a flattened version of the input 2D matrix with
% SCANLINE ordering. to get the vector of (flat) nearest neighbor
% indices at pixel p = f(r,c) we access 'index(p, :)' with
%
% p = f(r,c) = (r-1)*C+c
%
% with C = 'num cols in T'.
% these indices are flattened, so to get the actual (r,c) index
% of the flattened index p we compute
%
% r = floor((p-1)/C) + 1, and
% c = p - (r-1)*C
%
% with r = row index and c = col index
% these transforms are commonly used in hybridsynthesize.m related code
%
T = im2double(T); % gives us values in [0,1]
% default to retain 97% of the variance during PCA
pca_retain = 97;
if (exist('retain')),
pca_retain = retain;
end
% default to RGB mode, set to grayscale on user request
if (exist('mode') & mode == 1),
if (size(T,3) > 1),
T = rgb2gray(T);
end
end
% color dimension of input image
col_dim = size(T,3);
col_dim_minus_one = col_dim-1;
% build the input to nn_prepare and nn_search
R = size(T,1); C = size(T,2); % num rows (R) and cols (C) in T
N = R * C; % number of points in search space (N)
nbhd = 2*ov+1; % quadratic nbhd size
D = (nbhd^2) * col_dim; % dimensionality (D) of each search vector
pointset = zeros(N, D); % vector of length D for each pixel position 1...N
% ----------------------------------------------------------
% build pointset from T as input to nn_prepare and nn_search
% ----------------------------------------------------------
% shift it circulary, so entire nbhd is in upper left. also, the index of
% the center pixel will always be held at (b_ind,b_ind), and we circularly
% shift T in each step (in scanline order)
T = circshift(T,[ov ov]);
center_ind = 1+ov;
disp(strcat('building set of N=', num2str(N), ...
', feature vectors with dimension D=', num2str(D)));
tic
% iterate over all pixels in T in scanline order.
% construct feature vectors ('pointset').
point_index = 0;
for r=1:R,
for c=1:C,
% current point index. row major (scanline order). runs from 1...N
% point_index = (r-1)*C+c;
point_index = point_index + 1;
% for each vector V(point_index), flatten nbhd around current pixel
pointset(point_index,1:D) = reshape(T(1:nbhd,1:nbhd,1:col_dim),1,D);
% end of this column, circshift one column to the left, so current pixel evaluated
% is one pixel to the right of previous evaluated pixel
T = circshift(T,[0 -1]);
end
% end of this row, circshift one row up, so current row evaluated
% is one pixel below the previous row evaluated
T = circshift(T,[-1 0]);
end
toc
tic
% ----------------------------------------------------------
% perform PCA on pointset to reduce dimensionality
% comment this out if you 'really' want to work without PCA
% warning: no PCA = SLOW!
% ----------------------------------------------------------
disp('reducing feature vector dimensionality by PCA');
% retain 97% of the original variance as proposed by liang et al. in
% 'real time texture synthesis by patch based sampling' paper.
[rlvm,frvals,frvecs,pointset] = pca(pointset,'normalized',pca_retain,1);
% ----------------------------------------------------------
% prepare and search in pointset
% ----------------------------------------------------------
disp('preparing set of feature vectors for knn search');
% prepare pointset
atria = nn_prepare(pointset);
disp(strcat('computing knn with k=', num2str(k),', num feature vectors N=', num2str(N),...
', with dimension D=', num2str(D), ', reduced to D_pca=', num2str(size(pointset,2))));
% compute (exact) k-nearest neighbors
% the fifth paramtere to nn_search defines the accuracy of the search (0 = exact)
% see documentation accompanying nn_search in openTSTools to tweak this
[index,distance] = nn_search(pointset, atria, [1:N], k, 0);
disp('done');
toc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -