图像分割7日打卡营 作业分享
收藏
很开心,这次图像分割训练营真是干货满满,朱老师讲解得真的是太好了。但是对于还是菜鸟的我来说,内容确实有点难了……看来我是得先去补一下基础
那就分享一下第一次作业的代码吧,全程跟着朱老师手打的代码,了解了如何建立模型,导入数据和基本的数据转换
basic_model.py:
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph import Conv2D
from paddle.fluid.dygraph import to_variable
from paddle.fluid.dygraph import Pool2D
import numpy as np
np.set_printoptions(precision=2)
class BasicModel(fluid.dygraph.Layer):
# BasicModel contains:
# 1. pool: 4x4 max pool op, with stride 4
# 2. conv: 3x3 kernel size, takes RGB image as input and output num_classes channels,
# note that the feature map size should be the same
# 3. upsample: upsample to input size
#
# TODOs:
# 1. The model takes an random input tensor with shape (1, 3, 8, 8)
# 2. The model outputs a tensor with same HxW size of the input, but C = num_classes
# 3. Print out the model output in numpy format
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)
# 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], inputs.shape[3]))
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)# nchw
print('Input data shape: ', input_data.shape)
input_data = to_variable(input_data)
print("input_data is ",input_data)
output_data = model(input_data)
output_data = output_data.numpy()
print('Output data shape: ', output_data.shape)
if __name__ == "__main__":
main()
basic_dataloader.py
import os
import random
import numpy as np
import cv2
import paddle.fluid as fluid
class Transform(object):
def __init__(self, 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_LINEAR)
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_list_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 preprocess(self, data, label):
h,w,c=data.shape
h_gt, w_gt=label.shape
assert h==h_gt, "error"
assert w==w_gt, "error"
if self.transform:
data, label=self.transform(data, label)
label=label[:,:,np.newaxis]
return data, label
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.CUDAPlace(0)
with fluid.dygraph.guard(place):
transform=Transform(256)
# TODO: craete BasicDataloder instance
basic_dataloader=BasicDataLoader(
image_folder="./work/dummy_data",
image_list_file="./work/dummy_data/list.txt",
transform=transform,
shuffle=True
)
# TODO: craete fluid.io.DataLoader instance
dataloader=fluid.io.DataLoader.from_generator(capacity=1, use_multiprocess=False)
dataloader.set_sample_generator(basic_dataloader,
batch_size=batch_size,
places=place)
# TODO: set sample generator for fluid dataloader
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 __name__ == "__main__":
main()
basic_transforms.py
import cv2
import numpy as np
import os
class Compose(object):
def __init__(self, transforms):
self.transforms = transforms
def __call__(self, image, label=None):
for t in self.transforms:
image, label = t(image, label)
return image, label
class Normalize(object):
def __init__(self, mean_val, std_val, val_scale=1):
# set val_scale = 1 if mean and std are in range (0,1)
# set val_scale to other value, if mean and std are in range (0,255)
self.mean = np.array(mean_val, dtype=np.float32)
self.std = np.array(std_val, dtype=np.float32)
self.val_scale = 1 / 255.0 if val_scale == 1 else 1
def __call__(self, image, label=None):
image = image.astype(np.float32)
image = image * self.val_scale
image = image - self.mean
image = image * (1 / self.std)
return image, label
class ConvertDataType(object):
def __call__(self, image, label=None):
if label is not None:
label = label.astype(np.int64)
return image.astype(np.float32), label
class Pad(object):
def __init__(self, size, ignore_label=255, mean_val=0, val_scale=1):
# set val_scale to 1 if mean_val is in range (0, 1)
# set val_scale to 255 if mean_val is in range (0, 255)
factor = 255 if val_scale == 1 else 1
self.size = size
self.ignore_label = ignore_label
self.mean_val = mean_val
# from 0-1 to 0-255
if isinstance(self.mean_val, (tuple, list)):
self.mean_val = [int(x * factor) for x in self.mean_val]
else:
self.mean_val = int(self.mean_val * factor)
def __call__(self, image, label=None):
h, w, c = image.shape
pad_h = max(self.size - h, 0)
pad_w = max(self.size - w, 0)
pad_h_half = int(pad_h / 2)
pad_w_half = int(pad_w / 2)
if pad_h > 0 or pad_w > 0:
image = cv2.copyMakeBorder(image,
top=pad_h_half,
left=pad_w_half,
bottom=pad_h - pad_h_half,
right=pad_w - pad_w_half,
borderType=cv2.BORDER_CONSTANT,
value=self.mean_val)
if label is not None:
label = cv2.copyMakeBorder(label,
top=pad_h_half,
left=pad_w_half,
bottom=pad_h - pad_h_half,
right=pad_w - pad_w_half,
borderType=cv2.BORDER_CONSTANT,
value=self.ignore_label)
return image, label
# TODO
class CenterCrop(object):
def __init__(self, size):
assert type(size) in [int, tuple], "CHECK SIZE TYPE!"
if isinstance(size, int):
self.size = (size, size)
else:
self.size = size
def __call__(self, image, label):
h, w = image.shape[:2]
h_start = np.random.randint(0, h - self.size[0] + 1)
w_start = np.random.randint(0, w - self.size[1] + 1)
h_end, w_end = h_start + self.size[0], w_start + self.size[1]
image = image[h_start:h_end, w_start:w_end, :]
label = label[h_start:h_end, w_start:w_end]
return image, label
# TODO
class Resize(object):
def __init__(self, size):
assert type(size) in [int, tuple], "CHECK SIZE TYPE!"
if isinstance(size, int):
self.size = (size, size)
else:
self.size = size
def __call__(self, image, label):
image = cv2.resize(image, dsize=self.size, interpolation=cv2.INTER_LINEAR)
label = cv2.resize(label, dsize=self.size, interpolation=cv2.INTER_NEAREST)
return image, label
# TODO
class RandomFlip(object):
def __init__(self, prob):
self.prob = prob
def __call__(self, image, label):
if np.random.rand() <= self.prob:
image = image[:, ::-1, :]
label = label[:, ::-1]
else:
image = image[::-1, :, :]
label = label[::-1, :]
return image, label
# TODO
class RandomCrop(object):
def __init__(self, size):
assert type(size) in [int, tuple], "CHECK SIZE TYPE!"
if isinstance(size, int):
self.size = (size, size)
else:
self.size = size
def __call__(self, image, label):
h, w = image.shape[:2]
h_start = np.random.randint(0, h - self.size[0] + 1)
w_start = np.random.randint(0, w - self.size[1] + 1)
h_end, w_end = h_start + self.size[0], w_start + self.size[1]
image = image[h_start:h_end, w_start:w_end, :]
label = label[h_start:h_end, w_start:w_end]
return image, label
# TODO
class Scale(object):
def __init__(self, scale=0.5):
self.scale = scale
def __call__(self, image, label):
image = cv2.resize(image, dsize=None, fx=self.scale, fy=self.scale, interpolation=cv2.INTER_LINEAR)
label = cv2.resize(label, dsize=None, fx=self.scale, fy=self.scale, interpolation=cv2.INTER_NEAREST)
return image, label
# TODO
class RandomScale(object):
def __init__(self, scales=[0.5, 1, 2, 3]):
self.scales = scales
def __call__(self, image, label):
scale = float(np.random.choice(self.scales))
image = cv2.resize(image, dsize=None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
label = cv2.resize(label, dsize=None, fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST)
return image, label
def main():
cwd = os.path.dirname(os.path.abspath(__file__))
image_path = os.path.join(cwd, "dummy_data/JPEGImages/2008_000064.jpg")
label_path = os.path.join(cwd, "dummy_data/GroundTruth_trainval_png/2008_000064.png")
# image = cv2.imread('./dummy_data/JPEGImages/2008_000064.jpg')
# label = cv2.imread('./dummy_data/GroundTruth_trainval_png/2008_000064.png')
image = cv2.imread(image_path, 1)
label = cv2.imread(label_path, 0)
print(image.shape, label.shape)
# TODO: crop_size
crop_size = 256
# TODO: Transform: RandomScale, RandomFlip, Pad, RandomCrop
transform = Compose([RandomScale(scales=[0.5, 1, 2]),
RandomFlip(prob=0.5),
Pad(size=crop_size),
RandomCrop(size=crop_size)])
for i in range(10):
# TODO: call transform
image, label = transform(image, label)
# TODO: save image
save_path = os.path.join(cwd, 'save')
if not os.path.exists(save_path):
os.makedirs(save_path)
cv2.imwrite(os.path.join(save_path,'{}.jpg'.format(i)), image)
cv2.imwrite(os.path.join(save_path,'{}.png'.format(i)), label)
if __name__ == "__main__":
main()
7天的时间太短啦,说过去就过去啦。接下来要好好把视频反复看,争取能够全部弄懂!加油!
0
收藏
请登录后评论
有码有真相~
不说了,我也去看回放了 :)
加油!