图像数据预处理 -- 数据增强、写入tfrecords

Augmentor 是图像数据增强一个很好用的python库,支持多种图像变形变换。

  • 下面这段代码展示的是基于图像分割的数据集,同时生成增强的图像及其对应的label
import Augmentor


# 图像所在目录
AUGMENT_SOURCE_DIR = 'E:/datasets/leafs/imgs'
AUGMENT_LABEL_DIR = 'E:/datasets/leafs/lbls'

# 增强的图像的保存目录,好像只支持绝对路径
AUGMENT_OUTPUT_DIR = 'E:/datasets/leafs/img_aug'


def augment():
    p = Augmentor.Pipeline(
            source_directory=AUGMENT_SOURCE_DIR,
            output_directory=AUGMENT_OUTPUT_DIR
    )
    # 图片对应的标签的目录,且二者必须同名(要自己预处理一下)
    p.ground_truth(ground_truth_directory=AUGMENT_LABEL_DIR)
    # 旋转:概率0.3
    p.rotate(probability=0.3, max_left_rotation=2, max_right_rotation=2)
    # 缩放
    p.zoom(probability=0.3, min_factor=1.1, max_factor=1.2)
    # 歪斜
    p.skew(probability=0.3)
    # 扭曲,注意grid_width, grid_height 不能超过原图
    p.random_distortion(probability=0.3, grid_width=20, grid_height=20, magnitude=1)
    # 四周裁剪
    p.shear(probability=0.3, max_shear_left=2, max_shear_right=2)
    # 随机裁剪
    p.crop_random(probability=0.3, percentage_area=0.8)
    # 翻转
    p.flip_random(probability=0.3)
    # 生成多少增强的图片
    p.sample(n=8100)


# 分离image 和 label
def dispatch():
    root_dir = 'E:/datasets/leafs/img_aug'
    img_out = 'E:/datasets/leafs/images'
    lbl_out = 'E:/datasets/leafs/labels'
    cnt = 0
    files = os.listdir(root_dir)
    for filename in files:
        if filename.startswith('_groundtruth'):
            lbl_path = os.path.join(root_dir, filename)
            img_path = os.path.join(root_dir, filename.replace('_groundtruth_(1)_imgs_', 'imgs_original_'))
            cnt += 1
            shutil.copyfile(img_path, os.path.join(img_out, '%d.png' % cnt))
            shutil.copyfile(lbl_path, os.path.join(lbl_out, '%d.png' % cnt))
    print(cnt)

 

  • 上述操作之后图像和标签会同时生成在同一文件夹(AUGMENT_OUTPUT_DIR)下面,其图像和对应的label命名是对应的,所以下面将二者分别转移到各自的文件夹下:
def standard_img_and_lbl(dir):
    filenames = glob.glob(dir + '/*.png')
    for idx, filename in enumerate(filenames):
        if 'image_original' in filename:
            label_name = filename.replace('image_original_', '_groundtruth_(1)_image_')
            img = cv2.imread(filename)
            lbl = cv2.imread(label_name)
            cv2.imwrite(os.path.join(AUGMENT_IMAGE_PATH, '%d.png'%idx), img)
            cv2.imwrite(os.path.join(AUGMENT_LABEL_PATH, '%d.png'%idx), lbl)

 

  • 将图像写成TFRecords形式保存:TFRecords文件是一种二进制文件,其不对数据进行压缩,所以可以被快速加载到内存中.格式不支持随机访问,因此它适合于大量的数据流,但不适用于快速分片或其他非连续存取
def write_image_to_tfrecords():
    # image / label 各自的存储文件夹
    augment_image_path = AUGMENT_IMAGE_PATH
    augment_label_path = AUGMENT_LABEL_PATH
    # 要生成的文件:train、validation、predict
    train_set_writer = tf.python_io.TFRecordWriter(os.path.join('./dataset/my_set', TRAIN_SET_NAME))
    validation_set_writer = tf.python_io.TFRecordWriter(os.path.join('./dataset/my_set', VALIDATION_SET_NAME))
    predict_set_writer = tf.python_io.TFRecordWriter(os.path.join('./dataset/my_set', PREDICT_SET_NAME))

    # train set
    for idx in range(TRAIN_SET_SIZE):
        train_image = cv2.imread(os.path.join(augment_image_path, '%d.png' % idx))
        train_label = cv2.imread(os.path.join(augment_label_path, '%d.png' % idx), 0)
        train_image = cv2.resize(train_image, (INPUT_WIDTH, INPUT_HEIGHT))
        train_label = cv2.resize(train_label, (INPUT_WIDTH, INPUT_HEIGHT))
        train_label[train_label != 0] = 1
        example = tf.train.Example(features=tf.train.Features(feature={
            'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[train_label.tobytes()])),
            'image_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[train_image.tobytes()]))
        }))     # example对象对label和image数据进行封装
        train_set_writer.write(example.SerializeToString())
        if idx % 100 == 0:
            print('Done train_set writing %.2f%%' % (idx / TRAIN_SET_SIZE * 100))
    train_set_writer.close()
    print('Done test set writing.')

    # validation set
    for idx in range(TRAIN_SET_SIZE, TRAIN_SET_SIZE + VALIDATION_SET_SIZE):
        validation_image = cv2.imread(os.path.join(augment_image_path, '%d.png' % idx))
        validation_label = cv2.imread(os.path.join(augment_label_path, '%d.png' % idx), 0)
        validation_image = cv2.resize(validation_image, (INPUT_WIDTH, INPUT_HEIGHT))
        validation_label = cv2.resize(validation_label, (INPUT_WIDTH, INPUT_HEIGHT))
        validation_label[validation_label != 0] = 1

        example = tf.train.Example(features=tf.train.Features(feature={
            'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[validation_label.tobytes()])),
            'image_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[validation_image.tobytes()]))
        }))
        validation_set_writer.write(example.SerializeToString())  # 序列化为字符串
        if idx % 10 == 0:
            print('Done validation_set writing %.2f%%' % ((idx - TRAIN_SET_SIZE) / VALIDATION_SET_SIZE * 100))
    validation_set_writer.close()
    print("Done validation_set writing")

    # predict set
    predict_image_path = ORIGIN_PREDICT_IMG_DIR
    predict_label_path = ORIGIN_PREDICT_LBL_DIR
    for idx in range(PREDICT_SET_SIZE):
        predict_image = cv2.imread(os.path.join(predict_image_path, '%d.png'%idx))
        predict_label = cv2.imread(os.path.join(predict_label_path, '%d.png'%idx), 0)
        predict_image = cv2.resize(predict_image, (INPUT_WIDTH, INPUT_HEIGHT))
        predict_label = cv2.resize(predict_label, (OUTPUT_WIDTH, OUTPUT_HEIGHT))
        predict_label[predict_label != 0] = 1
        example = tf.train.Example(features=tf.train.Features(feature={
            'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[predict_label.tobytes()])),
            'image_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[predict_image.tobytes()]))
        }))
        predict_set_writer.write(example.SerializeToString())
        if idx % 10 == 0:
            print('Done predict_set writing %.2f%%' % (idx / PREDICT_SET_SIZE * 100))
    predict_set_writer.close()
    print("Done predict_set writing")

 

  • 读取并验证TFRecords文件是否存储正确:
