Warning: This is a development version. The latest stable version is Version 1.3.0.
In this example shows visually how the decoding looks.
This example requires the following python packages to be installed:
1#!/usr/bin/env python
2# encoding: utf-8
3
4# License for Commercial Usage
5# Distributed under the "PYERASURE EVALUATION LICENSE 1.3"
6# Licensees holding a valid commercial license may use this project in
7# accordance with the standard license agreement terms provided with the
8# Software (see accompanying file LICENSE.rst or
9# https://www.steinwurf.com/license), unless otherwise different terms and
10# conditions are agreed in writing between Licensee and Steinwurf ApS in which
11# case the license will be regulated by that separate written agreement.
12#
13# License for Non-Commercial Usage
14# Distributed under the "PYERASURE RESEARCH LICENSE 1.2"
15# Licensees holding a valid research license may use this project in accordance
16# with the license agreement terms provided with the Software
17# See accompanying file LICENSE.rst or https://www.steinwurf.com/license
18
19import pyerasure
20import pyerasure.finite_field
21import pyerasure.generator
22
23import math
24import os
25import time
26import random
27import sys
28
29try:
30 import pygame
31 import pygame.locals
32 import pygame.gfxdraw
33except:
34 import sys
35
36 print("Unable to import pygame module, please make sure it is installed.")
37 sys.exit()
38
39try:
40 import numpy
41except:
42 import sys
43
44 print("Unable to import numpy module, please make sure it is installed.")
45 sys.exit()
46
47while True:
48 try:
49 import Image
50
51 break
52 except ImportError:
53 pass
54
55 try:
56 from PIL import Image
57
58 break
59 except ImportError:
60 pass
61
62 print("Unable to import Image/PIL.Image module.")
63 sys.exit()
64
65
66def main():
67
68 if "--dry-run" in sys.argv:
69 sys.exit(0)
70
71 # Get directory of this file
72 directory = os.path.dirname(os.path.realpath(__file__))
73
74 # The name of the file to use for the test
75 filename = "lena.jpg"
76
77 # Open the image convert it to RGB and get the height and width
78 image = Image.open(os.path.join(directory, filename)).convert("RGB")
79
80 # Create the canvas
81 pygame.init()
82 pygame.display.set_caption("Example Canvas")
83 canvas = pygame.display.set_mode(image.size, pygame.NOFRAME)
84
85 # Paint it black
86 canvas.fill((0, 0, 0))
87
88 # Create the image surface
89 surface = pygame.Surface(image.size)
90
91 # Pick a symbol size (image.width * 3 will create a packet for each
92 # horizontal line of the image, that is three bytes per pixel (RGB))
93 symbol_bytes = image.width * 3
94
95 # Based on the size of the image and the symbol size, calculate the number
96 # of symbols needed for containing the image in a single generation.
97 symbols = int(math.ceil(image.width * image.height * 3.0 / symbol_bytes))
98
99 field = pyerasure.finite_field.Binary8()
100
101 encoder = pyerasure.Encoder(field, symbols, symbol_bytes)
102
103 decoder = pyerasure.Decoder(field, symbols, symbol_bytes)
104
105 generator = pyerasure.generator.RandomUniform(field, encoder.symbols)
106
107 # Create a bytearray from the image to use in the encoding (only pick the
108 # data we have room for).
109 data_in = bytearray(image.tobytes()[-encoder.block_bytes :])
110
111 # Set the converted image data
112 encoder.set_symbols(data_in)
113
114 systematic_index = 0
115 loss_probability = 40
116
117 while not decoder.is_complete():
118 pygame.event.get() # Process events
119 if encoder.rank > systematic_index:
120 index = systematic_index
121 systematic_index += 1
122 symbol = encoder.symbol_data(index)
123
124 if random.randint(0, 100) >= loss_probability:
125 decoder.decode_systematic_symbol(symbol, index)
126 else:
127 coefficients = generator.generate()
128 symbol = encoder.encode_symbol(coefficients)
129
130 if random.randint(0, 100) >= loss_probability:
131 decoder.decode_symbol(symbol, bytearray(coefficients))
132
133 # The data_out buffer is continuously updated
134 image_array = numpy.frombuffer(decoder.block_data(), dtype=numpy.uint8)
135
136 # We use PIL.Image to write the image and pygame to read it. To make
137 # the two compliant, we must reshape, rotate, and flip the array/image.
138 image_array.shape = (image.height, image.width, 3)
139 image_array = numpy.flipud(numpy.rot90(image_array, 1))
140
141 # Blit the image data to the surface
142 pygame.surfarray.blit_array(surface, image_array)
143
144 # Add the surface to the canvas.
145 canvas.blit(surface, (0, 0))
146 pygame.display.flip()
147 time.sleep(0.02)
148
149 time.sleep(2)
150
151 # Check we properly decoded the data
152 if decoder.block_data()[: len(data_in)] == data_in:
153 print("Data decoded correctly")
154 else:
155 print("Unexpected failure to decode please file a bug report :)")
156 sys.exit(1)
157
158
159if __name__ == "__main__":
160 main()