- 主要探究检测分割模型数据增强操作有哪些?

- 检测分割模型图像输入大小?检测模型Faster rcnn输入较大800+;而ssd则有300,512之分;分割模型一般deeplab使用321,513,769等;输入大小对结果敏感吗?

- 检测分割模型的batch-szie都比较小;这对显存消耗很大,和输入大小的关系?本身分割模型deeplab系列就有空洞卷积,显存消耗就大了;

检测模型

- 统计数据集RGB通道的均值;减均值;

- 尺度缩放,这样进行的缩放不会造成图像形变;

- 像素填充32倍整数;

- 另外检测模型中的数据增强方法?一般采用什么,主要是针对ann(bounding box不好操作吧!)

其中还可以采取第三步,将图片的宽和高扩展为32的整倍数,正如在Retinanet使用的。下面是一个简单的Pytorch数据预处理模块:

class Resizer():
def __call__(self, sample, targetSize=608, maxSize=1024, pad_N=32):
image, anns = sample['img'], sample['ann']
rows, cols = image.shape[:2] smaller_size, larger_size = min(rows, cols), max(rows, cols)
scale = targetSize / smaller_size
if larger_size * scale > maxSize:
scale = maxSize / larger_size
image = skimage.transform.resize(image, (int(round(rows*scale)),
int(round(cols*scale))),
mode='constant')
rows, cols, cns = image.shape[:3] pad_w, pad_h = (pad_N - cols % pad_N), (pad_N - rows % pad_N)
new_image = np.zeros((rows + pad_h, cols + pad_w, cns)).astype(np.float32)
new_image[:rows, :cols, :] = image.astype(np.float32) anns[:, :4] *= scale
return {'img': torch.from_numpy(new_image),
'ann':torch.from_numpy(anns),
'scale':scale}

分割模型

- 分割模型对数据增强的处理!

- https://github.com/hualin95/Deeplab-v3plus/blob/master/datasets/cityscapes_Dataset.py

def __getitem__(self, item):
id = self.items[item]
filename = id.split("train_")[-1].split("val_")[-1]
image_filepath = os.path.join(self.image_filepath, id.split("_")[0], id.split("_")[1])
image_filename = filename + "_leftImg8bit.png"
image_path = os.path.join(image_filepath, image_filename)
image = Image.open(image_path).convert("RGB") if self.split == "test":
return self._test_transform(image), filename gt_filepath = os.path.join(self.gt_filepath, id.split("_")[0], id.split("_")[1])
gt_filename = filename + "_gtFine_labelIds.png"
gt_image_path = os.path.join(gt_filepath, gt_filename)
gt_image = Image.open(gt_image_path) if self.split == "train" or self.split == "trainval":
image, gt_image = self._train_sync_transform(image, gt_image)
else:
image, gt_image = self._val_sync_transform(image, gt_image,filename)
# print(filename)
return image, gt_image, filename def _train_sync_transform(self, img, mask):
'''
:param image: PIL input image
:param gt_image: PIL input gt_image
:return:
'''
# random mirror
if random.random() < 0.5:
img = img.transpose(Image.FLIP_LEFT_RIGHT)
mask = mask.transpose(Image.FLIP_LEFT_RIGHT)
crop_size = self.crop_size
# random scale (short edge)
short_size = random.randint(int(self.base_size * 0.5), int(self.base_size * 2.0))
w, h = img.size
if h > w:
ow = short_size
oh = int(1.0 * h * ow / w)
else:
oh = short_size
ow = int(1.0 * w * oh / h)
img = img.resize((ow, oh), Image.BILINEAR)
mask = mask.resize((ow, oh), Image.NEAREST)
# pad crop
if short_size < crop_size:
padh = crop_size - oh if oh < crop_size else 0
padw = crop_size - ow if ow < crop_size else 0
img = ImageOps.expand(img, border=(0, 0, padw, padh), fill=0)
mask = ImageOps.expand(mask, border=(0, 0, padw, padh), fill=0)
# random crop crop_size
w, h = img.size
x1 = random.randint(0, w - crop_size)
y1 = random.randint(0, h - crop_size)
img = img.crop((x1, y1, x1 + crop_size, y1 + crop_size))
mask = mask.crop((x1, y1, x1 + crop_size, y1 + crop_size))
# gaussian blur as in PSP
if random.random() < 0.5:
img = img.filter(ImageFilter.GaussianBlur(
radius=random.random()))
# final transform
img, mask = self._img_transform(img), self._mask_transform(mask)
return img, mask def _val_sync_transform(self, img, mask,filename=None):
outsize = self.crop_size
short_size = outsize
w, h = img.size
if w > h:
oh = short_size
ow = int(1.0 * w * oh / h)
else:
ow = short_size
oh = int(1.0 * h * ow / w)
img = img.resize((ow, oh), Image.BILINEAR)
mask = mask.resize((ow, oh), Image.NEAREST)
# center crop
w, h = img.size
x1 = int(round((w - outsize) / 2.))
y1 = int(round((h - outsize) / 2.))
img = img.crop((x1, y1, x1 + outsize, y1 + outsize))
mask = mask.crop((x1, y1, x1 + outsize, y1 + outsize))
# final transform
img, mask = self._img_transform(img), self._mask_transform(mask,filename)
return img, mask def _test_transform(self, img):
outsize = self.crop_size
short_size = outsize
w, h = img.size
if w > h:
oh = short_size
ow = int(1.0 * w * oh / h)
else:
ow = short_size
oh = int(1.0 * h * ow / w)
img = img.resize((ow, oh), Image.BILINEAR)
# center crop
w, h = img.size
x1 = int(round((w - outsize) / 2.))
y1 = int(round((h - outsize) / 2.))
img = img.crop((x1, y1, x1 + outsize, y1 + outsize))
# final transform
img = self._img_transform(img)
return img def _img_transform(self, image):
image_transforms = ttransforms.Compose([
ttransforms.ToTensor(),
ttransforms.Normalize([.485, .456, .406], [.229, .224, .225]),
])
image = image_transforms(image)
return image def _mask_transform(self, gt_image,filename=None):
target = self._class_to_index(np.array(gt_image).astype('int32'),filename)
target = torch.from_numpy(target) return target def __len__(self):
return len(self.items)

