首页 AI Studio教育版 帖子详情
图像分割7日打卡营 作业分享
收藏
快速回复
AI Studio教育版 文章课程答疑 1164 2
图像分割7日打卡营 作业分享
收藏
快速回复
AI Studio教育版 文章课程答疑 1164 2

很开心,这次图像分割训练营真是干货满满,朱老师讲解得真的是太好了。但是对于还是菜鸟的我来说,内容确实有点难了……看来我是得先去补一下基础

那就分享一下第一次作业的代码吧,全程跟着朱老师手打的代码,了解了如何建立模型,导入数据和基本的数据转换

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
收藏
回复
全部评论(2)
时间顺序
UnseenMe
#2 回复于2020-10

有码有真相~

不说了,我也去看回放了 :)

0
回复
Zohar
#3 回复于2020-10

加油!

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户