[docs]defnormalize(inpt:torch.Tensor,mean:List[float],std:List[float],inplace:bool=False,)->torch.Tensor:"""[BETA] See :class:`~torchvision.transforms.v2.Normalize` for details."""iftorch.jit.is_scripting():returnnormalize_image(inpt,mean=mean,std=std,inplace=inplace)_log_api_usage_once(normalize)kernel=_get_kernel(normalize,type(inpt))returnkernel(inpt,mean=mean,std=std,inplace=inplace)
@_register_kernel_internal(normalize,torch.Tensor)@_register_kernel_internal(normalize,tv_tensors.Image)defnormalize_image(image:torch.Tensor,mean:List[float],std:List[float],inplace:bool=False)->torch.Tensor:ifnotimage.is_floating_point():raiseTypeError(f"Input tensor should be a float tensor. Got {image.dtype}.")ifimage.ndim<3:raiseValueError(f"Expected tensor to be a tensor image of size (..., C, H, W). Got {image.shape}.")ifisinstance(std,(tuple,list)):divzero=notall(std)elifisinstance(std,(int,float)):divzero=std==0else:divzero=Falseifdivzero:raiseValueError("std evaluated to zero, leading to division by zero.")dtype=image.dtypedevice=image.devicemean=torch.as_tensor(mean,dtype=dtype,device=device)std=torch.as_tensor(std,dtype=dtype,device=device)ifmean.ndim==1:mean=mean.view(-1,1,1)ifstd.ndim==1:std=std.view(-1,1,1)ifinplace:image=image.sub_(mean)else:image=image.sub(mean)returnimage.div_(std)@_register_kernel_internal(normalize,tv_tensors.Video)defnormalize_video(video:torch.Tensor,mean:List[float],std:List[float],inplace:bool=False)->torch.Tensor:returnnormalize_image(video,mean,std,inplace=inplace)
[docs]defgaussian_blur(inpt:torch.Tensor,kernel_size:List[int],sigma:Optional[List[float]]=None)->torch.Tensor:"""[BETA] See :class:`~torchvision.transforms.v2.GaussianBlur` for details."""iftorch.jit.is_scripting():returngaussian_blur_image(inpt,kernel_size=kernel_size,sigma=sigma)_log_api_usage_once(gaussian_blur)kernel=_get_kernel(gaussian_blur,type(inpt))returnkernel(inpt,kernel_size=kernel_size,sigma=sigma)
def_get_gaussian_kernel1d(kernel_size:int,sigma:float,dtype:torch.dtype,device:torch.device)->torch.Tensor:lim=(kernel_size-1)/(2.0*math.sqrt(2.0)*sigma)x=torch.linspace(-lim,lim,steps=kernel_size,dtype=dtype,device=device)kernel1d=torch.softmax(x.pow_(2).neg_(),dim=0)returnkernel1ddef_get_gaussian_kernel2d(kernel_size:List[int],sigma:List[float],dtype:torch.dtype,device:torch.device)->torch.Tensor:kernel1d_x=_get_gaussian_kernel1d(kernel_size[0],sigma[0],dtype,device)kernel1d_y=_get_gaussian_kernel1d(kernel_size[1],sigma[1],dtype,device)kernel2d=kernel1d_y.unsqueeze(-1)*kernel1d_xreturnkernel2d@_register_kernel_internal(gaussian_blur,torch.Tensor)@_register_kernel_internal(gaussian_blur,tv_tensors.Image)defgaussian_blur_image(image:torch.Tensor,kernel_size:List[int],sigma:Optional[List[float]]=None)->torch.Tensor:# TODO: consider deprecating integers from sigma on the futureifisinstance(kernel_size,int):kernel_size=[kernel_size,kernel_size]eliflen(kernel_size)!=2:raiseValueError(f"If kernel_size is a sequence its length should be 2. Got {len(kernel_size)}")forksizeinkernel_size:ifksize%2==0orksize<0:raiseValueError(f"kernel_size should have odd and positive integers. Got {kernel_size}")ifsigmaisNone:sigma=[ksize*0.15+0.35forksizeinkernel_size]else:ifisinstance(sigma,(list,tuple)):length=len(sigma)iflength==1:s=float(sigma[0])sigma=[s,s]eliflength!=2:raiseValueError(f"If sigma is a sequence, its length should be 2. Got {length}")elifisinstance(sigma,(int,float)):s=float(sigma)sigma=[s,s]else:raiseTypeError(f"sigma should be either float or sequence of floats. Got {type(sigma)}")forsinsigma:ifs<=0.0:raiseValueError(f"sigma should have positive values. Got {sigma}")ifimage.numel()==0:returnimagedtype=image.dtypeshape=image.shapendim=image.ndimifndim==3:image=image.unsqueeze(dim=0)elifndim>4:image=image.reshape((-1,)+shape[-3:])fp=torch.is_floating_point(image)kernel=_get_gaussian_kernel2d(kernel_size,sigma,dtype=dtypeiffpelsetorch.float32,device=image.device)kernel=kernel.expand(shape[-3],1,kernel.shape[0],kernel.shape[1])output=imageiffpelseimage.to(dtype=torch.float32)# padding = (left, right, top, bottom)padding=[kernel_size[0]//2,kernel_size[0]//2,kernel_size[1]//2,kernel_size[1]//2]output=torch_pad(output,padding,mode="reflect")output=conv2d(output,kernel,groups=shape[-3])ifndim==3:output=output.squeeze(dim=0)elifndim>4:output=output.reshape(shape)ifnotfp:output=output.round_().to(dtype=dtype)returnoutput@_register_kernel_internal(gaussian_blur,PIL.Image.Image)def_gaussian_blur_image_pil(image:PIL.Image.Image,kernel_size:List[int],sigma:Optional[List[float]]=None)->PIL.Image.Image:t_img=pil_to_tensor(image)output=gaussian_blur_image(t_img,kernel_size=kernel_size,sigma=sigma)returnto_pil_image(output,mode=image.mode)@_register_kernel_internal(gaussian_blur,tv_tensors.Video)defgaussian_blur_video(video:torch.Tensor,kernel_size:List[int],sigma:Optional[List[float]]=None)->torch.Tensor:returngaussian_blur_image(video,kernel_size,sigma)
[docs]defto_dtype(inpt:torch.Tensor,dtype:torch.dtype=torch.float,scale:bool=False)->torch.Tensor:"""[BETA] See :func:`~torchvision.transforms.v2.ToDtype` for details."""iftorch.jit.is_scripting():returnto_dtype_image(inpt,dtype=dtype,scale=scale)_log_api_usage_once(to_dtype)kernel=_get_kernel(to_dtype,type(inpt))returnkernel(inpt,dtype=dtype,scale=scale)
def_num_value_bits(dtype:torch.dtype)->int:ifdtype==torch.uint8:return8elifdtype==torch.int8:return7elifdtype==torch.int16:return15elifdtype==torch.int32:return31elifdtype==torch.int64:return63else:raiseTypeError(f"Number of value bits is only defined for integer dtypes, but got {dtype}.")@_register_kernel_internal(to_dtype,torch.Tensor)@_register_kernel_internal(to_dtype,tv_tensors.Image)defto_dtype_image(image:torch.Tensor,dtype:torch.dtype=torch.float,scale:bool=False)->torch.Tensor:ifimage.dtype==dtype:returnimageelifnotscale:returnimage.to(dtype)float_input=image.is_floating_point()iftorch.jit.is_scripting():# TODO: remove this branch as soon as `dtype.is_floating_point` is supported by JITfloat_output=torch.tensor(0,dtype=dtype).is_floating_point()else:float_output=dtype.is_floating_pointiffloat_input:# float to floatiffloat_output:returnimage.to(dtype)# float to intif(image.dtype==torch.float32anddtypein(torch.int32,torch.int64))or(image.dtype==torch.float64anddtype==torch.int64):raiseRuntimeError(f"The conversion from {image.dtype} to {dtype} cannot be performed safely.")# For data in the range `[0.0, 1.0]`, just multiplying by the maximum value of the integer range and converting# to the integer dtype is not sufficient. For example, `torch.rand(...).mul(255).to(torch.uint8)` will only# be `255` if the input is exactly `1.0`. See https://github.com/pytorch/vision/pull/2078#issuecomment-612045321# for a detailed analysis.# To mitigate this, we could round before we convert to the integer dtype, but this is an extra operation.# Instead, we can also multiply by the maximum value plus something close to `1`. See# https://github.com/pytorch/vision/pull/2078#issuecomment-613524965 for details.eps=1e-3max_value=float(_max_value(dtype))# We need to scale first since the conversion would otherwise turn the input range `[0.0, 1.0]` into the# discrete set `{0, 1}`.returnimage.mul(max_value+1.0-eps).to(dtype)else:# int to floatiffloat_output:returnimage.to(dtype).mul_(1.0/_max_value(image.dtype))# int to intnum_value_bits_input=_num_value_bits(image.dtype)num_value_bits_output=_num_value_bits(dtype)ifnum_value_bits_input>num_value_bits_output:returnimage.bitwise_right_shift(num_value_bits_input-num_value_bits_output).to(dtype)else:returnimage.to(dtype).bitwise_left_shift_(num_value_bits_output-num_value_bits_input)# We encourage users to use to_dtype() instead but we keep this for BC
[docs]defconvert_image_dtype(image:torch.Tensor,dtype:torch.dtype=torch.float32)->torch.Tensor:"""[BETA] [DEPRECATED] Use to_dtype() instead."""returnto_dtype_image(image,dtype=dtype,scale=True)
@_register_kernel_internal(to_dtype,tv_tensors.Video)defto_dtype_video(video:torch.Tensor,dtype:torch.dtype=torch.float,scale:bool=False)->torch.Tensor:returnto_dtype_image(video,dtype,scale=scale)@_register_kernel_internal(to_dtype,tv_tensors.BoundingBoxes,tv_tensor_wrapper=False)@_register_kernel_internal(to_dtype,tv_tensors.Mask,tv_tensor_wrapper=False)def_to_dtype_tensor_dispatch(inpt:torch.Tensor,dtype:torch.dtype,scale:bool=False)->torch.Tensor:# We don't need to unwrap and rewrap here, since TVTensor.to() preserves the typereturninpt.to(dtype)
Docs
Access comprehensive developer documentation for PyTorch
To analyze traffic and optimize your experience, we serve cookies on this site. By clicking or navigating, you agree to allow our usage of cookies. As the current maintainers of this site, Facebook’s Cookies Policy applies. Learn more, including about available controls: Cookies Policy.