精华内容
下载资源
问答
  • 游程编码

    千次阅读 2018-08-24 16:09:43
    游程编码是一种无损数据压缩编码。通过记录字母连续重复次数的方式,节约存储空间。举例‘BBCCCCABDDD’,可编码为‘2B4CAB3D’(如果某个字符进出现一次则要省略前面的数字1) 输入:一个仅包含字母的字符串 输出:...
    • 游程编码是一种无损数据压缩编码。通过记录字母连续重复次数的方式,节约存储空间。举例‘BBCCCCABDDD’,可编码为‘2B4CAB3D’(如果某个字符进出现一次则要省略前面的数字1)
      • 输入:一个仅包含字母的字符串
      • 输出:一个编码后的字符串
    def encode(s):
        f = s[0]
        count=1
        tmp=''
        for i in range(1,len(s)):
            if f == s[i]:
                count += 1
            else:
                tmp='%s%s%s'%(tmp,count,f)
                f=s[i]
                count=1
        if count==1:
            count=''
        tmp='%s%s%s'%(tmp,count,f)
        return tmp
    s = 'aabbbccccd'
    print(encode(s))
    展开全文
  • 各种游程编码编码表

    2014-12-26 16:08:22
    游程编码,FDR(0游程编码)、EFDR、IFDR、NFDR(01交替游程编码)编码表
  • 二值图像的游程编码及解码一、实验目的掌握游程编码,并用编程实现游程编码及解码。二、实验引言二值图像在图像分析中应用非常广泛,二值图像就是指只有黑白两个灰度级的图像,二值图像具有存储空间小,处理速度快,可以...

    二值图像的游程编码及解码

    一、实验目的

    掌握游程编码,并用编程实现游程编码及解码。

    二、实验引言

    二值图像在图像分析中应用非常广泛

    ,

    二值图像就是指只有黑白两个灰度级的图像

    ,

    值图像具有存储空间小

    ,

    处理速度快

    ,

    可以方便地对图像进行布尔逻辑运算等特点

    .

    更重要的

    ,

    在二值图像的基础上

    ,

    还可以进一步对图像处理(编码等)

    ,

    获得该图像的一些几何特征

    或者其他更多特征。

    游程编码作为编码技术中常用的一种,

    对二值图像非常有效。

    本文介绍

    了二值图像和游程编码,并利用

    Matlab

    语言实现了二值图像的游程编码及解码。

    三、实验原理

    读入图象—

    >

    二值转换—

    >

    游程编码(压缩)—

    >

    恢复原图象

    3.1

    二值转换

    所谓二值图像

    ,

    就是指图像上的所有像素点的灰度值只用两种可能,

    不为

    0

    就为

    1

    也就是整个图像呈现出明显的黑白效果。

    3.2

    游程编码及其原理

    又称“运行长度编码”或“行程编码”,是一种统计编码,该编码属于无损压缩编码

    对于二值图有效。

    行程编码的基本原理是:用一个符号值或串长代替具有相同值的连续符号(连续

    符号构成了一段连续的“行程”。行程编码因此而得名)

    ,使符号长度少于原始数据的

    长度。

    据进行编码时,沿一定方向排列的具有相同灰度值的像素可看成是连续符号,用

    字串代替这些连续符号,可大幅度减少数据量。

    行程编码分为定长行程编码和不定长行程编码两种类型。行程编码是连续精确的

    编码,

    在传输过程中,如果其中一位符号发生错误,即可影响整个编码序列,使行程编

    码无法还原回原始数据。

    3.3

    游程编码算法

    一般游程编码有两种算法

    第一种:使用

    1

    的起始位置和

    1

    的游程长度

    第二种:只使用游程长度,如果第一个编码值为

    0

    ,则表示游程长度编码是从

    0

    像素的

    长度开始。

    两种方法各有优缺点:第一种存储比第二种困难,因此编程也比较复杂。而第二种需要

    知道第一个像素值,故压缩编码算法中需给出所读出的图的第一个像素值。

    此次试验中采用第一种算法。算法举例图示

    压缩后输出为:

    (2,2)(6,3)(13,6)(20,1)(4,6)(11,10)(1,5)(11,1)(17,4)

    展开全文
  • matlab游程编码二值图像的游程编码及解码一、实验目的 掌握游程编码,并用编程实现游程编码及解码。二、实验引言二值图像在图像分析中应用非常广泛,二值图像就是指只有黑白两个灰度级的图像,二值图像具有存储空间小,...

    matlab游程编码

    二值图像的游程编码及解码一、实验目的 掌握游程编码,并用编程实现游程编码及解码。二、实验引言二值图像在图像分析中应用非常广泛,二值图像就是指只有黑白两个灰度级的图像,二值图像具有存储空间小,处理速度快,可以方便地对图像进行布尔逻辑运算等特点.更重要的是,在二值图像的基础上,还可以进一步对图像处理(编码等),获得该图像的一些几何特征或者其他更多特征。游程编码作为编码技术中常用的一种,对二值图像非常有效。本文介绍了二值图像和游程编码,并利用Matlab语言实现了二值图像的游程编码及解码。三、实验原理读入图象—>二值转换—>游程编码(压缩)—>恢复原图象3.1二值转换所谓二值图像,就是指图像上的所有像素点的灰度值只用两种可能,不为“0”就为“1”,也就是整个图像呈现出明显的黑白效果。 3.2游程编码及其原理又称“运行长度编码”或“行程编码”,是一种统计编码,该编码属于无损压缩编码对于二值图有效。 行程编码的基本原理是:用一个符号值或串长代替具有相同值的连续符号(连续符号构成了一段连续的“行程”。行程编码因此而得名),使符号长度少于原始数据的长度。据进行编码时,沿一定方向排列的具有相同灰度值的像素可看成是连续符号,用字串代替这些连续符号,可大幅度减少数据量。行程编码分为定长行程编码和不定长行程编码两种类型。行程编码是连续精确的编码,在传输过程中,如果其中一位符号发生错误,即可影响整个编码序列,使行程编码无法还原回原始数据。3.3游程编码算法一般游程编码有两种算法第一种:使用1的起始位置和1的游程长度第二种:只使用游程长度,如果第一个编码值为0,则表示游程长度编码是从0像素的长度开始。两种方法各有优缺点:第一种存储比第二种困难,因此编程也比较复杂。而第二种需要知道第一个像素值,故压缩编码算法中需给出所读出的图的第一个像素值。 此次试验中采用第一种算法。算法举例图示压缩后输出为:(2,2)(6,3)(13,6)(20,1)(4,6)(11,10)(1,5)(11,1)(17,4)压缩程序流程图:解压流程图:四.结果:以下为实验的运行结果,分别为转换所得的二值图像,游程编码结果,以及游程编码解码后的图像图中第一幅图为原始图片,中间一幅为压缩数据(横轴表示1游程的起始位置,纵轴代表对应的宽度)五:结果分析比较游程编码前的二值图像其像素大小为32*32,游程编码后的大小为其大小为1*1的结构数组,但每一数组长为101。故总长为202.两者比值为0.1973.六:参考文献贾云得,机器视觉,科学出版社,2000。七、附录一、主函数: 二、压缩函数三、解压函数:执行结果:

    展开全文
  • C++设计游程编码

    2019-01-15 22:50:08
    基于C++语言的游程编码设计,可以实现对输入数据进行游程编码解码
  • 游程编码.zip

    2019-07-05 15:40:12
    文件里有一个基础的游程编码压缩,还有一个图像的游程编码压缩,可以运行出结果~
  • 游程编码、算术编码、哈夫曼编码、预测编码的完整代码和思路
  • 一、什么是游程编码游程编码是一种比较简单的压缩算法,其基本思想是将重复且连续出现多次的字符使用(连续出现次数,某个字符)来描述。比如一个字符串:AAAAABBBBCCC使用游程编码可以将其描述为:5A4B3C5A表示这个...

    一、什么是游程编码

    游程编码是一种比较简单的压缩算法,其基本思想是将重复且连续出现多次的字符使用(连续出现次数,某个字符)来描述。

    比如一个字符串:

    AAAAABBBBCCC

    使用游程编码可以将其描述为:

    5A4B3C

    5A表示这个地方有5个连续的A,同理4B表示有4个连续的B,3C表示有3个连续的C,其它情况以此类推。

    原字符串需要12个字符才能描述,而使用游程编码压缩之后只需要6个字符就可以表示,还原回去的时候只需要将字符重复n次即可,这是个原理非常简单的算法。

    再来分析一下这个编码的适用场景,前面说过了这个算法的基本思想是将重复且连续出现的字符进行压缩,使用更简短的方式来描述,这种方式是基于柯氏复杂度的,那么什么是柯氏复杂度呢,比如有这么三个字符串,它们的长度都是100,其中第一个是100个A,第二个是99个A和一个B,第三个是100个完全随机的字符,我们想办法用尽可能短的语言来描述原字符串,描述第一个字符串时可以说“这是100个A”,描述第二个字符串可以说“这是99个A,然后是一个B”,但是描述第三个字符串时应该怎么说呢?比较容易想到的是“这是100个随机字符”,看上去似乎没有问题,但是这里一个比较重要的点是描述信息需要符合这么一个条件,当单独给出对字符串的描述时能够根据描述恢复出原字符串的内容,100个A和先99个A然后是一个B可以,但是100个随机字符太笼统了显然不行,这个描述信息的长度就称之为柯氏复杂度,在这个例子中第一个柯氏复杂度最小,第二第三依次次之。

    那么在不同情况下这个编码的效果如何呢,假如采用定长1个字节来描述连续出现次数,并且一个字符占用1个字节,那么描述(连续出现次数,某个字符)需要的空间是2个字节,只要这个连续出现次数大于2就能够节省空间,比如AAA占用3个字节,编码为(3,A)占用两个字节,能够节省一个字节的空间,可以看出连续出现的次数越多压缩效果越好,节省的空间越大,对一个字符编码能够节省的空间等于=连续出现次数-2,于是就很容易推出连续出现次数等于2时占用空间不变,比如AA占用两个字节,编码为(2,A)仍然占用两个字节,白白浪费了对其编码的资源却没有达到节省空间的效果,还有更惨的情况,就是连续出现次数总是为1,这个时候会越压越大,比如A占用一个字节,编码为(1,A)占用两个字节,比原来多了一个字节,这种情况就很悲剧,一个1M的文件可能一下给压缩成了2M(真是效果奇佳啊),这是能够出现的最糟糕的情况,相当于在文件的每一个字节前面都插入了一个多余的字节0X01(这个字节表示连续出现次数为1),这种情况说明不适合使用游程编码,事实上,绝大多数数据的特征都属于第三种情况,不适合使用游程编码。

    二、 压缩文本

    本节将尝试使用游程编码对文本进行压缩。

    先来写一种最简单的实现,只能压缩英文字母,读取一个字符串,然后一直数出现了多少个连续字符,当重复被打断时就将上一个的重复字符和重复次数记一下,恢复时反之:

    #! /usr/bin/python3

    # -*- coding: utf-8 -*-

    import random

    import string

    def rle_compress(s):

    """

    对字符串使用RLE算法压缩,s中不能出现数字

    :param s:

    :return:

    """

    result = ''

    last = s[0]

    count = 1

    for _ in s[1:]:

    if last == _:

    count += 1

    else:

    result += str(count) + last

    last = _

    count = 1

    result += str(count) + last

    return result

    def rle_decompress(s):

    result = ''

    count = ''

    for _ in s:

    if _.isdigit():

    count += _

    else:

    result += _ * int(count)

    count = ''

    return result

    def random_rle_friendly_string(length):

    """

    生成对RLE算法友好的字符串以演示压缩效果

    :param length:

    :return:

    """

    result = ''

    while length > 0:

    current_length = random.randint(1, length)

    current_char = random.choice(string.ascii_letters)

    result += (current_char * current_length)

    length -= current_length

    return result

    if __name__ == '__main__':

    raw_string = random_rle_friendly_string(128)

    rle_compressed = rle_compress(raw_string)

    rle_decompress = rle_decompress(rle_compressed)

    print(' raw string: %s' % raw_string)

    print(' rle compress: %s' % rle_compressed)

    print('rle decompress: %s' % rle_decompress)

    执行效果:

    97fce3244705001ef2e9b81f52f5ff7d.png

    可以看到,128个字符的原始数据被压缩成9个字符,大约是原来的7%。

    但是上面的不支持数字是个硬伤,为什么不支持数字呢,因为没办法区分一个数字究竟是表示连续出现次数的数字还是重复字符,这个是编码中经常出现的问题,一个很有效的方式是使数据结构化。

    啥是结构化呢,看这个“100M22c6t”,表示连续出现次数的数字100占用三个字符,22占用两个字符,6占用1个字符,不是定长的啊,这个时候可以规定我的整个字符串可以从最开始按两个字符进行分组,每一组的第一个字符表示连续出现次数,第二个字符表示连续出现的字符,这样我按照位置区分数据的类型,就能够存储任意字符了:

    #! /usr/bin/python3

    # -*- coding: utf-8 -*-

    import random

    import string

    def rle_compress(s):

    """

    对字符串使用RLE算法压缩,s可以出现任意字符,包括数字,因为采用了定长表示重复次数

    :param s:

    :return:

    """

    result = ''

    last = s[0]

    count = 1

    for _ in s[1:]:

    # 采用一个字符表示重复次数,所以count最大是9

    if last == _ and count < 9:

    count += 1

    else:

    result += str(count) + last

    last = _

    count = 1

    result += str(count) + last

    return result

    def rle_decompress(s):

    result = ''

    for _ in range(len(s)):

    if _ % 2 == 0:

    result += int(s[_]) * s[_ + 1]

    return result

    def random_rle_friendly_string(length):

    """

    生成对RLE算法友好的字符串以演示压缩效果

    :param length:

    :return:

    """

    char_list_to_be_choice = string.digits + string.ascii_letters

    result = ''

    while length > 0:

    current_length = random.randint(1, length)

    current_char = random.choice(char_list_to_be_choice)

    result += (current_char * current_length)

    length -= current_length

    return result

    if __name__ == '__main__':

    # raw_string = random_rle_friendly_string(128)

    raw_string = "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMcccccccccccccccccccccctttttt"

    rle_compressed = rle_compress(raw_string)

    rle_decompress = rle_decompress(rle_compressed)

    print(' raw string: %s' % raw_string)

    print(' rle compress: %s' % rle_compressed)

    print('rle decompress: %s' % rle_decompress)

    执行效果:

    c0bd6c35bcca811ab99d658041aea0dd.png

    采用定长表示连续出现次数,但是因为一个字符最大能够表示9,所以同样的数据压缩之后比原来大了一些。

    注:这里表示出现次数为了简单采用的是十进制0~9,也可以将其扩展为十六进制0~F,甚至扩展到无符号0~255,但可能会出现一些不可读字符。

    三、 压缩字节(二进制文件)

    前面的例子使用游程编码压缩文本,看起来很好理解,那么游程编码能不能用来压缩二进制文件呢。

    二进制文件在内存中的表示是字节,所以需要想办法能够压缩字节,压缩字节和压缩字符其实是一样一样的,还是结构化的存储,每两个字节一组,每组的第一个字节表示连续出现次数,第二个字节表示连续出现的字节。

    #! /usr/bin/python3

    # -*- coding: utf-8 -*-

    def compress_file_use_rle(src_path, dest_path):

    with open(dest_path, 'wb') as dest:

    with open(src_path, 'rb') as src:

    last = None

    count = 0

    t = src.read(1)

    while t:

    if last is None:

    last = t

    count = 1

    else:

    # 一个字节能够存储的最大长度是255

    if t == last and count < 255:

    count += 1

    else:

    dest.write(int.to_bytes(count, 1, byteorder='big'))

    dest.write(last)

    last = t

    count = 1

    t = src.read(1)

    dest.write(int.to_bytes(count, 1, byteorder='big'))

    dest.write(last)

    def decompress_file_use_rle(src_path, dest_path):

    with open(dest_path, 'wb') as dest:

    with open(src_path, 'rb') as src:

    count = src.read(1)

    byte = src.read(1)

    while count and byte:

    dest.write(int.from_bytes(count, byteorder='big') * byte)

    count = src.read(1)

    byte = src.read(1)

    if __name__ == '__main__':

    img_name = 'test-bmp-24'

    suffix = 'bmp'

    raw_img_path = 'data/%s.%s' % (img_name, suffix)

    rle_compressed_img_save_path = 'data/%s-rle-compressed.%s' % (img_name, suffix)

    rle_decompress_img_save_path = 'data/%s-rle-decompress.%s' % (img_name, suffix)

    compress_file_use_rle(raw_img_path, rle_compressed_img_save_path)

    decompress_file_use_rle(rle_compressed_img_save_path, rle_decompress_img_save_path)

    对文件进行压缩比较适合的情况是文件内的二进制有大量的连续重复,一个经典的例子就是具有大面积色块的BMP图像,BMP因为没有压缩,所以看到的是什么样子存储的时候二进制就是什么样子,来做一个简单的实验,Win+R,输入mspaint打开Windows自带的画图程序,随便涂抹一副具有大面积色块的图片:

    87a1c4bd9e040f3e1f6baf080f43ad99.png

    保存时选择256色的BMP:

    f2c6bd1965863aad8cb1ca26710e4266.png

    为什么一定要是BMP呢,因为这种算法不压缩,存储二进制的规律与看到的一致,那为什么是256色呢,因为上面写的程序只计算后面一个字节的重复次数,而一个字节能够表示最大256色,如果表示一个像素超过了一个字节,那么上面的代码将很可能越压越大起不到任何作用。

    然后对比一下结果:

    a6b2d6edf9ed88206ed58e753705aa3c.png

    压缩效果很惊人,原来370K的文件压缩后只有7K,是原来的1.9%,相当于98.1%的数据被压掉了,并且是无损压缩。

    那么试一下对于颜色比较丰富的256色图图片呢,随便搞一张信息量比较大的贴到画图中然后保存为256色BMP:

    b9e3d23e5920169dc6db3dbeedd57675.png

    将其转为256色之后会损失一些颜色,然后看下效果:

    9930a0c93c70c6d1d30e3ae3c3724bd8.png

    效果并不太理想,所以还是具有大面积色块的256色的BMP更合适,当然存储图片时一般也没有使用BMP格式的,太奢侈了,这里只是强行举了一个例子。

    另外值得一提的是,因为是边读取边压缩边写入,所以这种也可以读取输入流中的数据写到输出流,不受文件大小的限制可以无限压缩下去。

    四、总结

    游程编码适合的场景是数据本身具有大量连续重复出现的内容。

    .

    展开全文
  • 游程编码和Huffman编码的思想进行了明了的阐述,同时将游程编码进行了优化,将这两种编码结合起来,达到较好的压缩效果。
  • 文件包含可执行程序和源代码,可以直接下载运行。C++ QT 实现文件压缩,有两种压缩算法,一是哈夫曼编码,还要一个是游程编码
  • 游程编码C++实现

    2013-05-02 11:20:31
    游程编码程序,输入一个01序列,将它转换成游程编码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 566
精华内容 226
关键字:

游程编码