【Tool】Augmentor和imgaug——python图像数据增强库

Augmentor和imgaug——python图像数据增强库

Tags: ComputerVision Python


介绍两个图像增强库:Augmentor和imgaug,Augmentor使用比较简单,只有一些简单的操作。 imgaug实现的功能更多,可以对keypoint, bounding box同步处理,比如你现在由一些标记好的数据,只有同时对原始图片和标记信息同步处理,才能有更多的标记数据进行训练。我在segmentation和detection任务经常使用imgaug这个库。

Augmentor

http://augmentor.readthedocs.io/en/master/index.html
Augmentor 是管道化的图像增强库,每一个增强操作都是逐步叠加在图像上。此外对于输入的图像,可以选择按照一定的概率进行增强,比如只随机对一半图像进行旋转。

rotate(probability=0.5, max_left_rotation=5, max_right_rotation=10)

可以实现的操作有, rotate, crop, perspective skew(视角倾斜), elastic distortions(弹性变换), sheering(坐标轴倾斜), mirroring(镜像)

可以使用Augumentor.Pipeline()创建一个实例,调用各种方法向pipeline添加方法, status()可以显示当前pipeline的状态,在status中每个操作都有一个对应的index, remove_operation(index)移除一个操作, 最后调用sample(nums)得到nums个augument后的图像。

import Augmentor
p = Augmentor.Pipeline("/path/to/images/")
p.status()
p.remove_operation(0)

rotate

  • rotate() 旋转,非90度旋转会带来padding或者裁剪
  • rotate90()
  • rotate180()
  • rotate270()
  • rotate_random_90() 随机旋转,90, 180, 270

resize

crop

  • crop_centre()
  • crop_by_size()
  • crop_random()

sheer

+ sheer()

mirroring

  • flip_left_right()
  • flip_top_bottom()
  • flip_random()

elastic distortion

  • random_distortion()
    Before
    before.jpg
    After
    after.jpg
    弹性变换是在计算机视觉任务中经常使用的一种变换,比较有名的Segmentation Model U-Net就使用了elastic deformation来对自己的数据做Augmentation.最后取得了较好的效果.

imgaug

http://imgaug.readthedocs.io/en/latest/index.html

安装

  依赖

  • numpy
  • scipy
  • scikit-image (pip install -U + scikit-image)
  • six (pip install -U six)
  • OpenCV (i.e. cv2 must be available in python). The library is mainly tested in OpenCV 2, but seems to also work in OpenCV 3.
pip install git+https://github.com/aleju/imgaug

或者

pip install imgaug

前者安装github最新版本,后者安装pypi版本。 

basic

Keypoint

keypoint.jpg

Bounding Boxes

这个部分做object detection的人应该经常用到。

imgaug支持:

  • 将bounding boxes作为对象表示
  • 增强boundiing boxes
  • 在图像上画bounding boxes
  • boxing boxes移动, 映射, 计算IoU

Before
box1.jpg
After

box.jpg

由于VOC_PASCAL是在分割和检测领域常见的数据集,这里给出一个使用VOC_PASCAL标记格式进行数据增强的例子。
标记格式:

<?xml version="1.0" ?>
<annotation>
<folder>Pictures</folder>
<filename>bndbox.jpg</filename>
<path>/home/redtea/Pictures/bndbox.jpg</path>
<source>
    <database>Unknown</database>
</source>
<size>
    <width>1200</width>
    <height>1200</height>
    <depth>3</depth>
</size>

<segmented>0</segmented>
    <object>
    <name>cat</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
        <xmin>49</xmin>
        <ymin>647</ymin>
        <xmax>599</xmax>
        <ymax>1125</ymax>
    </bndbox>
</object>
    <object>
    <name>dog</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
        <xmin>678</xmin>
        <ymin>547</ymin>
        <xmax>1159</xmax>
        <ymax>1159</ymax>
    </bndbox>
</object>
</annotation>
import xml.etree.ElementTree as ET 
import pickle
import  os
from os import getcwd
import numpy as np
from PIL import Image
import cv2

import imgaug as ia 
from imgaug import augmenters as iaa

