class TorchVision::Transforms::F
Public Class Methods
center_crop(img, output_size)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 121 def center_crop(img, output_size) if output_size.is_a?(Integer) output_size = [output_size.to_i, output_size.to_i] elsif output_size.is_a?(Array) && output_size.length == 1 output_size = [output_size[0], output_size[0]] end image_width, image_height = image_size(img) crop_height, crop_width = output_size if crop_width > image_width || crop_height > image_height padding_ltrb = [ crop_width > image_width ? (crop_width - image_width).div(2) : 0, crop_height > image_height ? (crop_height - image_height).div(2) : 0, crop_width > image_width ? (crop_width - image_width + 1).div(2) : 0, crop_height > image_height ? (crop_height - image_height + 1).div(2) : 0 ] # TODO img = pad(img, padding_ltrb, fill: 0) image_width, image_height = image_size(img) if crop_width == image_width && crop_height == image_height return img end end crop_top = ((image_height - crop_height) / 2.0).round crop_left = ((image_width - crop_width) / 2.0).round crop(img, crop_top, crop_left, crop_height, crop_width) end
crop(img, top, left, height, width)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 111 def crop(img, top, left, height, width) if img.is_a?(Torch::Tensor) assert_image_tensor(img) indexes = [true] * (img.dim - 2) img[*indexes, top...(top + height), left...(left + width)] else img.crop(left, top, width, height) end end
hflip(img)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 93 def hflip(img) if img.is_a?(Torch::Tensor) assert_image_tensor(img) img.flip(-1) else img.flip(:horizontal) end end
normalize(tensor, mean, std, inplace: false)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 5 def normalize(tensor, mean, std, inplace: false) unless Torch.tensor?(tensor) raise ArgumentError, "tensor should be a torch tensor. Got #{tensor.class.name}" end if tensor.ndimension != 3 raise ArgumentError, "Expected tensor to be a tensor image of size (C, H, W). Got tensor.size() = #{tensor.size}" end tensor = tensor.clone unless inplace dtype = tensor.dtype # TODO Torch.as_tensor mean = Torch.tensor(mean, dtype: dtype, device: tensor.device) std = Torch.tensor(std, dtype: dtype, device: tensor.device) # TODO if std.to_a.any? { |v| v == 0 } raise ArgumentError, "std evaluated to zero after conversion to #{dtype}, leading to division by zero." end if mean.ndim == 1 mean = mean[0...mean.size(0), nil, nil] end if std.ndim == 1 std = std[0...std.size(0), nil, nil] end tensor.sub!(mean).div!(std) tensor end
resize(img, size)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 35 def resize(img, size) raise "img should be Vips::Image. Got #{img.class.name}" unless img.is_a?(Vips::Image) if size.is_a?(Integer) w, h = img.size if (w <= h && w == size) || (h <= w && h == size) return img end if w < h ow = size oh = (size * h / w).to_i img.thumbnail_image(ow, height: oh) else oh = size ow = (size * w / h).to_i img.thumbnail_image(ow, height: oh) end else img.thumbnail_image(size[0], height: size[1], size: :force) end end
resized_crop(img, top, left, height, width, size)
click to toggle source
TODO interpolation
# File lib/torchvision/transforms/functional.rb, line 152 def resized_crop(img, top, left, height, width, size) img = crop(img, top, left, height, width) img = resize(img, size) #, interpolation) img end
to_tensor(pic)
click to toggle source
TODO improve
# File lib/torchvision/transforms/functional.rb, line 58 def to_tensor(pic) if !pic.is_a?(Numo::NArray) && !pic.is_a?(Vips::Image) raise ArgumentError, "pic should be Vips::Image or Numo::NArray. Got #{pic.class.name}" end if pic.is_a?(Numo::NArray) && ![2, 3].include?(pic.ndim) raise ArgumentError, "pic should be 2/3 dimensional. Got #{pic.dim} dimensions." end if pic.is_a?(Numo::NArray) if pic.ndim == 2 pic = pic.reshape(*pic.shape, 1) end img = Torch.from_numo(pic.transpose(2, 0, 1)) if img.dtype == :uint8 return img.float.div(255) else return img end end case pic.format when :uchar img = Torch::ByteTensor.new(Torch::ByteStorage.from_buffer(pic.write_to_memory)) else raise Error, "Format not supported yet: #{pic.format}" end img = img.view(pic.height, pic.width, pic.bands) # put it from HWC to CHW format img = img.permute([2, 0, 1]).contiguous img.float.div(255) end
vflip(img)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 102 def vflip(img) if img.is_a?(Torch::Tensor) assert_image_tensor(img) img.flip(-2) else img.flip(:vertical) end end
Private Class Methods
assert_image_tensor(img)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 169 def assert_image_tensor(img) if img.ndim < 2 raise TypeError, "Tensor is not a torch image." end end
image_size(img)
click to toggle source
# File lib/torchvision/transforms/functional.rb, line 160 def image_size(img) if img.is_a?(Torch::Tensor) assert_image_tensor(img) [img.shape[-1], img.shape[-2]] else [img.width, img.height] end end