Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/torch/image.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoumith Chintala <soumith@gmail.com>2016-08-25 17:43:24 +0300
committerGitHub <noreply@github.com>2016-08-25 17:43:24 +0300
commita7af1af68cb76b48d398329164d22fcb799ed3b6 (patch)
tree01d46100ca01c0e03b77ebb888e2d83f352f6254
parent797fcb101b76c9b329b3ee83349b0f6adeacac94 (diff)
parent49fa1e57bfb355ef9c23745eb7f010dbd8d3ff8a (diff)
Merge pull request #185 from qureai/master
Added affinetransform
-rw-r--r--doc/paramtransform.md16
-rw-r--r--init.lua121
2 files changed, 137 insertions, 0 deletions
diff --git a/doc/paramtransform.md b/doc/paramtransform.md
index 839c754..a160a34 100644
--- a/doc/paramtransform.md
+++ b/doc/paramtransform.md
@@ -19,6 +19,22 @@ When `clamp_mode` equals `pad`, the user can specify the padding value with `pad
If `dst` is specified, it is used to store the result of the warp.
Otherwise, returns a new `res` Tensor.
+<a name="image.affinetransform"></a>
+### [res] image.affinetransform([dst,]src,matrix,[mode,translation,clamp_mode,pad_val]) ###
+Warps image `src` (of size`KxHxW`)
+according to `(y,x)` affine transformation defined by `matrix`.
+The latter has size `2x2`. String `mode` can
+take on values [lanczos](https://en.wikipedia.org/wiki/Lanczos_resampling),
+[bicubic](https://en.wikipedia.org/wiki/Bicubic_interpolation),
+[bilinear](https://en.wikipedia.org/wiki/Bilinear_interpolation) (the default),
+or *simple*.
+Additional translation can be added to the image before affine transformation with `translation`.( Default is `torch.Tensor{0, 0}`.)
+The `clamp_mode` variable specifies how to handle the interpolation of samples off the input image.
+Permitted values are strings *clamp* (the default) or *pad*.
+When `clamp_mode` equals `pad`, the user can specify the padding value with `pad_val` (default = 0). Note: setting this value when `clamp_mode` equals `clamp` will result in an error.
+If `dst` is specified, it is used to store the result of the warp.
+Otherwise, returns a new `res` Tensor.
+
<a name="image.convolve"></a>
### [res] image.convolve([dst,] src, kernel, [mode]) ###
Convolves Tensor `kernel` over image `src`. Valid string values for argument
diff --git a/init.lua b/init.lua
index 5f4b9ed..7f15fd5 100644
--- a/init.lua
+++ b/init.lua
@@ -969,6 +969,127 @@ end
rawset(image, 'warp', warp)
----------------------------------------------------------------------
+-- affine transform
+--
+local function affinetransform(...)
+ local dst,src,matrix
+ local mode = 'bilinear'
+ local translation = torch.Tensor{0,0}
+ local clamp_mode = 'clamp'
+ local pad_value = 0
+ local args = {...}
+ local nargs = select('#',...)
+ local bad_args = false
+ if nargs == 2 then
+ src = args[1]
+ matrix = args[2]
+ elseif nargs >= 3 then
+ if type(args[3]) == 'string' then
+ -- No destination tensor
+ src = args[1]
+ matrix = args[2]
+ mode = args[3]
+ if nargs >= 4 then translation = args[4] end
+ if nargs >= 5 then clamp_mode = args[5] end
+ if nargs >= 6 then
+ assert(clamp_mode == 'pad', 'pad_value can only be specified if' ..
+ ' clamp_mode = "pad"')
+ pad_value = args[6]
+ end
+ if nargs >= 7 then bad_args = true end
+ else
+ -- With Destination tensor
+ dst = args[1]
+ src = args[2]
+ matrix = args[3]
+ if nargs >= 4 then mode = args[4] end
+ if nargs >= 5 then translation = args[5] end
+ if nargs >= 6 then clamp_mode = args[6] end
+ if nargs >= 7 then
+ assert(clamp_mode == 'pad', 'pad_value can only be specified if' ..
+ ' clamp_mode = "pad"')
+ pad_value = args[7]
+ end
+ if nargs >= 8 then bad_args = true end
+ end
+ end
+ if bad_args then
+ print(dok.usage('image.warp',
+ 'warp an image, according to given affine transform', nil,
+ {type='torch.Tensor', help='input image (KxHxW)', req=true},
+ {type='torch.Tensor', help='(y,x) affine translation matrix', req=true},
+ {type='string', help='mode: lanczos | bicubic | bilinear | simple', default='bilinear'},
+ {type='torch.Tensor', help='extra (y,x) translation to be done before transform', default=torch.Tensor{0,0}},
+ {type='string', help='clamp mode: how to handle interp of samples off the input image (clamp | pad)', default='clamp'},
+ '',
+ {type='torch.Tensor', help='input image (KxHxW)', req=true},
+ {type='torch.Tensor', help='(y,x) affine translation matrix', req=true},
+ {type='string', help='mode: lanczos | bicubic | bilinear | simple', default='bilinear'},
+ {type='torch.Tensor', help='extra (y,x) translation to be done before transform', default=torch.Tensor{0,0}},
+ {type='string', help='clamp mode: how to handle interp of samples off the input image (clamp | pad)', default='clamp'},
+ {type='number', help='pad value: value to pad image. Can only be set when clamp mode equals "pad"', default=0}))
+ dok.error('incorrect arguments', 'image.warp')
+ end
+ -- This is a little messy, but convert mode string to an enum
+ if (mode == 'simple') then
+ mode = 0
+ elseif (mode == 'bilinear') then
+ mode = 1
+ elseif (mode == 'bicubic') then
+ mode = 2
+ elseif (mode == 'lanczos') then
+ mode = 3
+ else
+ dok.error('Incorrect arguments (mode is not lanczos | bicubic | bilinear | simple)!', 'image.warp')
+ end
+ if (clamp_mode == 'clamp') then
+ clamp_mode = 0
+ elseif (clamp_mode == 'pad') then
+ clamp_mode = 1
+ else
+ dok.error('Incorrect arguments (clamp_mode is not clamp | pad)!', 'image.warp')
+ end
+
+ local dim2 = false
+ if src:nDimension() == 2 then
+ dim2 = true
+ src = src:reshape(1,src:size(1),src:size(2))
+ end
+ dst = dst or src.new()
+ dst:resize(src:size(1), src:size(2), src:size(3))
+
+ -- create field
+ local height = src:size(2)
+ local width = src:size(3)
+
+ local grid_y = torch.ger( torch.linspace(-1,1,height), torch.ones(width) )
+ local grid_x = torch.ger( torch.ones(height), torch.linspace(-1,1,width) )
+
+ local grid_xy = torch.FloatTensor()
+ grid_xy:resize(2,height,width)
+ grid_xy[1] = grid_y * ((height-1)/2) * -1
+ grid_xy[2] = grid_x * ((width-1)/2) * -1
+ local view_xy = grid_xy:reshape(2,height*width)
+
+ local field = torch.mm(matrix, view_xy)
+ field = (grid_xy - field:reshape( 2, height, width )):double()
+
+ -- offset field for translation
+ translation = torch.Tensor(translation)
+ field[1] = field[1] - translation[1]
+ field[2] = field[2] - translation[2]
+
+
+ local offset_mode = true
+ src.image.warp(dst, src, field, mode, offset_mode, clamp_mode, pad_value)
+ if dim2 then
+ dst = dst[1]
+ end
+ return dst
+end
+rawset(image, 'affinetransform', affinetransform)
+
+----------------------------------------------------------------------
-- hflip
--
local function hflip(...)