rle的编码与解码的代码实现Python

RLE(Run-Length Encoding)全称是游程编码,又译行程长度编码,或称为变动长度编码法。它是一种简单的非破坏性资料压缩法,主要技术是检测重复的比特或字符序列,并用它们的出现次数取而代之。这种压缩方法在控制论中对于二值图像而言是一种重要的编码方法,尤其适用于计算机生成的图形图像,对减少存储容量很有效果。

RLE的基本原理

RLE的基本原理是在给定的数据图像中寻找连续的重复数值,然后用两个字符取代这些连续值。具体来说,它将一扫描行中颜色值相同的相邻像素用两个字段表示:第一个字段是一个计数值,用于指定像素重复的次数;第二个字段是具体像素的值。通过压缩除掉数据中的冗余字节或字节中的冗余位,从而达到减少文件所占空间的目的。

RLE的用途

  1. 图像压缩:RLE压缩算法是Windows系统中使用的一种图像文件压缩方法,尤其适合于二值图像的编码。如果图像由很多块颜色或灰度相同的大面积区域组成,采用RLE编码可以达到很高的压缩比。
  2. 数据压缩:RLE不仅限于图像数据,还可以用于其他类型的数据压缩,特别是当数据中存在大量连续重复的元素时。
  3. 无损压缩:RLE是一种无损压缩技术,意味着在解压缩后,数据可以完全恢复到原始状态,不会丢失任何信息。

RLE的优缺点

优点

  • 加压缩和解压缩都非常快。
  • 压缩过程简单直观,易于实现。
  • 对于具有大量连续重复数据的情况,压缩效果显著。

缺点

  • 如果原始数据中连续重复的数据较少,压缩效果可能不明显,甚至可能导致数据膨胀。
  • 不适用于连续色调图像的压缩,如日常生活中的照片。

编码:

def mask2rle(img):
    '''
    img: numpy array, 1 -> mask, 0 -> background
    Returns run length as string formated
    '''
    pixels = img.T.flatten()
    pixels = np.concatenate([[0], pixels, [0]])
    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
    # print("runs[1::2]: {}".format(runs[1::2].shape))
    # print("runs[::2]: {}".format(runs[::2].shape))
    runs[1::2] -= runs[::2]
    return ' '.join(str(x) for x in runs)


读入数据并写入csv的完整过程,最后会生成一个csv文件。mask的值是0,1的二值图像,0是背景,1是前景。读入mask数据也可以使用cv2读入,写入csv的方式也可以按照自己喜欢的方式写入。

import numpy as np
import csv
import os

import pandas as pd
from PIL import Image
def mask2rle(img):
    '''
    img: numpy array, 1 -> mask, 0 -> background
    Returns run length as string formated
    '''
    pixels = img.T.flatten()
    pixels = np.concatenate([[0], pixels, [0]])
    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
    # print("runs[1::2]: {}".format(runs[1::2].shape))
    # print("runs[::2]: {}".format(runs[::2].shape))
    runs[1::2] -= runs[::2]
    return ' '.join(str(x) for x in runs)

def read_mask(mask_path):
    mask=Image.open(mask_path)
    mask=np.array(mask)
    mask=mask/255


if __name__=='__main__':

    mask_paths="******" # mask 的位置

    image_ids =os.listdir(mask_paths)
    # # 准备要写入CSV的数据
    data_to_write = []
    for image_id in image_ids:
        mask_path=os.path.join(mask_paths+image_id)
        mask=read_mask(mask_path)
        rle_string = mask2rle(mask)  # 计算RLE编码
        height, width = mask.shape  # 获取图像尺寸
        row = {'image_id': image_id, 'cell_rle': rle_string,'width': width, 'height': height}
        data_to_write.append(row)

    # # 写入CSV文件
    with open('encoded_masks0.csv', 'w', newline='') as csvfile:
        fieldnames = ['image_id', 'cell_rle', 'width', 'height']  # CSV的列名
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

        writer.writeheader()  # 写入表头
        for row in data_to_write:
            writer.writerow(row)  # 写入每一行数据

    

 解码:

def rle2mask(mask_rle, shape=(256, 256)):
    if mask_rle != 'None':
        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).T
    else:
        return np.zeros([shape[1], shape[0]], dtype=np.uint8)

af9d2b9ab1e24772af12e639192c787f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值