-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7b049da
Showing
5 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Feature Extractor Library for Torch7 | ||
!!! This is not complete yet !!! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
fex = fex or {} | ||
local function stdnormalpdf(pdf) | ||
pdf:cmul(pdf) | ||
pdf:div(-2) | ||
pdf:exp() | ||
pdf:mul(1/math.sqrt(2*math.pi)) | ||
return pdf | ||
end | ||
|
||
function fex.normpdf(x,mean,std) | ||
mean = mean or 0 | ||
std = std or 1 | ||
local pdf = x:clone() | ||
pdf:add(-mean) | ||
pdf:div(std) | ||
pdf = stdnormalpdf(pdf) | ||
pdf:div(std) | ||
return pdf | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
local fex = {} | ||
|
||
torch.include('fex','dist.lua') | ||
torch.include('fex','sift.lua') | ||
torch.include('fex','hog.lua') | ||
torch.include('fex','utils.lua') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
|
||
function gendgauss(sigma) | ||
|
||
--Laplacian of size sigma | ||
local f_wid = 4 * math.floor(sigma); | ||
local G = fex.normpdf(torch.range(-f_wid,f_wid),0,sigma); | ||
G = torch.ger(G,G) | ||
GX,GY = fex.gradient(G); | ||
|
||
GX:div(torch.sum(torch.abs(GX))):mul(2) | ||
GY:div(torch.sum(torch.abs(GY))):mul(2) | ||
return GX, GY | ||
end | ||
|
||
function fex.dsift(im, grid_spacing, patch_size) | ||
local I | ||
if im:dim() == 3 then | ||
I = torch.sum(im,1)/3 | ||
I = I[1] | ||
elseif im:dim() == 2 then | ||
I = im | ||
else | ||
error('im has to be 2D or 3D') | ||
end | ||
|
||
patch_size = patch_size or 16 | ||
grid_spacing = grid_spacing or patch_size/2 | ||
|
||
local num_angles = 8 | ||
local num_bins = 4 | ||
local num_samples = num_bins * num_bins | ||
|
||
local alpha = 9 | ||
local sigma_edge = 1 | ||
|
||
local angle_step = 2 * math.pi / num_angles | ||
local angles = torch.range(0,2*math.pi,angle_step) | ||
angles = angles:narrow(1,1,num_angles):clone() | ||
|
||
local hgt = I:size(1) | ||
local wid = I:size(2) | ||
|
||
local G_X,G_Y = gendgauss(sigma_edge) | ||
|
||
I:add(-torch.mean(I)) | ||
local I_X = fex.xcorr2(I, G_X, 'S') | ||
local I_Y = fex.xcorr2(I, G_Y, 'S') | ||
|
||
local I_mag = torch.sqrt(torch.pow(I_X,2) + torch.pow(I_Y,2)) | ||
local I_theta = torch.atan(torch.cdiv(I_Y,I_X)) | ||
I_theta[torch.ne(I_theta,I_theta)]=0 | ||
|
||
local grid_x = torch.range(patch_size/2,wid-patch_size/2,grid_spacing) | ||
local grid_y = torch.range(patch_size/2,hgt-patch_size/2,grid_spacing) | ||
|
||
local I_orientation = torch.zeros(num_angles, hgt, wid) | ||
|
||
local cosI = torch.cos(I_theta) | ||
local sinI = torch.sin(I_theta) | ||
|
||
for a=1,num_angles do | ||
local tmp = cosI*math.cos(angles[a]) + sinI*math.sin(angles[a]) | ||
tmp:pow(alpha) | ||
tmp[torch.le(tmp,0)] = 0 | ||
torch.cmul(I_orientation[a], tmp, I_mag) | ||
end | ||
|
||
local weight_kernel = torch.zeros(patch_size,patch_size) | ||
local r = patch_size/2; | ||
local cx = r-0.5; | ||
local sample_res = patch_size/num_bins; | ||
local weight_x = torch.abs(torch.range(1,patch_size)-cx)/sample_res | ||
weight_x:apply(function(x) if x <= 1 then return 1-x else return x end end) | ||
local tw = torch.ger(weight_x, weight_x) | ||
|
||
for a=1,num_angles do | ||
I_orientation[a]:copy(fex.conv2(I_orientation[a],tw,'S')) | ||
end | ||
return I_orientation | ||
end | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
function fex.conv2(...) | ||
local arg = {...} | ||
if arg[#arg] == 'S' then | ||
local ro,x,k = nil,nil,nil | ||
if #arg == 4 then | ||
ro = arg[1] | ||
x = arg[2] | ||
k = arg[3] | ||
else | ||
x = arg[1] | ||
k = arg[2] | ||
ro = x.new(x:size()) | ||
end | ||
local r = torch.conv2(x,k,'F') | ||
local shifti = math.floor((r:size(1)-x:size(1))/2) | ||
local shiftj = math.floor((r:size(2)-x:size(2))/2) | ||
local ii = r:dim()-1 | ||
local jj = r:dim() | ||
ro:resizeAs(x) | ||
ro:copy(r:narrow(ii,shifti,x:size(1)):narrow(jj,shiftj,x:size(2))) | ||
return ro | ||
else | ||
return torch.conv2(...) | ||
end | ||
end | ||
function fex.xcorr2(...) | ||
local arg = {...} | ||
if arg[#arg] == 'S' then | ||
local ro,x,k = nil,nil,nil | ||
if #arg == 4 then | ||
ro = arg[1] | ||
x = arg[2] | ||
k = arg[3] | ||
else | ||
x = arg[1] | ||
k = arg[2] | ||
ro = x.new(x:size()) | ||
end | ||
local r = torch.xcorr2(x,k,'F') | ||
local shifti = math.floor((r:size(1)-x:size(1))/2) | ||
local shiftj = math.floor((r:size(2)-x:size(2))/2) | ||
local ii = r:dim()-1 | ||
local jj = r:dim() | ||
ro:resizeAs(x) | ||
ro:copy(r:narrow(ii,shifti,x:size(1)):narrow(jj,shiftj,x:size(2))) | ||
return ro | ||
else | ||
return torch.xcorr2(...) | ||
end | ||
end | ||
|
||
function fex.gradient(x,dim) | ||
|
||
if not dim then dim = torch.range(0,x:dim()):narrow(1,2,x:dim()) end | ||
if type(dim) == 'number' then dim = torch.Tensor({dim}) end | ||
local ndim = x:dim() | ||
|
||
local function grad(x,dim) | ||
local sz = x:size() | ||
if sz[dim] == 1 then return x:clone():zero() end | ||
sz[dim] = sz[dim]+2 | ||
local xx = x.new(sz):zero() | ||
-- copy center | ||
xx:narrow(dim,2,x:size(dim)):copy(x) | ||
-- extrapolate the beginning | ||
local ff = xx:narrow(dim,1,1) | ||
local f1 = xx:narrow(dim,2,1) | ||
local f2 = xx:narrow(dim,3,1) | ||
torch.add(ff,f1,-1,f2) | ||
ff:add(f1) | ||
-- extrapolate the ending | ||
local xend = xx:size(dim) | ||
local fe = xx:narrow(dim,xend,1) | ||
local ff1 = xx:narrow(dim,xend-1,1) | ||
local ff2 = xx:narrow(dim,xend-2,1) | ||
torch.add(fe,ff1,-1,ff2) | ||
fe:add(ff1) | ||
-- now subtract | ||
local d = xx:narrow(dim,3,xend-2):clone() | ||
d:add(-1,xx:narrow(dim,1,xend-2)) | ||
return d:div(2) | ||
end | ||
|
||
local res = {} | ||
for i=1,ndim do | ||
table.insert(res,i,grad(x,ndim-i+1)) | ||
end | ||
return unpack(res) | ||
end | ||
|
||
local function dimnarrow(x,sz,pad,dim) | ||
local xn = x | ||
for i=1,x:dim() do | ||
if i > dim then | ||
xn = xn:narrow(i,pad[i]+1,sz[i]) | ||
end | ||
end | ||
return xn | ||
end | ||
local function padzero(x,pad) | ||
local sz = x:size() | ||
for i=1,x:dim() do sz[i] = sz[i]+pad[i]*2 end | ||
local xx = x.new(sz):zero() | ||
local xn = dimnarrow(xx,x:size(),pad,-1) | ||
xn:copy(x) | ||
return xx | ||
end | ||
local function padmirror(x,pad) | ||
local xx = padzero(x,pad) | ||
local sz = xx:size() | ||
for i=1,x:dim() do | ||
local xxn = dimnarrow(xx,x:size(),pad,i) | ||
for j=1,pad[i] do | ||
xxn:select(i,j):copy(xxn:select(i,pad[i]*2-j+1)) | ||
xxn:select(i,sz[i]-j+1):copy(xxn:select(i,sz[i]-pad[i]*2+j)) | ||
end | ||
end | ||
return xx | ||
end | ||
function fex.padarray(x,pad,padtype) | ||
if x:dim() ~= #pad then | ||
error('number of dimensions of Input should match number of padding sizes') | ||
end | ||
if padtype == 'zero' then return padzero(x,pad) end | ||
if padtype == 'mirror' then return padmirror(x,pad) end | ||
error('unknown paddtype ' .. padtype) | ||
end | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|