系列文章目录(共五章33节已完结)
第一章deeplabv3+源码之慢慢解析 根目录(1)main.py–get_argparser函数
第一章deeplabv3+源码之慢慢解析 根目录(2)main.py–get_dataset函数
第一章deeplabv3+源码之慢慢解析 根目录(3)main.py–validate函数
第一章deeplabv3+源码之慢慢解析 根目录(4)main.py–main函数
第一章deeplabv3+源码之慢慢解析 根目录(5)predict.py–get_argparser函数和main函数
第二章deeplabv3+源码之慢慢解析 datasets文件夹(1)voc.py–voc_cmap函数和download_extract函数
第二章deeplabv3+源码之慢慢解析 datasets文件夹(2)voc.py–VOCSegmentation类
第二章deeplabv3+源码之慢慢解析 datasets文件夹(3)cityscapes.py–Cityscapes类
第二章deeplabv3+源码之慢慢解析 datasets文件夹(4)utils.py–6个小函数
第三章deeplabv3+源码之慢慢解析 metrics文件夹stream_metrics.py–StreamSegMetrics类和AverageMeter类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a1)hrnetv2.py–4个函数和可执行代码
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a2)hrnetv2.py–Bottleneck类和BasicBlock类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a3)hrnetv2.py–StageModule类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(a4)hrnetv2.py–HRNet类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(b1)mobilenetv2.py–2个类和2个函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(b2)mobilenetv2.py–MobileNetV2类和mobilenet_v2函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(c1)resnet.py–2个基础函数,BasicBlock类和Bottleneck类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(c2)resnet.py–ResNet类和10个不同结构的调用函数
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(d1)xception.py–SeparableConv2d类和Block类
第四章deeplabv3+源码之慢慢解析 network文件夹(1)backbone文件夹(d2)xception.py–Xception类和xception函数
第四章deeplabv3+源码之慢慢解析 network文件夹(2)_deeplab.py–ASPP相关的4个类和1个函数
第四章deeplabv3+源码之慢慢解析 network文件夹(3)_deeplab.py–DeepLabV3类,DeepLabHeadV3Plus类和DeepLabHead类
第四章deeplabv3+源码之慢慢解析 network文件夹(4)modeling.py–5个私有函数(4个骨干网,1个模型载入)
第四章deeplabv3+源码之慢慢解析 network文件夹(5)modeling.py–12个调用函数
第四章deeplabv3+源码之慢慢解析 network文件夹(6)utils.py–_SimpleSegmentationModel类和IntermediateLayerGetter类
第五章deeplabv3+源码之慢慢解析 utils文件夹(1)ext_transforms.py.py–2个翻转类和ExtCompose类
第五章deeplabv3+源码之慢慢解析 utils文件夹(2)ext_transforms.py.py–2个裁剪类和2个缩放类
第五章deeplabv3+源码之慢慢解析 utils文件夹(3)ext_transforms.py.py–旋转类,填充类,张量转化类和标准化类
第五章deeplabv3+源码之慢慢解析 utils文件夹(4)ext_transforms.py.py–ExtResize类,ExtColorJitter类,Lambda类和Compose类
第五章deeplabv3+源码之慢慢解析 utils文件夹(5)loss.py–FocalLoss类
第五章deeplabv3+源码之慢慢解析 utils文件夹(6)scheduler.py–PolyLR类
第五章deeplabv3+源码之慢慢解析 utils文件夹(7)utils.py–去标准化,momentum设定,标准化层锁定和路径创建
第五章deeplabv3+源码之慢慢解析 utils文件夹(8)visualizer.py–Visualizer类(完结)
说明
提示:本节介绍ext_transforms.py中的2个裁剪类和2个缩放类。
中心裁剪 ExtCenterCrop类
class ExtCenterCrop(object): #中心切割,实际上是选择中心区域的尺寸进行输出,被切割的是边上的部分。
"""Crops the given PIL Image at the center.
Args:
size (sequence or int): Desired output size of the crop. If size is an
int instead of sequence like (h, w), a square crop (size, size) is
made.
"""
def __init__(self, size):
if isinstance(size, numbers.Number): #numbers.Number此类对象包含三个对象:Integral整型、Real (float)浮点型、Complex (complex)复数。
self.size = (int(size), int(size))
else:
self.size = size
def __call__(self, img, lbl):
"""
Args:
img (PIL Image): Image to be cropped.
Returns:
PIL Image: Cropped image.
"""
return F.center_crop(img, self.size), F.center_crop(lbl, self.size) #调用F.center_crop函数进行操作。
def __repr__(self):
return self.__class__.__name__ + '(size={0})'.format(self.size)
随机裁剪类 ExtRandomCrop类
class ExtRandomCrop(object): #随机位置裁剪。
"""Crop the given PIL Image at a random location.
Args:
size (sequence or int): Desired output size of the crop. If size is an
int instead of sequence like (h, w), a square crop (size, size) is
made.
padding (int or sequence, optional): Optional padding on each border
of the image. Default is 0, i.e no padding. If a sequence of length
4 is provided, it is used to pad left, top, right, bottom borders
respectively.
pad_if_needed (boolean): It will pad the image if smaller than the
desired size to avoid raising an exception.
"""
def __init__(self, size, padding=0, pad_if_needed=False):
if isinstance(size, numbers.Number):
self.size = (int(size), int(size))
else:
self.size = size
self.padding = padding
self.pad_if_needed = pad_if_needed
@staticmethod
def get_params(img, output_size): #如果尺寸不变,则返回(0, 0, h, w)。否则返回(i, j, th, tw),即(0-长宽差值)中间的随机值和输出尺寸。
"""Get parameters for ``crop`` for a random crop.
Args:
img (PIL Image): 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 = img.size #PIL Image对应(w,h)
th, tw = output_size #输出尺寸是传入参数(h,w)
if w == tw and h == th: #如果尺寸不变,则返回(0, 0, h, w)。
return 0, 0, h, w
i = random.randint(0, h - th)
j = random.randint(0, w - tw)
return i, j, th, tw
def __call__(self, img, lbl):
"""
Args:
img (PIL Image): Image to be cropped.
lbl (PIL Image): Label to be cropped.
Returns:
PIL Image: Cropped image.
PIL Image: Cropped label.
"""
assert img.size == lbl.size, 'size of img and lbl should be the same. %s, %s'%(img.size, lbl.size)
if self.padding > 0: #有填充值则填充
img = F.pad(img, self.padding)
lbl = F.pad(lbl, self.padding)
# pad the width if needed
if self.pad_if_needed and img.size[0] < self.size[1]: #有填充需求,且输入的w小于输出的w。
img = F.pad(img, padding=int((1 + self.size[1] - img.size[0]) / 2)) #个人理解,此处的意思是只添加左右。应该是padding=(int((1 + self.size[1] - img.size[0]) / 2),0)
lbl = F.pad(lbl, padding=int((1 + self.size[1] - lbl.size[0]) / 2))
# pad the height if needed
if self.pad_if_needed and img.size[1] < self.size[0]: #有填充需求,且输入的h小于输出的h。
img = F.pad(img, padding=int((1 + self.size[0] - img.size[1]) / 2)) #个人理解,此处的意思是只添加上下。应该是padding=(0,int((1 + self.size[0] - img.size[1]) / 2))
lbl = F.pad(lbl, padding=int((1 + self.size[0] - lbl.size[1]) / 2))
i, j, h, w = self.get_params(img, self.size)
return F.crop(img, i, j, h, w), F.crop(lbl, i, j, h, w) #根据实际参数调用F.crop。
def __repr__(self):
return self.__class__.__name__ + '(size={0}, padding={1})'.format(self.size, self.padding)
随机缩放 ExtRandomScale类
class ExtRandomScale(object): #随机缩放。
def __init__(self, scale_range, interpolation=Image.BILINEAR):
self.scale_range = scale_range #缩放尺寸范围。
self.interpolation = interpolation #此处直接双线性插值。
def __call__(self, img, lbl):
"""
Args:
img (PIL Image): Image to be scaled.
lbl (PIL Image): Label to be scaled.
Returns:
PIL Image: Rescaled image.
PIL Image: Rescaled label.
"""
assert img.size == lbl.size
scale = random.uniform(self.scale_range[0], self.scale_range[1]) #random.uniform从一个均匀分布[low,high)中随机采样,注意定义域是左闭右开,即包含low,不包含high。
target_size = ( int(img.size[1]*scale), int(img.size[0]*scale) ) #读入的img是PIL Image(w,h),此处需要转为(h,w)。
return F.resize(img, target_size, self.interpolation), F.resize(lbl, target_size, Image.NEAREST)
def __repr__(self): #自定义输出实例化对象时的信息,通过重写类的 __repr__() 方法即可。事实上,当我们输出某个实例化对象时,其调用的就是该对象的 __repr__() 方法,输出的是该方法的返回值。
interpolate_str = _pil_interpolation_to_str[self.interpolation] #将图像的双线性插值转化为字符串,以便输出。
return self.__class__.__name__ + '(size={0}, interpolation={1})'.format(self.size, interpolate_str)
缩放尺寸 ExtScale类
class ExtScale(object): #转换尺寸,同ExtRandomScale类理解,只是scale是参数指定的。
"""Resize the input PIL Image to the given scale.
Args:
Scale (sequence or int): scale factors
interpolation (int, optional): Desired interpolation. Default is
``PIL.Image.BILINEAR``
"""
def __init__(self, scale, interpolation=Image.BILINEAR):
self.scale = scale
self.interpolation = interpolation
def __call__(self, img, lbl):
"""
Args:
img (PIL Image): Image to be scaled.
lbl (PIL Image): Label to be scaled.
Returns:
PIL Image: Rescaled image.
PIL Image: Rescaled label.
"""
assert img.size == lbl.size
target_size = ( int(img.size[1]*self.scale), int(img.size[0]*self.scale) ) # 同ExtRandomScale,(W, H)转为(H, W)。
return F.resize(img, target_size, self.interpolation), F.resize(lbl, target_size, Image.NEAREST)
def __repr__(self):
interpolate_str = _pil_interpolation_to_str[self.interpolation]
return self.__class__.__name__ + '(size={0}, interpolation={1})'.format(self.size, interpolate_str)
Tips
- 本节是图像的裁剪和缩放功能。
- 下一个节介绍ext_transforms.py中的旋转类,填充类,张量转化类和标准化类。