INPUT_WIDTH, INPUT_HEIGHT, INPUT_CHANNEL = 512, 512, 3
OUTPUT_WIDTH, OUTPUT_HEIGHT, OUTPUT_CHANNEL = 512, 512, 1
TRAIN_SET_NAME = 'train_set.tfrecords'
TFRECORDS_DIR = './dataset/my_set'


# 读取图像及其对应的label
def read_image(file_queue):
    # 用于读取TFRecord的类
    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(file_queue)
    # 解析文件
    features = tf.parse_single_example(
            serialized_example,
            features={
                'label': tf.FixedLenFeature([], tf.string),
                'image_raw': tf.FixedLenFeature([], tf.string)
            }
    )
    # 解码为 uint8 的图像格式
    image = tf.decode_raw(features['image_raw'], tf.uint8)
    image = tf.reshape(image, [INPUT_WIDTH, INPUT_HEIGHT, INPUT_CHANNEL])
    label = tf.decode_raw(features['label'], tf.uint8)
    label = tf.reshape(label, [OUTPUT_WIDTH, OUTPUT_HEIGHT])
    return image, label


# 显示图像和label
def read_check_tfrecords():
    train_file_path = os.path.join(TFRECORDS_DIR, TRAIN_SET_NAME)
    train_image_filename_queue = tf.train.string_input_producer(
            string_tensor=tf.train.match_filenames_once(train_file_path),
            num_epochs=1,
            shuffle=True
    )
    train_images, train_labels = read_image(train_image_filename_queue)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        sess.run(tf.local_variables_initializer())
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(coord=coord)
        example, label = sess.run([train_images, train_labels])
        cv2.imshow('image', example)
        cv2.imshow('label', label)
        cv2.waitKey(0)
        coord.request_stop()
        coord.join(threads)
    print('Done reading and checking.')
    
# read_check_tfrecords()

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据预处理是数据分析中非常重要的一个环节,它可以让原始数据更加适合用于各种分析和建模任务。常见的数据预处理包括数据清洗、缺失值处理、异常值处理、特征选择、特征缩放和特征变换等。下面我们将介绍一些常见的数据预处理方法。 1. 数据清洗 数据清洗是指在数据中去除不合理、重复或者无效的数据,保证数据的完整性和准确性。常见的数据清洗方法包括: - 删除重复数据 - 去除异常值 - 去除不合理数据 - 填充缺失值 2. 缺失值处理 缺失值是指数据集中某些数据缺失的情况。常见的缺失值处理方法包括: - 删除缺失值 - 插值法填补缺失值 - 使用平均值、中位数、众数等统计量填补缺失值 3. 异常值处理 异常值是指数据集中不符合正常规律的数据。常见的异常值处理方法包括: - 删除异常值 - 修改异常值 - 使用插值法填补异常值 4. 特征选择 特征选择是指从原始数据中选择最具有代表性的特征,以便用于分析和建模。常见的特征选择方法包括: - 过滤式特征选择 - 包裹式特征选择 - 嵌入式特征选择 5. 特征缩放 特征缩放是指将不同量纲的特征缩放到相同的范围内。常见的特征缩放方法包括: - 标准化 - 归一化 - 对数变换 6. 特征变换 特征变换是指通过对原始数据进行某些变换,使得数据更适合用于分析和建模。常见的特征变换方法包括: - 主成分分析(PCA) - 线性判别分析(LDA) - 因子分析 以上就是一些常见的数据预处理方法,通过对数据进行适当的预处理,可以提高数据分析和建模的准确性和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值