- 读取图使用PIL,因此需要转为RGB通道顺序;

- 需要对img,mask都进行数据增强操作;

- https://github.com/kazuto1011/deeplab-pytorch/blob/master/libs/datasets/cocostuff.py

    def __getitem__(self, index):
if self.preload:
image, label = self.images[index], self.labels[index]
else:
image_id = self.files[index]
image, label = self._load_data(image_id)
image, label = self._transform(image, label)
return image.astype(np.float32), label.astype(np.int64) def _load_data(self, image_id):
# Set paths
image_path = osp.join(self.root, "images", image_id + ".jpg")
label_path = osp.join(self.root, "annotations", image_id + ".mat")
# Load an image
image = cv2.imread(image_path, cv2.IMREAD_COLOR).astype(np.float32)
# Load a label map
if self.version == "1.1":
label = sio.loadmat(label_path)["S"].astype(np.int64)
label -= 1 # unlabeled (0 -> -1)
elif self.version == "1.0":
label = np.array(h5py.File(label_path, "r")["S"], dtype=np.int64)
label = label.transpose(1, 0)
label -= 2 # unlabeled (1 -> -1)
else:
raise NotImplementedError(
"1.0 or 1.1 expected, but got: {}".format(self.version)
)
return image, label def _transform(self, image, label):
# Mean subtraction
image -= self.mean
# Pre-scaling
if self.warp:
base_size = (self.base_size,) * 2
else:
raw_h, raw_w = label.shape
if raw_h > raw_w:
base_size = (int(self.base_size * raw_w / raw_h), self.base_size)
else:
base_size = (self.base_size, int(self.base_size * raw_h / raw_w))
image = cv2.resize(image, base_size, interpolation=cv2.INTER_LINEAR)
label = cv2.resize(label, base_size, interpolation=cv2.INTER_NEAREST)
if self.scale is not None:
# Scaling
scale_factor = random.choice(self.scale)
scale_kwargs = {"dsize": None, "fx": scale_factor, "fy": scale_factor}
image = cv2.resize(image, interpolation=cv2.INTER_LINEAR, **scale_kwargs)
label = cv2.resize(label, interpolation=cv2.INTER_NEAREST, **scale_kwargs)
scale_h, scale_w = label.shape
# Padding
pad_h = max(max(base_size[1], self.crop_size) - scale_h, 0)
pad_w = max(max(base_size[0], self.crop_size) - scale_w, 0)
pad_kwargs = {
"top": 0,
"bottom": pad_h,
"left": 0,
"right": pad_w,
"borderType": cv2.BORDER_CONSTANT,
}
if pad_h > 0 or pad_w > 0:
image = cv2.copyMakeBorder(image, value=(0.0, 0.0, 0.0), **pad_kwargs)
label = cv2.copyMakeBorder(label, value=self.ignore_label, **pad_kwargs)
# Random cropping
base_h, base_w = label.shape
start_h = random.randint(0, base_h - self.crop_size)
start_w = random.randint(0, base_w - self.crop_size)
end_h = start_h + self.crop_size
end_w = start_w + self.crop_size
image = image[start_h:end_h, start_w:end_w]
label = label[start_h:end_h, start_w:end_w]
if self.flip:
# Random flipping
if random.random() < 0.5:
image = np.fliplr(image).copy() # HWC
label = np.fliplr(label).copy() # HW
# HWC -> CHW
image = image.transpose(2, 0, 1)
return image, label

- 使用opencv进行读图;

- 都没有进行随机翻转操作,可能对旋转后会产生黑色区域;

- 针对这些问题:在以后的实际项目中注意操作用法,训练网络,查看实际数据增强对任务的提升效果!!!

