在学习中,碰到FCN的部分源码,对这部分做一个集中的学习

代码如下: 

class SegmentationPresetTrain:  #训练过程中图像预处理方法
    def __init__(self, base_size, crop_size, hflip_prob=0.5, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):
        min_size = int(0.5 * base_size)  #520*0.5=260
        max_size = int(2.0 * base_size)  #520*2=1024

        trans = [T.RandomResize(min_size, max_size)]  #随机选取数值
        if hflip_prob > 0:  #随机水平翻转大于0
            trans.append(T.RandomHorizontalFlip(hflip_prob)) #水平翻转
        trans.extend([
            T.RandomCrop(crop_size), #随机裁剪
            T.ToTensor(),
            T.Normalize(mean=mean, std=std),#标准化
        ])
        self.transforms = T.Compose(trans)  #将预处理方法进行打包

    def __call__(self, img, target):  #transforms方法是在call中被调用的
        return self.transforms(img, target)

def get_transform(train):  #train为true的话
    base_size = 520
    crop_size = 480

    return SegmentationPresetTrain(base_size, crop_size) if train else SegmentationPresetEval(base_size)#后者是验证集的图片大小

当train为true时,调用SegmentationPresetTrain(base_size, crop_size),并且传参

base_size = 520
crop_size = 480


__call__方法中引用

self.transforms(img, target)

 __init__方法

  • RandomResize(min_size, max_size):将img,target缩放为随机尺寸大小

class RandomResize(object): #随机裁剪
    def __init__(self, min_size, max_size=None):
        self.min_size = min_size
        if max_size is None:
            max_size = min_size  #如果max_size没有传入值,则默认将min_size传入进来
        self.max_size = max_size

    def __call__(self, image, target):
        size = random.randint(self.min_size, self.max_size)  #随机选择一个整数,随机长宽比裁剪原始图片,最后将图片resize到设定好的size

        # 这里size传入的是int类型,所以是将图像的最小边长缩放到size大小
        image = F.resize(image, size)

        # 这里的interpolation注意下,在torchvision(0.9.0)以后才有InterpolationMode.NEAREST
        # 如果是之前的版本需要使用PIL.Image.NEAREST
        target = F.resize(target, size, interpolation=T.InterpolationMode.NEAREST)

        return image, target
  • 水平翻转transforms.RandomHorizontalFlip

class torchvision.transforms.RandomHorizontalFlip(p=0.5)
功能:依据概率p对PIL图片进行水平翻转,水平翻转是左右翻转。180°
参数:
p- 概率,默认值为0.5

  • Python List append()方法

append() 方法用于在列表末尾添加新的对象

语法:

list.append(obj)  #obj -- 添加到列表末尾的对象

该方法无返回值,但是会修改原来的列表

示例:

aList = [123, 'xyz', 'zara', 'abc']
aList.append( 2009 )

print("Updated List : ", aList)
#Updated List :  [123, 'xyz', 'zara', 'abc', 2009]
  •  Python List extend()方法

extend() 函数用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)。 

语法:

list.extend(seq)    #seq -- 元素列表

 该方法没有返回值,但会在已存在的列表中添加新的列表内容。

示例:

aList = [123, 'xyz', 'zara', 'abc', 123];
bList = [2009, 'manni'];
aList.extend(bList)

print("Extended List : ", aList)
#Extended List :  [123, 'xyz', 'zara', 'abc', 123, 2009, 'manni']

原文中的代码: 

def append(self, *args, **kwargs): # real signature unknown
    """ Append object to the end of the list. """
    pass
def extend(self, *args, **kwargs): # real signature unknown
    """ Extend list by appending elements from the iterable. """
    pass
  • RandomCrop(min_size, max_size):将img,target裁剪为随机尺寸大小

T.RandomCrop(crop_size), #随机裁剪 crop_size=480

源码阅读: 

def pad_if_smaller(img, size, fill=0):
    # 如果图像最小边长小于给定size,则用数值fill进行padding
    min_size = min(img.size)
    if min_size < size: #图像边长小的时候
        ow, oh = img.size
        padh = size - oh if oh < size else 0  #一般使用0填充
        padw = size - ow if ow < size else 0
        img = F.pad(img, (0, 0, padw, padh), fill=fill)
    return img

class RandomCrop(object):  #从图片中随机位置裁剪出size大小的图片
    def __init__(self, size):
        self.size = size

    def __call__(self, image, target):
        image = pad_if_smaller(image, self.size) #如果图像最小边长小于给定size,则用数值fill进行padding
        target = pad_if_smaller(target, self.size, fill=255) #填充的像素是没有意义的,所以标签设置255,求损失的时候会忽略
        crop_params = T.RandomCrop.get_params(image, (self.size, self.size))   # get_params(img, output_size),返回i, j, th, tw
        image = F.crop(image, *crop_params)  #裁剪的大小
        target = F.crop(target, *crop_params)
        return image, target
    def get_params(img: Tensor, output_size: Tuple[int, int]) -> Tuple[int, int, int, int]:
        """Get parameters for ``crop`` for a random crop.

        Args:
            img (PIL Image or Tensor): Image to be cropped.
            output_size (tuple): Expected output size of the crop.

        Returns:
            tuple: params (i, j, h, w) to be passed to ``crop`` for random crop.
        """
        w, h = F.get_image_size(img)   #传入的img大小
        th, tw = output_size  #裁剪大小

        if h + 1 < th or w + 1 < tw:
            raise ValueError(
                "Required crop size {} is larger then input image size {}".format((th, tw), (h, w))
            )  #如果填充后,得到的img图片大小小于裁剪大小则会报错

        if w == tw and h == th:  #填充后,img大小与裁剪大小相等
            return 0, 0, h, w
 
        #填充后,img图片大于裁剪大小,返回需要裁剪的地方(i,j)以及目标裁剪的高和宽
        i = torch.randint(0, h - th + 1, size=(1, )).item()
        j = torch.randint(0, w - tw + 1, size=(1, )).item()
        return i, j, th, tw

 


版权声明:本文为qq_36998053原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_36998053/article/details/122359046