图像分割
分类
- 图像分割
- 图像语义分割
- 图像实例分割
- 图像全景分割
- 视频目标分割
- 视频实例分割
语义分割
目的
语义分割算法的基本流程
- 输入:图像(RGB)
- 算法:深度学习模型
- 输出:分类结果(与输入大小一致的单通道图)
- 训练过程 :
- 输入: image + label
- 前向:out = model(image)
- 计算损失 :loss = loss_func(out,label)
- 反向:loss.backward()
- 更新权重:optimizer.minimize(loss)
分割网络的评价指标
mIoU
mAcc
代码
环境:Paddle 1.8.4,Python 3.7
BasicModel
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph import to_variable
from paddle.fluid.dygraph import Conv2D
from paddle.fluid.dygraph import Pool2D
import numpy as np
np.set_printoptions(precision=2)
class BasicModel(fluid.dygraph.Layer):
def __init__(self, num_classes=59):
super(BasicModel, self).__init__()
self.pool = Pool2D(pool_size=2, pool_stride=2)
self.conv = Conv2D(num_channels=3, num_filters=num_classes, filter_size=1)
def forward(self, inputs):
x = self.pool(inputs)
x = fluid.layers.interpolate(x, out_shape=inputs.shape[2::])
x = self.conv(x)
return x
def main():
place = paddle.fluid.CPUPlace()
with fluid.dygraph.guard(place):
model = BasicModel(num_classes=59)
model.eval()
input_data = np.random.rand(1, 3, 8, 8).astype(np.float32)
print('input data shape', input_data.shape)
input_data = to_variable(input_data)
output_data = model(input_data)
output_data = output_data.numpy()
print('output data shape', output_data.shape)
if __name__ == "__main__":
main()
BasicDataLoader
import os
import random
import numpy as np
import cv2
import paddle.fluid as fluid
class Transform(object):
def __init__(selfm,size = 256):
self.size = size
def __call__(self,input,label):
input = cv2.resize(input,(self.size),(self.size),interpolation=cv2.INTER_LINEAR)
label = cv2.resize(label,(self.size),(self,size),interpolation=cv2.INTER_NEAREST)
return input,label
class BasicDataLoader(object):
def __init__(self,
image_folder,
image_list_file,
transform=None,
shuffle=True):
self.image_folder=image_folder
self.image_list_file=image_list_file
self.transform=transform
self.shuffle=shuffle
self.data_list = self.read_list()
def read_list(self):
data_list = []
with open(self.image_lise_file) as infile:
for line in infile:
data_path = os.path.join(self.image_folder,line.split()[0])
label_path = os.path.join(self.image_folder,line.split()[1])
data_list.append((data_path,label_path))
random.shuffle(data_list)
return data_list
def pregrocess(self,data,label):
h,w,c = data.shape
h_gt,w_gt = label.shape
if self.transform:
data,label = self.transform(data,label)
label = label[:,:,:np.newaxis]
def __len__(self):
return len(self.data_list)
def __call__(self):
for data_path,label_path in self.data_list:
data = cv2.imread(data_path,cv2_IMREAD_COLOR)
data = cv2.cvtColor(data,cv2.COLOR_BGR2RGB)
label = cv2.imread(label_path,cv2_IMREAD_GRAYSCALE)
print(data.shape,label.shape)
data,label = self.preprocess(data,label)
yield data,label
def main()
batch_size =5
place = fluid.CPUPlace(0)
with fluid.dygraph.guard(place):
transform = Transform(256)
basic_dataloader = BasicDataLodaer(image_folder='./'
image_list_file='./.txt'
transform=transform,
shuffle=True
)
dataloader = fluid.io.DataLoader.from_generator(capacity=1,use_multiprocess = False)
dataloader.set_sample_generator(basic_dataloader,
batch_size=batch_size,
places = place)
num_epoch = 2
for epoch in range(1,num_epoch+1):
print(f'Epoch[{epoch}/num_epoch]:')
for idx,(data,label) in enumerate(dataloader):
print(f'Iter {idx},Data shape:{data.shape},label shape: {label.shape}')
if __main__ =="__main__"
main()
|