图像处理:基于keras构建FCN用于猪只图像分割

- FCN简介

FCN实际上就是利用CNN底层反卷积上采样得到图像轮廓实现实例分割的过程。博客上已经有很多解析整个过程的技术文章。详见[https://blog.csdn.net/qq_36269513/article/details/80420363]。
(https://blog.csdn.net/qq_36269513/article/details/80420363)
在这里插入图片描述

  • 上采样解析过程如下
    在这里插入图片描述
  • 数据源
    随便百度获取猪只图像。利用labelme进行数据处理
    在这里插入图片描述

实现过程

- 数据预处理
导入相关库

from keras.layers import Conv2D,MaxPool2D,UpSampling2D,Conv2DTranspose,Input,add,MaxPooling2D,concatenate,ZeroPadding2D
from keras.models import Model,Sequential
import os
import numpy as np
import matplotlib.pyplot as plt
import cv2
import sys
import os.path as osp
from PIL import Image

导入数据并padding图像一致尺寸

img_data=[]
label_data=[]
for i in range(1,11):
    i = str(i)
    img = plt.imread('./voc_data/pig/img'+i+'.png')
    label = plt.imread('./voc_data/pig/label'+i+'.png')
    img_data.append(np.array(img))
    label_data.append(np.array(label))

def padding_data(x,y):
    sz = (320, 320)
    n_img = x
    n_label =y
    for i in range(len(x)):
        n_img[i] = cv2.resize(x[i], sz, interpolation = cv2.INTER_CUBIC)
        n_label[i] = cv2.resize(y[i], sz, interpolation = cv2.INTER_CUBIC)
    
    nor_img = [] # 转换后图像
    nor_label = [] # 转换后的标签, 又新建一个 list 是因为这样可以重复运行这个 cell,
               # 如果你内存小就不要新建这个 list, 在原来的数据上操作

    for i in range(len(n_img)): 
    # PngImageFile 转换成 np.array
        nor_img.append(np.array(n_img[i]))
        #nor_img[i] = nor_img[i].astype(np.float32) / 255.0
    
    # 这里没有先把 label_data[i] 转换成 np.array 是因为在读入的时候已经转换过了
        nor_label.append(n_label[i])
    
    # 因为标签图像的值就已经是 01, 就不再除以 255
    # 后面会讲多分类问题怎么处理
        nor_label[i] = nor_label[i].astype(np.float32)   
    return nor_img,nor_label

FCN32s
FCN32s直接利用最后一层上采样32倍;

channels = 3
std_shape = (320,320,3)
model1 = Sequential()
model1.add(Conv2D(32,(3,3),activation='relu',padding='same',input_shape=std_shape))
model1.add(MaxPool2D(2,2))
model1.add(Conv2D(64,(3,3),activation='relu',padding='same',input_shape=std_shape))
model1.add(MaxPool2D(2,2))
model1.add(Conv2D(128,(3,3),activation='relu',padding='same',input_shape=std_shape))
model1.add(MaxPool2D(2,2))
model1.add(Conv2D(256,(3,3),activation='relu',padding='same',input_shape=std_shape))
model1.add(MaxPool2D(2,2))
model1.add(Conv2D(512,(3,3),activation='relu',padding='same',input_shape=std_shape))
model1.add(MaxPool2D(2,2))
model1.add(UpSampling2D((32,32),interpolation = "nearest"))
model1.add(Conv2D(3,(3,3),activation='sigmoid',padding='same'))
model1.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
model1.summary()

FCN 32s模型结构
在这里插入图片描述
FCN16s
利用倒数第二层上采样16倍;

#FCN_16s
up6 = Conv2DTranspose(256,kernel_size=(3,3),strides=(2,2),padding='same',kernel_initializer='he_normal',name='upsamping_6')(max_pool_5)
_16s = add([max_pool_4,up6])
up7 = UpSampling2D((16,16),interpolation='bilinear',name='upsamping_7')(_16s)
conv_11 = Conv2D(3,(3,3),activation='sigmoid',padding='same',name='conv_11')(up7)
model = Model(img_input,conv_11,name='FCN_16S')
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
model.summary()

FCN16s模型结构
在这里插入图片描述
FCN8s
利用倒数第三层上采样8倍;


up6 = Conv2DTranspose(256,(3,3),strides=(2,2),padding='same',kernel_initializer='he_normal',name='upsamping_6')(max_pool_5)
_16s = add([max_pool_4,up6])
up_16s = Conv2DTranspose(128,(3,3),strides=(2,2),padding='same',kernel_initializer='he_normal',name='conv2dtranspose_16s')(_16s)
_8s = add([max_pool_3,up_16s])
up7 = UpSampling2D((8,8),interpolation='bilinear',name='upsamping_7')(_8s)
conv_11 = Conv2D(3,(3,3),activation='sigmoid',padding='same',name='conv_11')(up7)

model_8s = Model(img_input,conv_11)

model_8s.compile(loss='binary_crossentropy',metrics=['accuracy'],optimizer='adam')
model_8s.summary()

FCN8s模型结构
在这里插入图片描述
**

  • 图像结果展现

**
分割好的模型结果展示:对物体标上不同颜色

def plot_(model,i,color_max):
    d=model.predict(nor_img)
    img_marked = nor_img[i].copy()
    img_mask = np.zeros((320,320,3),dtype = np.uint8)

    for r in range(img_marked.shape[0]):
        for c in range(img_marked.shape[1]):
            if d[i][r][c] > color_max: # 阈值
                img_marked[r][c] += [3, 0, 0] # 在 img_marked 上标记为红色
                                            # 三个值分别是 RGB 颜色, 值越小越透明
                img_mask[r][c] = 255
    plt.imshow(img_marked)
    plt.show()
    plt.imshow(img_mask)
    plt.show()
    #plt.imshow(nor_label_[i])
    plt.show()
    #plt.imshow(d[i])
    return d[i]

结果

可以看到FCN32s模型取得的结果上色像素成块状,FCN8s结果效果更好。

  • 结语

本文训练集数据只有10张图片(电脑无GPU显卡,大量本数据训练不起来),训练单只猪只效果尚可,实际运用远远达不到。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是对您的问题的回答: 首先,GAN指的是对抗生成网络,是一种由两个神经网络组成的模型:一个生成器和一个判别器。生成器负责生成新的数据样本,而判别器则试图区分出生成器生成的样本和真实数据样本之间的差别。 使用Keras构建GAN网络用于手写数字图像生成的步骤大致如下: 1. 准备数据集:需要准备手写数字图像的数据集,并将其分为训练集和测试集。 2. 定义生成器网络:生成器网络通常是一个多层的神经网络,其输入为噪声向量,输出为生成的图像。可以使用Keras的Sequential模型定义生成器网络。 3. 定义判别器网络:判别器网络也是一个多层的神经网络,其输入为图像,输出为一个二元分类结果,代表该图像是真实数据还是生成器生成的数据。同样使用Keras的Sequential模型定义判别器网络。 4. 编译GAN网络:将生成器和判别器组合起来形成一个GAN网络。编译GAN网络时需要注意的一点是,对于生成器而言,其误差评估的对象为GAN网络输出的结果,而非生成器的输出结果。 5. 训练GAN网络:将训练集输入生成器网络中进行训练,通过GAN网络在生成图像和判别真实图像之间不断博弈,从而使得生成器不断优化生成效果。训练GAN网络的过程中需要注意的一点是,由于GAN网络的训练目标是非常复杂的,因此需要进行较长时间的训练。 以上是基于Keras构建GAN网络用于手写数字图像生成的大致步骤。希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值