keras实现图像语义分割的子函数
来源:互联网 发布:淘宝网网页登陆首页 编辑:程序博客网 时间:2024/06/10 13:22
权重下载地址
参考
图像augmentation及预训练参考
定义损失函数,dice_loss
调色盘
将包含训练、测试、验证集的图像文件夹CamVid放在当前目录下,导入图像数据代码如下:
import utilimport numpy as npimport osDataPath='/CamVid/'def load_data(mode): data=[] label=[] with open(os.getcwd()+DataPath+mode+'.txt') as f: txt=f.readlines() txt=[line.split(' ') for line in txt] for i in range(len(txt)): img_data,img_h,img_w=util.get_preprocessed_image(os.getcwd()+txt[i][0]) data.append(img_data) img_label,y_h,y_w=util.get_preprocessed_label(os.getcwd()+txt[i][1][:-1]) label.append(img_label) return np.array(data),np.array(label)其中训练样本保存在文件夹train中,其ground truth保存在trainannot文件夹中,ground truth是一通道图像,每个像素是类别索引(0~11)。保存训练图像和ground truth路径和名字的文本为train.txt,内容格式为:
/CamVid/train/0001TP_006690.png /CamVid/trainannot/0001TP_006690.png
如果导入的是训练集,则
train_data, train_label = load_data("train")np.save("data/train_data.npy", train_data)
util如下:
import numpy as npfrom PIL import Imagefrom keras.applications.vgg16 import preprocess_inputdef one_hot_it(labels,h,w): x=np.zeros([h,w,12]) for i in range(h): for j in range(w): x[i,j,int(labels[i][j])]=1 return xdef get_preprocessed_label(file_name): #from 1-channel index map to 1-channel binary index map im=np.array(Image.open(file_name)) img_h,img_w=im.shape im=one_hot_it(im,img_h,img_w) if img_h>500 or img_w>500: raise ValueError("Please resize your images to be not bigger than 500 x 500") pad_h=500-img_h pad_w=500-img_w im=np.pad(im,pad_width=((0,pad_h),(0,pad_w),(0,0)),mode='constant',constant_values=0) return im.reshape(500,500,12),img_h,img_wdef get_preprocessed_image(file_name): #Note: channels last im=np.array(Image.open(file_name)).astype(np.float32) assert im.ndim==3,"Only RGB images are supported" img_h,img_w,img_c=im.shape assert img_c==3,"Only RGB images are supported" if img_h>500 or img_w>500: raise ValueError("Please resize your images to be not bigger than 500 x 500") im=preprocess_input(im) pad_h=500-img_h pad_w=500-img_w im=np.pad(im,pad_width=((0,pad_h),(0,pad_w),(0,0)),mode='constant',constant_values=0) return im.astype(np.float32).reshape(500,500,3),img_h,img_wdef get_label_image(probs, img_h, img_w): """ Returns the label image (PNG with Pascal VOC colormap) given the probabilities.Channels_last. """ labels = probs.argmax(axis=2).astype("uint8")[:img_h, :img_w] label_im = Image.fromarray(labels, "P") label_im.putpalette(_PALETTE) return label_im
其中one_hot_it可用keras自带to_categorical实现:
from keras.utils.np_utils import to_categoricalcategorical_labels = to_categorical(imgs, num_classes)label=categorical_labels.reshape(imgs_num,img_rows,img_cols,num_classes)将ground truth显示为彩色的代码如下:
import numpy as npimport osfrom PIL import Imageimport util_PALETTE = [0, 0, 0, 128, 0, 0, 0, 128, 0, 128, 128, 0, 0, 0, 128, 128, 0, 128, 0, 128, 128, 128, 128, 128, 64, 0, 0, 192, 0, 0, 64, 128, 0, 192, 128, 0, 64, 0, 128, 192, 0, 128, 64, 128, 128, 192, 128, 128, 0, 64, 0, 128, 64, 0, 0, 192, 0, 128, 192, 0, 0, 64, 128, 128, 64, 128, 0, 192, 128, 128, 192, 128, 64, 64, 0, 192, 64, 0, 64, 192, 0, 192, 192, 0]_COLOR_LIST=np.array(_PALETTE).reshape(28,3).tolist()def get_rgb(single,h,w): #from index map to rgb x=np.zeros([h,w,3]) for i in range(h): for j in range (w): r,g,b=_COLOR_LIST[int(single[i][j])] x[i,j,0]=r x[i,j,1]=g x[i,j,2]=b r = Image.fromarray(x[:,:,0]).convert('L') g = Image.fromarray(x[:,:,1]).convert('L') b = Image.fromarray(x[:,:,2]).convert('L') image = Image.merge("RGB", (r,g,b)) return imageDataPath = '/CamVid/'mode='test'output_file='/colorlabel/'with open(os.getcwd() + DataPath + mode +'.txt') as f: txt = f.readlines() txt = [line.split(' ') for line in txt] for i in range(len(txt)): im = np.array(Image.open(os.getcwd() +txt[i][1][:-1])) y=im.astype(np.float32) #######################一通道索引图转换为3通道RGB############################################### y= get_rgb(y,y.shape[0],y.shape[1]) y.save(os.getcwd() +output_file+txt[i][1][-18:-1]) #########################一通道索引图显示为彩色,但仍为一通道########################################## y = one_hot_it(y,y.shape[0],y.shape[1]) segmentation = get_label_image(y) segmentation.save(os.getcwd() +output_file+txt[i][1][-18:-1])
将RGB的ground truth转化为多通道二值索引图:
def label_colormap(label_rgb): h=label_rgb.shape[0] w=label_rgb.shape[1] cmap=np.zeros([h,w]) for i in range(h): for j in range(w): r,g,b=label_rgb[i][j] cmap[i][j]=_COLOR_LIST.index([r,g,b]) return cmapdef get_preprocessed_label_MSRC(file_name): #Note: channels_last im =label_colormap(np.array(Image.open(file_name))) img_h, img_w = im.shape im=one_hot_it(im,img_h,img_w) if img_h > 500 or img_w > 500: raise ValueError("Please resize your images to be not bigger than 500 x 500.") pad_h = 500 - img_h pad_w = 500 - img_w im = np.pad(im, pad_width=((0, pad_h), (0, pad_w),(0,0)), mode='constant', constant_values=0) return im.reshape(500, 500,12), img_h, img_w
用单幅图像测试:
input_file = "image.jpg"output_file = "out.png"saved_model_path="my_weights.h5"model = get_model()model.load_weights(saved_model_path)img_data, img_h, img_w = util.get_preprocessed_image(input_file)temp=np.expand_dims(img_data,axis=0)probs = model.predict(temp, verbose=False)[0, :, :, :]segmentation = util.get_label_image(probs, img_h, img_w)segmentation.save(output_file)
使用VGG预训练模型提取图像特征并显示:
from keras.applications.vgg16 import VGG16from keras.preprocessing import imagefrom keras.applications.vgg16 import preprocess_inputfrom keras.models import Modelimport numpy as npimport matplotlib.pyplot as pltimport osimport utilimg_path='image.jpg'img=image.load_img(img_path,target_size=(224,224))x=image.img_to_array(img)x=np.expand_dims(x,axis=0)x=preprocess_input(x)base_model=VGG16(weights='imagenet',include_top=False)model=Model(inputs=base_model.input,outputs=base_model.get_layer('block3_pool').output)block3_pool_features=model.predict(x)[0,:,:,:]for i,layer in enumerate(model.layers): print(i,layer.name)plt.imshow(block3_pool_features[:,:,2]) #show single feature mapplt.axis('off')plt.show()for i in range(20): #show more feature maps plt.figure() plt.imshow(block3_pool_features[:,:,i])
直方图均衡化(图像处理时常将r与b通道互换):
from skimage import exposuredef normalized(rgb): norm=np.zeros((rgb.shape[0], rgb.shape[1], 3),np.float32) b=rgb[:,:,0] g=rgb[:,:,1] r=rgb[:,:,2] norm[:,:,0]=exposure.equalize_hist(b) norm[:,:,1]=exposure.equalize_hist(g) norm[:,:,2]=exposure.equalize_hist(r) return norm
调用时:
from keras.preprocessing import imagex=normalized(image.img_to_array(x))
训练:
import keras.callbacks import ModelCheckpoint,Callback,EarlyStoppingclass LossHistory(Callback): def on_train_begin(self,logs={}): self.losses=[] def on_batch_end(self,batch,logs={}): self.losses.append(logs.get('loss')) model.compile(optimizer=SGD(lr=1e-13,momentum=0.99,nesterov=True),loss='binary_crossentropy',metrics=['accuracy'])checkpointer=ModelCheckpoint(filepath='my.h5',monitor='val_acc',verbose=1,save_best_only=True, save_weights_only=True,mode='auto')history=LossHistory()earlystop=EarlyStopping(monitor='val_acc',patience=10,verbose=1,mode='auto') memory=model.fit(train_data,train_label,batch_size=1,epochs=100,verbose=1, callbacks=[checkpointer,earlystop,history],validation_split=0.1,shuffle=True) #validation_split first, then shuffle (validation no shuffle)scores=model.evaluate(val_data,val_label,batch_size=1,verbose=1)print("%s:%.2f%%" % (model.metrics_names[1],scores[1]*100))
显示acc和loss:
import matplotlib.pyplot as pltprint(memory.history.keys()) #list all data in memory#summaryize memory for accuracyplt.plot(memory.history['acc'])plt.plot(memory.history['val_acc'])plt.title('model accuracy')plt.ylabel('accuracy')plt.xlabel('epoch')plt.legend(['train','val'],loc='upper left')plt.show()#summarize memory for lossplt.plot(memory.history['loss'])plt.plot(memory.history['val_loss'])plt.title('model loss')plt.ylabel('loss')plt.xlabel('epoch')plt.legend(['train','val'],loc='upper right')plt.show()
data augmentation:使用图像生成器ImageDataGenerator,训练时该函数会无限生成数据,直到达到指定的epoch为止。
from keras.preprocessing.image import ImageDataGeneratortrain_datagen=ImageDataGenerator(featurewise_center=False,# set input mean to 0 over the datasetsamplewise_center=False, #set each sample mean to 0featurewise_std_normalization=False, #divide inputs by std of the datasetsamplewise_std_normalization=False, #divide each input by its stdzca_whitening=False, #apply ZCA whiteningrotation_range=10, #randomly rotate images in the range (degrees, 0 to 180)width_shift_range=0.1, #randomly shift iamges horizontally (fraction of total width)height_shift_range=0.1, #randomly shift images vertically (fraction of total height)rescale=1./255,shear_range=0.2, zoom_range=0.2, horizontal_flip=True)test_datagen=ImageDataGenerator(rescale=1./255)train_generator=train_datagen.flow_from_directory(train_data_dir,target_size=(img_width,img_height),batch_size=32,class_mode='binary') #train文件夹下有若干文件夹,各文件夹包含一类。此函数似乎不适用语义分割validation_generator=test_datagen.flow_from_directory(validation_data_dir,target_size=(img_width,img_height),batch_size=32,class_mode='binary')model.fit_generator(train_generator,samples_per_epoch=nb_train_samples,nb_epoch=nb_epoch,validation_data=validation_generator,nb_val_samples=nb_validation_samples)或
model.fit_generator(datagen.flow(x_train,y_train,batch_size=batch_size),steps_per_epoch=batch_size,epochs=epochs,validation_data=(x_test,y_test))显示augmentation后的图像:
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_imgdatagen=ImageDataGenerator(rotation_range=40,width_shift_range=0.2,height_shift_range=0.2,rescale=1./255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')img=load_img('image.jpg')x=img_to_array(img)x=x.reshape((1,)+x.shape)i=0for batch in datagen.flow(x,batch_size=1,save_to_dir='preview',save_prefix='augmentation',save_format='jpg'): i+=1 if i>50: break
使用预训练权重训练新网络有两种方法。一是将网络分成两个子模型,前一个子模型导入已训练的权重,将输出结果作为后一个子模型的输入,训练后一个子模型(只适用add的网络),前一个子模型输出的保存和载入代码如下:
np.save(open('features_train.npy','w'),features_train)train_data=np.load(open('features_train.npy'))二是将已有权重的网络层固定,不再训练,代码如下:
for layer in model.layers[:25]: layer.trainable=False
将模型保存为图片:
from keras.utils import plot_modelplot_model(model,'model1.png')
阅读全文
0 0
- keras实现图像语义分割的子函数
- Caffe的图像语义分割
- 图像语义分割代码实现(1)
- 图像语义分割代码实现(2)
- CRF做图像语义分割的资源
- 图像语义分割的衡量指标详解
- 基于卷积神经网络的图像语义分割
- 图像语义分割的研究进展(课件PPT)
- FCN图像语义分割
- 图像语义分割
- DeepLab:语义图像分割
- 图像语义分割技术
- 图像语义分割
- 图像语义分割
- 图像语义分割
- 图像语义分割概述
- 图像语义分割
- 图像语义分割简介
- xxx.app文件已损坏,打不开,解决方案
- 查询数据库的数据忽略大tetime类型的时分秒
- 大数据七大趋势 第一个趋势是物联网
- 使用iframe框架,top中搜索框提交数据,在main中显示的问题
- JavaWeb学习笔记—Tomcat目录结构以及JavaEE目录结构规范
- keras实现图像语义分割的子函数
- VMware Workstation下的虚拟Linux通过NAT模式共享上网
- org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.yuanv.b
- SpringMVC概述
- Boost.Asio命名空间
- 使用java自带的库下载网页源码和头部信息
- Apache NiFi Processor实战
- Notification(通知栏)
- java希尔排序算法实现