pytorch中检测分割模型中图像预处理探究的更多相关文章

  1. 基于OpenCV的火焰检测(一)——图像预处理

    博主最近在做一个基于OpenCV的火焰检测的项目,不仅可以检测图片中的火焰,还可以检测视频中的火焰,最后在视频检测的基础上推广到摄像头实时检测.在做这个项目的时候,博主参考了很多相关的文献,用了很多种 ...

  2. laravel中如何在模型中自关联?

    https://segmentfault.com/q/1010000007926567 在模型中声明一对多的关系,关联表本身.parent_id对应父记录的id.我在sof中查阅到很多这样的写法: p ...

  3. 在SQL Server中实现关系模型

    使用SQL Server的Transact-SQL(T-SQL)方言,此楼梯将为您提供如何使用SQL Server表中的数据的基本了解. DML是数据操作语言,是处理数据的语言的一个方面.它包括SEL ...

  4. asp.net MVC 自定义模型绑定 从客户端中检测到有潜在危险的 Request.QueryString 值

    asp.net mvc 自定义模型绑定 有潜在的Requset.Form 自定义了一个模型绑定器.前端会传过来一些敏感字符.调用bindContext. valueProvider.GetValue( ...

  5. 在Keras模型中one-hot编码,Embedding层,使用预训练的词向量/处理图片

    最近看了吴恩达老师的深度学习课程,又看了python深度学习这本书,对深度学习有了大概的了解,但是在实战的时候, 还是会有一些细枝末节没有完全弄懂,这篇文章就用来总结一下用keras实现深度学习算法的 ...

  6. 深度学习中的Normalization模型

    Batch Normalization(简称 BN)自从提出之后,因为效果特别好,很快被作为深度学习的标准工具应用在了各种场合.BN 大法虽然好,但是也存在一些局限和问题,诸如当 BatchSize ...

  7. [优化]深度学习中的 Normalization 模型

    来源:https://www.chainnews.com/articles/504060702149.htm 机器之心专栏 作者:张俊林 Batch Normalization (简称 BN)自从提出 ...

  8. css中的盒子模型

    css中的盒子模型 css中的盒子模型,有两种,一种是“标准 W3C 盒子模型”,另外一种是IE盒子模型.   1.w3c盒子模型 从图中可以看出:w3c盒子模型的范围包括了:margin,borde ...

  9. 深入理解JAVA I/O系列六:Linux中的IO模型

    IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器, ...

随机推荐

  1. C++ code:prime decision

    1 判断一个数是否为素数 对于判断一个数m是否为素数,最朴素的方式是按照素数的定义,试除以从2开始到m-1的整数,倘若无一例外地不能整除,则该数必为素数. #include<iostream&g ...

  2. JVM内存管理概述

    1.概述 java不在需要开发人员显示的分配内存和回收内存,而是由JVM自动管理内存的分配和回收(又称为垃圾回收-GC),这简化了编程难度,但同时可能使得程序员在不知不觉中浪费了很多内存,导致JVM花 ...

  3. PHP递归排序

    递归算法对于任何一个编程人员来说,应该都不陌生.因为递归这个概念,无论是在PHP语言还是Java等其他编程语言中,都是大多数算法的灵魂. 对于PHP新手来说,递归算法的实现原理可能不容易理解.但是只要 ...

  4. POJ 2184 Cow Exhibition (带负值的01背包)

    题意:给你N(N<=100)只牛,每只牛有一个智慧值Si和一个活泼值Fi,现在要从中找出一些来,使得这些牛智慧值总和S与活泼值总和F之和最大,且F和S均为正.Si和Fi范围在-1000到1000 ...

  5. [HAOI2016]放棋子

    题解: 刚开始没有仔细看题目.. 后来发现障碍是每行每列有且只有一个 那么其实会发现这就是一道错排的题目 f[i]=(n-1)*(f[i-1]+f[i-2])

  6. python全栈开发day45-DOM操作、对象、定时器

    一.昨日内容回顾 1.内置对象 Array String Date Math 2.DOM事件三要素:事件源.事件.事件驱动程序 事件源,事件,事件驱动程序 3.获取事件源的三种方式 var oDiv ...

  7. KNN分类算法补充

    KNN补充: 1.K值设定为多大? k太小,分类结果易受噪声点影响:k太大,近邻中又可能包含太多的其它类别的点. (对距离加权,可以降低k值设定的影响) k值通常是采用交叉检验来确定(以k=1为基准) ...

  8. my作业

    学号:2017xxxxxx 我是吴登峰,我的爱好是音乐,看电影,玩游戏! 我的码云个人主页是:https://gitee.com/fengaa 我的第一个项目地址是:https://gitee.com ...

  9. 类的 __call__ 和__repr__ 方法

    __call__: 让类实例可以被调用: __str__ , __repr__ : 两个都能是类实例名能被打印,区别在于repr可在交互是直接打印类名不用加print

  10. VsCode下代码导航

    Visual Studio Code具有高效的代码编辑器,当与编程语言服务结合使用时,可以为您提供IDE的强大功能和文本编辑器的速度.在本主题中,我们将首先描述VS Code的语言智能功能(建议,参数 ...