ia.seed(1)

def read_xml_annotation(root,image_id):
    in_file = open(os.path.join(root,image_id))
    tree = ET.parse(in_file)
    root = tree.getroot()

    bndbox = root.find('object').find('bndbox')

    xmin = int(bndbox.find('xmin').text)
    xmax = int(bndbox.find('xmax').text)
    ymin = int(bndbox.find('ymin').text)
    ymax = int(bndbox.find('ymax').text)

    return (xmin, ymin, xmax, ymax)

def change_xml_annotation(root, image_id, new_target):
    
    new_xmin = new_target[0]
    new_ymin = new_target[1]
    new_xmax = new_target[2]
    new_ymax = new_target[3]

    in_file = open(os.path.join(root, str(image_id)+'.xml')) #这里root分别由两个意思
    tree = ET.parse(in_file)
    xmlroot = tree.getroot() 
    object = xmlroot.find('object')
    bndbox = object.find('bndbox')
    xmin = bndbox.find('xmin')
    xmin.text = str(new_xmin)
    ymin = bndbox.find('ymin')
    ymin.text = str(new_ymin)
    xmax = bndbox.find('xmax')
    xmax.text = str(new_xmax)
    ymax = bndbox.find('ymax')
    ymax.text = str(new_ymax)
    tree.write(os.path.join(root,str(image_id)+"_aug"+'.xml'))





if __name__ == "__main__":

    cmd = os.getcwd()
    image_id = "bndbox"
    img = Image.open(os.path.join(cmd, str(image_id)+'.jpg'))
    img = np.array(img)

    bndbox = read_xml_annotation(cmd, str(image_id)+'.xml')

    bbs = ia.BoundingBoxesOnImage([
       ia.BoundingBox(x1=bndbox[0], y1=bndbox[1], x2=bndbox[2], y2=bndbox[3])
    ], shape=img.shape)
    seq = iaa.Sequential([
    iaa.Flipud(0.5), # vertically flip 20% of all images
       iaa.Multiply((1.2, 1.5)), # change brightness, doesn't affect BBs
       iaa.Affine(
           translate_px={"x": 10, "y": 10},
           scale=(0.8, 0.95),
           rotate=(-10,10)
        ) # translate by 40/60px on x/y axis, and scale to 50-70%, affects BBs
    ])
    seq_det = seq.to_deterministic() # 保持坐标和图像同步改变,而不是随机
    image_aug = seq_det.augment_images([img])[0]
    bbs_aug = seq_det.augment_bounding_boxes([bbs])[0]

    before  = bbs.bounding_boxes[0]
    after = bbs_aug.bounding_boxes[0]
    print("BB : (%.4f, %.4f, %.4f, %.4f) -> (%.4f, %.4f, %.4f, %.4f)" % (
        before.x1, before.y1, before.x2, before.y2,
        after.x1, after.y1, after.x2, after.y2)
    )

    image_before = bbs.draw_on_image(img, thickness=2)
    image_after = bbs_aug.draw_on_image(image_aug, thickness=2)
    Image.fromarray(image_before).save("before.jpg")
    Image.fromarray(image_after).save('after.jpg')

    new_bndbox = []
    new_bndbox.append(int(bbs_aug.bounding_boxes[0].x1))
    new_bndbox.append(int(bbs_aug.bounding_boxes[0].y1))
    new_bndbox.append(int(bbs_aug.bounding_boxes[0].x2))
    new_bndbox.append(int(bbs_aug.bounding_boxes[0].y2))
    
    # 修改xml tree 并保存
    change_xml_annotation(cmd, image_id, new_bndbox)

SxPAl.jpg

SxawJ.jpg

这个包好像不能画出倾斜的bounding box, 我的read xml程序只能读取第一个bounding box,懒得修改了。

总之我觉得如果你Augmentor不能满足你就可以使用imgaug,但是有一点需要注意!imgaug中一些变换会给边缘区域带来黑色填充块,如果这些黑色填充块对你的模型有影响的话,就需要特殊处理!!

转载于:https://www.cnblogs.com/vincentcheng/p/9186540.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值