Task 01 语义分割-RLE编码
目录
- 思考
- 源码
- 自我理解RLE
- 关于源码中注释部分question的解释
思考
- RLE是什么?
- 它是怎么运作的?
- 在mask.csv中图片后面的一系列数字具体表达什么意思?
源码
import os
import cv2
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from typing import Tuple
mask_csv_path = r"../dataset/train_mask.csv/train_mask.csv"
assert os.path.exists(mask_csv_path), FileExistsError("`{0}` does not exist".format(mask_csv_path))
def rle_encode(img: np.ndarray) -> str:
"""
将传入的图片编码成RLE格式
:img: 需要编码的图片数据,type -> np.ndarray
其中像素数据表示为:1 -> mask, 0 -> background
:return:
"""
# 将图片数据进行扁平化,转换成一维数组 e.g. array = np.array([[1,2],[3,4]])
# 其中order = {'C', 'F', 'A', 'K'} res = array.flatten(order=<order>)
# C:means to flatten in row-major (C-style) order. >>> res = [1,2,3,4]
# F:means to flatten in column-major (Fortran- style) order. >>> res = [1,3,2,4]
# A: means to flatten in column-major order if a is Fortran contiguous in memory, row-major order otherwise. >>> res = [1,2,3,4]
# K: means to flatten a in the order the elements occur in memory. >>> res = [1,2,3,4]
# 默认值为:C
pixels = img.flatten(order='F')
# 数组拼接 numpy.concatenate((a1,a2,...), axis=0)
# >>> pixels = [0, *pixels, 0]
# TODO: Q1:这里在数组的前后都追加0,的目的是什么?为什么这么做?@lpliner@2021年2月19日11:26:36
# 因为下方会通过切片取值然后按位比较数据的差异,以此来记录数据更替的交界点,如果不使用追加数据0,那么在切片过程中可能会导致数据的丢失
pixels = np.concatenate([[0], pixels, [0]])
# np.where(condition)
# >>> pixels[1:] = [*pixels, 0]
# >>> pixels[:-1] = [0, *pixels]
# 当pixels[1:] != pixels[:-1] 依次按照坐标对比,当符合条件的则记下对应的下标,并返回tuple(array(...),)
# TODO: Q2:这里对比像素的目的是什么?为什么之后又要+1?@lpliner@2021年2月19日11:27:37
runs = np.where(pixels[1:] != pixels