import os import io import numpy as np import matplotlib.pyplot as plt from PIL import Image import paddle from paddle.nn import functional as F import random from paddle.io import Dataset from visualdl import LogWriter from paddle.vision.transforms import transforms as T import warnings import cv2 as cv from PIL import Image import re warnings.filterwarnings("ignore") os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" class SeparableConv2D(paddle.nn.Layer): def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=None, weight_attr=None, bias_attr=None, data_format="NCHW"): super(SeparableConv2D, self).__init__() self._padding = padding self._stride = stride self._dilation = dilation self._in_channels = in_channels self._data_format = data_format # 第一次卷积参数,没有偏置参数 filter_shape = [in_channels, 1] + self.convert_to_list(kernel_size, 2, 'kernel_size') self.weight_conv = self.create_parameter(shape=filter_shape, attr=weight_attr) # 第二次卷积参数 filter_shape = [out_channels, in_channels] + self.convert_to_list(1, 2, 'kernel_size') self.weight_pointwise = self.create_parameter(shape=filter_shape, attr=weight_attr) self.bias_pointwise = self.create_parameter(shape=[out_channels], attr=bias_attr, is_bias=True) def convert_to_list(self, value, n, name, dtype=np.int): if isinstance(value, dtype): return [value, ] * n else: try: value_list = list(value) except TypeError: raise ValueError("The " + name + "'s type must be list or tuple. Received: " + str( value)) if len(value_list) != n: raise ValueError("The " + name + "'s length must be " + str(n) + ". Received: " + str(value)) for single_value in value_list: try: dtype(single_value) except (ValueError, TypeError): raise ValueError( "The " + name + "'s type must be a list or tuple of " + str( n) + " " + str(dtype) + " . Received: " + str( value) + " " "including element " + str(single_value) + " of type" + " " + str(type(single_value))) return value_list def forward(self, inputs): conv_out = F.conv2d(inputs, self.weight_conv, padding=self._padding, stride=self._stride, dilation=self._dilation, groups=self._in_channels, data_format=self._data_format) out = F.conv2d(conv_out, self.weight_pointwise, bias=self.bias_pointwise, padding=0, stride=1, dilation=1, groups=1, data_format=self._data_format) return out class Encoder(paddle.nn.Layer): def __init__(self, in_channels, out_channels): super(Encoder, self).__init__() self.relus = paddle.nn.LayerList( [paddle.nn.ReLU() for i in range(2)]) self.separable_conv_01 = SeparableConv2D(in_channels, out_channels, kernel_size=3, padding='same') self.bns = paddle.nn.LayerList( [paddle.nn.BatchNorm2D(out_channels) for i in range(2)]) self.separable_conv_02 = SeparableConv2D(out_channels, out_channels, kernel_size=3, padding='same') self.pool = paddle.nn.MaxPool2D(kernel_size=3, stride=2, padding=1) self.residual_conv = paddle.nn.Conv2D(in_channels, out_channels, kernel_size=1, stride=2, padding='same') def forward(self, inputs): previous_block_activation = inputs y = self.relus[0](inputs) y = self.separable_conv_01(y) y = self.bns[0](y) y = self.relus[1](y) y = self.separable_conv_02(y) y = self.bns[1](y) y = self.pool(y) residual = self.residual_conv(previous_block_activation) y = paddle.add(y, residual) return y class Decoder(paddle.nn.Layer): def __init__(self, in_channels, out_channels): super(Decoder, self).__init__() self.relus = paddle.nn.LayerList( [paddle.nn.ReLU() for i in range(2)]) self.conv_transpose_01 = paddle.nn.Conv2DTranspose(in_channels, out_channels, kernel_size=3, padding=1) self.conv_transpose_02 = paddle.nn.Conv2DTranspose(out_channels, out_channels, kernel_size=3, padding=1) self.bns = paddle.nn.LayerList( [paddle.nn.BatchNorm2D(out_channels) for i in range(2)] ) self.upsamples = paddle.nn.LayerList( [paddle.nn.Upsample(scale_factor=2.0) for i in range(2)] ) self.residual_conv = paddle.nn.Conv2D(in_channels, out_channels, kernel_size=1, padding='same') def forward(self, inputs): previous_block_activation = inputs y = self.relus[0](inputs) y = self.conv_transpose_01(y) y = self.bns[0](y) y = self.relus[1](y) y = self.conv_transpose_02(y) y = self.bns[1](y) y = self.upsamples[0](y) residual = self.upsamples[1](previous_block_activation) residual = self.residual_conv(residual) y = paddle.add(y, residual) return y class PetNet(paddle.nn.Layer): def __init__(self, num_classes): super(PetNet, self).__init__() self.conv_1 = paddle.nn.Conv2D(3, 32, kernel_size=3, stride=2, padding='same') self.bn = paddle.nn.BatchNorm2D(32) self.relu = paddle.nn.ReLU() in_channels = 32 self.encoders = [] self.encoder_list = [64, 128, 256] self.decoder_list = [256, 128, 64, 32] for out_channels in self.encoder_list: block = self.add_sublayer('encoder_{}'.format(out_channels), Encoder(in_channels, out_channels)) self.encoders.append(block) in_channels = out_channels self.decoders = [] for out_channels in self.decoder_list: block = self.add_sublayer('decoder_{}'.format(out_channels), Decoder(in_channels, out_channels)) self.decoders.append(block) in_channels = out_channels self.output_conv = paddle.nn.Conv2D(in_channels, num_classes, kernel_size=3, padding='same') def forward(self, inputs): y = self.conv_1(inputs) y = self.bn(y) y = self.relu(y) for encoder in self.encoders: y = encoder(y) for decoder in self.decoders: y = decoder(y) y = self.output_conv(y) return y IMAGE_SIZE = (512, 512) num_classes = 2 network = PetNet(num_classes) model = paddle.Model(network) optimizer = paddle.optimizer.RMSProp(learning_rate=0.001, parameters=network.parameters()) layer_state_dict = paddle.load("mymodel.pdparams") opt_state_dict = paddle.load("optimizer.pdopt") network.set_state_dict(layer_state_dict) optimizer.set_state_dict(opt_state_dict) def FinalImage(mask,image): # 这个函数的作用是把mask高斯模糊之后的遮罩和原始的image叠加起来 #输入 mask [0,255]的这招图 #image 必须无条件转化为512*512 三通道彩图 th = cv.threshold(mask,140,255,cv.THRESH_BINARY)[1] blur = cv.GaussianBlur(th,(33,33), 15) heatmap_img = cv.applyColorMap(blur, cv.COLORMAP_OCEAN) Blendermap = cv.addWeighted(heatmap_img, 0.5, image, 1, 0) return Blendermap import gradio as gr def Showsegmentation(image): mask = paddle.argmax(network(paddle.to_tensor([((image - 127.5) / 127.5).transpose(2, 0, 1)]))[0], axis=0).numpy() mask=mask.astype('uint8')*255 immask=cv.resize(mask, (512, 512)) image=cv.resize(image,(512,512)) blendmask=FinalImage(immask,image) return blendmask gr.Interface(fn=Showsegmentation, inputs="image", outputs="image").launch(share=True)