游程编码又称行程长度编码,是一种简单的非破坏性资料压缩方法。RLE适用于颜色较单一的图片,如果图片颜色复杂则很难起到压缩的作用。改编码方式在深度学习语义分割的标签制作中有应用。
0001100000110000
0011110001111000
0111111011111100
1111111111111110
1111111111111110
1111111111111110
1111111111111110
1111111111111110
0111111111111100
0011111111111000
0001111111110000
0000111111100000
0000011111000000
0000001110000000
0000000100000000
上面的图像只有两种颜色,白色(0),红色(1)。
为了压缩文件,RLE编码将图片每一行的像素替换为连续相同的像素值的个数。通常以白色开头
如上图的第一行则可以表示为:
3 2 5 2 4
第二行可表示为:
2 4 3 4 3
第四行则不同,因为它是以红色像素开始的,上面举例的两行都是以白色开始的。第四行可表示为:
0 15 1
整幅图像通过rle编码则可以表示为:
3 2 5 2 4
2 4 3 4 3
1 6 1 6 2
0 15 1
0 15 1
0 15 1
0 15 1
0 15 1
1 13 2
2 11 3
3 9 4
4 7 5
5 5 6
6 3 7
7 1 8
一幅经过RLE编码的黑白二值图
4, 9, 3
4, 7, 2, 1, 2
4, 7, 2, 1, 2
4, 9, 3
4, 7, 5
4, 7, 5
5, 5, 6
0, 15, 1
1, 13, 2
则解压后的图片可表示为:
RLE to Image 和 image to RLE 参考代码(针对黑白二值图)
import numpy as np
import pandas as pd
import cv2
# 将图片编码为rle格式
def rle_encode(im):
'''
im: numpy array, 1 - mask, 0 - background
Returns run length as string formated
'''
pixels = im.flatten(order = 'F')
pixels = np.concatenate([[0], pixels, [0]])
runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
runs[1::2] -= runs[::2]
return ' '.join(str(x) for x in runs)
# 将rle格式进行解码为图片
def rle_decode(mask_rle, shape=(512, 512)):
'''
mask_rle: run-length as string formated (start length)
shape: (height,width) of array to return
Returns numpy array, 1 - mask, 0 - background
'''
s = mask_rle.split()
starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]
starts -= 1
ends = starts + lengths
img = np.zeros(shape[0]*shape[1], dtype=np.uint8)
for lo, hi in zip(starts, ends):
img[lo:hi] = 1
return img.reshape(shape, order='F')
参考链接: