在TF.DATASET和keras的ImageDataGenerator中应用CV2完成复杂图像处理

前言

在深度学习的实际工作和比赛中,对于小规模数据集我们可以采用运用opencv的各种操作处理,然后全部读取到内存中再传入tf.data.dataset的pipline完成数据读取(tf.data.dataset的预处理在一般情况只支持TF预置的一些简单图像操作)。但是在大规模数据集中,这种是方案需要大量消耗内存,对于我们这种平民玩家是不可行的方案。对于这种情况,有两个解决方法(是我个人常用的两种框架tensorflowkeras):

  • 第一个是tf.data.dataset中使用tf.py_func函数来实现opencv中的一些复杂处理。
  • 第二种是参考keras中的ImageDataGenerator文档,编写自己的图像数据生成器。

tf.data.dataset的实现

考虑一个我打比赛实例,一个kaggle的多分类比赛(https://www.kaggle.com/c/aptos2019-blindness-detection/kernels。

  • 因为数据提交时需要验证一个30K的图片集,所以我们必须使用批量读取来训练模型。
  • 这次比赛中我们想使用图片的纹理来进行训练,最好和快速的方法是使用opencv处理。
  • 在TF.DATA.DATASET中有tf.py_func中来实现额外的CV2操作。

以上是我处理的基本思路,接下来直接上代码:

   #预处理部分,用py_func函数包装起来
   #filename是图片位置
    def _read_py_function(filename, label):
        train_img=[]
        radius = 1  # LBP算法中范围半径的取值
        n_points = 8 * radius # 领域像素点数
        img = cv2.imread(filename.decode(),cv2.IMREAD_UNCHANGED)#读图片,可以说各种借口中CV2的读取速度最快
        img = cv2.resize(img,(224,224))
        img 
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用TensorFlow实现的Unet遥感图像分类代码: ```python import tensorflow as tf import numpy as np import os import cv2 from sklearn.model_selection import train_test_split # 设置随机数种子,保证每次运行结果一致 np.random.seed(42) tf.random.set_seed(42) # 数据集路径 data_path = "path/to/dataset" # 定义Unet网络结构 def Unet(): inputs = tf.keras.layers.Input(shape=(256, 256, 3)) conv1 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs) conv1 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1) pool1 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(conv1) conv2 = tf.keras.layers.Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1) conv2 = tf.keras.layers.Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2) pool2 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(conv2) conv3 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool2) conv3 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3) pool3 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(conv3) conv4 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool3) conv4 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4) drop4 = tf.keras.layers.Dropout(0.5)(conv4) pool4 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(drop4) conv5 = tf.keras.layers.Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool4) conv5 = tf.keras.layers.Conv2D(1024, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5) drop5 = tf.keras.layers.Dropout(0.5)(conv5) up6 = tf.keras.layers.Conv2D(512, 2, activation='relu', padding='same', kernel_initializer='he_normal')( tf.keras.layers.UpSampling2D(size=(2, 2))(drop5)) merge6 = tf.keras.layers.concatenate([drop4, up6], axis=3) conv6 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge6) conv6 = tf.keras.layers.Conv2D(512, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6) up7 = tf.keras.layers.Conv2D(256, 2, activation='relu', padding='same', kernel_initializer='he_normal')( tf.keras.layers.UpSampling2D(size=(2, 2))(conv6)) merge7 = tf.keras.layers.concatenate([conv3, up7], axis=3) conv7 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge7) conv7 = tf.keras.layers.Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv7) up8 = tf.keras.layers.Conv2D(128, 2, activation='relu', padding='same', kernel_initializer='he_normal')( tf.keras.layers.UpSampling2D(size=(2, 2))(conv7)) merge8 = tf.keras.layers.concatenate([conv2, up8], axis=3) conv8 = tf.keras.layers.Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge8) conv8 = tf.keras.layers.Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv8) up9 = tf.keras.layers.Conv2D(64, 2, activation='relu', padding='same', kernel_initializer='he_normal')( tf.keras.layers.UpSampling2D(size=(2, 2))(conv8)) merge9 = tf.keras.layers.concatenate([conv1, up9], axis=3) conv9 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(merge9) conv9 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv9) conv9 = tf.keras.layers.Conv2D(2, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv9) conv10 = tf.keras.layers.Conv2D(1, 1, activation='sigmoid')(conv9) model = tf.keras.Model(inputs=inputs, outputs=conv10) return model # 加载数据集 def load_data(): images = [] masks = [] for root, dirs, files in os.walk(data_path): for file in files: if file.endswith(".tif"): # 读取遥感图像 image = cv2.imread(os.path.join(root, file)) # 读取对应的遥感图像掩码 mask = cv2.imread(os.path.join(root, file.replace(".tif", "_mask.tif")), cv2.IMREAD_GRAYSCALE) # 对掩码进行二值化处理 mask = np.where(mask > 0, 1, 0) # 调整图像大小为256x256 image = cv2.resize(image, (256, 256)) mask = cv2.resize(mask, (256, 256)) # 将图像和掩码添加到列表 images.append(image) masks.append(mask) # 将图像和掩码转换为numpy数组 images = np.array(images) masks = np.array(masks) # 将掩码转换为one-hot编码 masks = tf.keras.utils.to_categorical(masks, num_classes=2) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(images, masks, test_size=0.2, random_state=42) return X_train, X_test, y_train, y_test # 训练模型 def train_model(): # 加载数据集 X_train, X_test, y_train, y_test = load_data() # 构建Unet模型 model = Unet() # 定义损失函数和优化器 loss_fn = tf.keras.losses.BinaryCrossentropy() optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3) # 编译模型 model.compile(optimizer=optimizer, loss=loss_fn, metrics=['accuracy']) # 训练模型 model.fit(X_train, y_train, batch_size=32, epochs=50, validation_data=(X_test, y_test)) if __name__ == '__main__': train_model() ``` 在这个实现,我们使用了TensorFlowkeras API来构建Unet模型。load_data函数用于加载数据集,其包括遥感图像和对应的掩码。训练模型使用了BinaryCrossentropy作为损失函数和Adam作为优化器,训练50个epochs。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值