Loading Encoding_decoding.ipynb +49 −42 Original line number Diff line number Diff line %% Cell type:code id:14f74f21 tags: ``` python import numpy as np from matplotlib import pyplot as plt from itertools import product import os import sys from PIL import Image from scipy.optimize import minimize,linprog import time import seaborn as sns from sklearn.neighbors import KernelDensity import pandas as pd from collections import Counter import time import numpy.linalg as la ``` %% Cell type:code id:c16af61f tags: ``` python def file_extractor(dirname="images"): files = os.listdir(dirname) scenes = [] for file in files: if file == '.DS_Store': continue else: scenes.append(os.path.join(dirname, file)) return scenes def image_extractor(scenes): image_folder = [] for scene in scenes: files = os.listdir(scene) for file in files: if file[-5:] != ".tiff" or file[-7:] == "_6.tiff": continue else: image_folder.append(os.path.join(scene, file)) return image_folder #returns a list of file paths to .tiff files in the specified directory given in file_extractor def im_distribution(images, num): """ Function that extracts tiff files from specific cameras and returns a list of all the tiff files corresponding to that camera. i.e. all pictures labeled "_7.tiff" or otherwise specified camera numbers. Parameters: images (list): list of all tiff files, regardless of classification. This is NOT a list of directories but of specific tiff files that can be opened right away. This is the list that we iterate through and divide. num (str): a string designation for the camera number that we want to extract i.e. "14" for double digits of "_1" for single digits. Returns: tiff (list): A list of tiff files that have the specified designation from num. They are the files extracted from the 'images' list that correspond to the given num. """ tiff = [] for im in images: if im[-7:-5] == num: tiff.append(im) return tiff ``` %% Cell type:code id:53786325 tags: ``` python def predict_pix(tiff_image_path, difference = True): """ This function predict the pixel values excluding the boundary. Using the 4 neighbor pixel values and MSE to predict the next pixel value (-1,1) (0,1) (1,1) => relative position of the 4 other given values (-1,0) (0,0) => (0,0) is the one we want to predict take the derivative of mean square error to solve for the system of equation A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) A @ [a, b, c] = [-z0+z2-z3, z0+z1+z2, -z0-z1-z2-z3] where z0 = (-1,1), z1 = (0,1), z2 = (1,1), z3 = (-1,0) and the predicted pixel value is c. Input: tiff_image_path (string): path to the tiff file Return: image ndarray(512 X 640): original image predict ndarray(325380,): predicted image excluding the boundary diff. ndarray(325380,): IF difference = TRUE, difference between the min and max of four neighbors exclude the boundary ELSE: the residuals of the four nearest pixels to a fitted hyperplane error ndarray(325380,): difference between the original image and predicted image A ndarray(3 X 3): system of equation """ image_obj = Image.open(tiff_image_path) #Open the image and read it as an Image object image_array = np.array(image_obj)[1:,:].astype(int) #Convert to an array, leaving out the first row because the first row is just housekeeping data # image_array = image_array.astype(int) A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation # where z0 = (-1,1), z1 = (0,1), z2 = (1,1), z3 = (-1,0) z0 = image_array[0:-2,0:-2] # get all the first pixel for the entire image z1 = image_array[0:-2,1:-1] # get all the second pixel for the entire image z2 = image_array[0:-2,2::] # get all the third pixel for the entire image z3 = image_array[1:-1,0:-2] # get all the forth pixel for the entire image # calculate the out put of the system of equation y0 = np.ravel(-z0+z2-z3) y1 = np.ravel(z0+z1+z2) y2 = np.ravel(-z0-z1-z2-z3) y = np.vstack((y0,y1,y2)) # use numpy solver to solve the system of equations all at once #predict = np.floor(np.linalg.solve(A,y)[-1]) predict = np.round(np.round((np.linalg.solve(A,y)[-1]),1)) #Matrix system of points that will be used to solve the least squares fitting hyperplane points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]]) # flatten the neighbor pixlels and stack them together z0 = np.ravel(z0) z1 = np.ravel(z1) z2 = np.ravel(z2) z3 = np.ravel(z3) neighbor = np.vstack((z0,z1,z2,z3)).T if difference: # calculate the difference diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1) else: #Compute the best fitting hyperplane using least squares #The res is the residuals of the four points used to fit the hyperplane (summed distance of each of the #points to the hyperplane), it is a measure of gradient f, diff, rank, s = la.lstsq(points, neighbor.T, rcond=None) diff = diff.astype(int) # calculate the error error = np.ravel(image_array[1:-1,1:-1])-predict return image_array, predict, diff, error, A ``` %% Cell type:code id:6b965751 tags: ``` python """ this huffman encoding code is found online https://favtutor.com/blogs/huffman-coding """ class NodeTree(object): def __init__(self, left=None, right=None): self.left = left self.right = right def children(self): return self.left, self.right def __str__(self): return str(self.left) + str(self.right) return self.left, self.right def huffman_code_tree(node, binString=''): ''' Function to find Huffman Code ''' if type(node) is str: return {node: binString} (l, r) = node.children() d = dict() d.update(huffman_code_tree(l, binString + '0')) d.update(huffman_code_tree(r, binString + '1')) return d def make_tree(nodes): ''' Function to make tree :param nodes: Nodes :return: Root of the tree ''' while len(nodes) > 1: (key1, c1) = nodes[-1] (key2, c2) = nodes[-2] nodes = nodes[:-2] node = NodeTree(key1, key2) nodes.append((node, c1 + c2)) #reverse True, decending order sorted_nodes = sorted(nodes, key=lambda x: x[1], reverse=True) return sorted_nodes[0][0] #There is a huge memory leak here, no idea how or why nodes = sorted(nodes, key=lambda x: x[1], reverse=True) return nodes[0][0] ``` %% Cell type:code id:b7561883 tags: ``` python def huffman(tiff_image_path, num_bins=4, difference = True): """ This function is used to encode the error based on the difference and split the difference into different bins Input: tiff_image_path (string): path to the tiff file num_bins (int): number of bins Return: list_dic (num_bins + 1): a list of dictionary image (512, 640): original image new_error (512, 640): error that includes the boundary diff (510, 638): difference of min and max of the 4 neighbors boundary (2300,): the boundary values after subtracting the very first pixel value predict (325380,): the list of predicted values bins (num_bins - 1,): a list of threshold to cut the bins A (3 X 3): system of equation huffman_encoding_list list (num_bins + 1): a list of dictionary image_array ndarray (512, 640): original image new_error ndarray (512, 640): error that includes the boundary diff ndarray (510, 638): difference of min and max of the 4 neighbors boundary ndarray (2300,): the boundary values after subtracting the very first pixel value predict ndarray (325380,): the list of predicted values bins list (num_bins - 1,): a list of threshold to cut the bins A ndarray (3 X 3): system of equation """ # get the image_array, etc image_array, predict, diff, error, A = predict_pix(tiff_image_path, difference) # calculate the number of points that will go in each bin data_points_per_bin = len(diff) // num_bins data_points_per_bin = diff.size // num_bins # sort the difference and create the bins sorted_diff = np.sort(diff.copy()) bins = [sorted_diff[i*data_points_per_bin] for i in range(1,num_bins)] # get the boundary boundary = np.hstack((image_array[0,:],image_array[-1,:],image_array[1:-1,0],image_array[1:-1,-1])) # take the difference of the boundary with the very first pixel boundary = boundary - image_array[0,0] #boundary is 1dim, so boundary[0] is just the first element boundary[0] = image_array[0,0] # huffman encode the boundary bound_vals_as_string = [str(i) for i in boundary] freq = dict(Counter(bound_vals_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) huffman_encoding_dict = huffman_code_tree(node) # create a list of huffman table list_dic = [encode] huffman_encoding_list = [huffman_encoding_dict] n = len(bins) # loop through different bins for i in range (0,n): # the fisrt bin # the first bin if i == 0 : # get the point within the bin and huffman encode # get the point within the bin and huffman huffman_encoding_dict mask = diff <= bins[i] line_as_string = [str(i) for i in error[mask].astype(int)] freq = dict(Counter(line_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) list_dic.append(encode) huffman_encoding_dict = huffman_code_tree(node) huffman_encoding_list.append(huffman_encoding_dict) # the middle bins else: # get the point within the bin and huffman encode # get the point within the bin and huffman huffman_encoding_dict mask = diff > bins[i-1] new_error = error[mask] mask2 = diff[mask] <= bins[i] line_as_string = [str(i) for i in new_error[mask2].astype(int)] freq = dict(Counter(line_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) list_dic.append(encode) huffman_encoding_dict = huffman_code_tree(node) huffman_encoding_list.append(huffman_encoding_dict) # the last bin # get the point within the bin and huffman encode # get the point within the bin and huffman huffman_encoding_dict mask = diff > bins[-1] line_as_string = [str(i) for i in error[mask].astype(int)] freq = dict(Counter(line_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) list_dic.append(encode) huffman_encoding_dict = huffman_code_tree(node) huffman_encoding_list.append(huffman_encoding_dict) # create a error matrix that includes the boundary (used in encoding matrix) new_error = np.copy(image_array) new_error[1:-1,1:-1] = np.reshape(error,(510, 638)) keep = new_error[0,0] new_error[0,:] = new_error[0,:] - keep new_error[-1,:] = new_error[-1,:] - keep new_error[1:-1,0] = new_error[1:-1,0] - keep new_error[1:-1,-1] = new_error[1:-1,-1] - keep new_error[0,0] = keep # huffman_encoding_list = list(set(huffman_encoding_list)) diff = np.reshape(diff,(510,638)) # return the huffman dictionary return list_dic, image_array, new_error, diff, boundary, predict, bins, A return huffman_encoding_list, image_array, new_error, diff, boundary, predict, bins, A ``` %% Cell type:code id:2eb774d2 tags: ``` python def encoder(error, list_dic, diff, bound, bins): """ This function encode the matrix with huffman coding tables Input: error (512, 640): a matrix with all the errors list_dic (num_dic + 1,): a list of huffman coding table bound (2300,): the boundary values after subtracting the very first pixel value bins (num_bins - 1,): a list of threshold to cut the bins Return: encoded (512, 640): encoded matrix """ # copy the error matrix (including the boundary) encoded = np.copy(error).astype(int).astype(str).astype(object) #diff = np.reshape(diff,(510,638)) # loop through all the pixel to encode for i in range(encoded.shape[0]): for j in range(encoded.shape[1]): if i == 0 or i == encoded.shape[0]-1 or j == 0 or j == encoded.shape[1]-1: encoded[i][j] = list_dic[0][encoded[i][j]] elif diff[i-1][j-1] <= bins[0]: encoded[i][j] = list_dic[1][encoded[i][j]] elif diff[i-1][j-1] <= bins[1] and diff[i-1][j-1] > bins[0]: encoded[i][j] = list_dic[2][encoded[i][j]] elif diff[i-1][j-1] <= bins[2] and diff[i-1][j-1] > bins[1]: encoded[i][j] = list_dic[3][encoded[i][j]] else: encoded[i][j] = list_dic[4][encoded[i][j]] return encoded ``` %% Cell type:code id:8eeb40d0 tags: ``` python def decoder(A, encoded_matrix, list_dic, bins, use_diff): """ This function decodes the encoded_matrix. Input: A (3 X 3): system of equation list_dic (num_dic + 1,): a list of huffman coding table encoded_matrix (512, 640): encoded matrix bins (num_bins - 1,): a list of threshold to cut the bins Return: decode_matrix (512, 640): decoded matrix """ # change the dictionary back to list # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins the_keys0 = list(list_dic[0].keys()) the_values0 = list(list_dic[0].values()) the_keys1 = list(list_dic[1].keys()) the_values1 = list(list_dic[1].values()) the_keys2 = list(list_dic[2].keys()) the_values2 = list(list_dic[2].values()) the_keys3 = list(list_dic[3].keys()) the_values3 = list(list_dic[3].values()) the_keys4 = list(list_dic[4].keys()) the_values4 = list(list_dic[4].values()) #Matrix system of points that will be used to solve the least squares fitting hyperplane points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]]) decode_matrix = np.zeros((512,640)) # loop through all the element in the matrix for i in range(decode_matrix.shape[0]): for j in range(decode_matrix.shape[1]): # if it's the very first pixel on the image if i == 0 and j == 0: decode_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) # if it's on the boundary elif i == 0 or i == decode_matrix.shape[0]-1 or j == 0 or j == decode_matrix.shape[1]-1: decode_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) + decode_matrix[0][0] # if not the boundary else: # predict the image with the known pixel value z0 = decode_matrix[i-1][j-1] z1 = decode_matrix[i-1][j] z2 = decode_matrix[i-1][j+1] z3 = decode_matrix[i][j-1] y0 = int(-z0+z2-z3) y1 = int(z0+z1+z2) y2 = int(-z0-z1-z2-z3) y = np.vstack((y0,y1,y2)) if use_diff: difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3) else: f, difference, rank, s = la.lstsq(points, [z0,z1,z2,z3], rcond=None) difference = difference.astype(int) predict = np.round(np.round(np.linalg.solve(A,y)[-1][0],1)) # add on the difference by searching the dictionary # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins if difference <= bins[0]: decode_matrix[i][j] = int(the_keys1[the_values1.index(encoded_matrix[i,j])]) + int(predict) elif difference <= bins[1] and difference > bins[0]: decode_matrix[i][j] = int(the_keys2[the_values2.index(encoded_matrix[i,j])]) + int(predict) elif difference <= bins[2] and difference > bins[1]: decode_matrix[i][j] = int(the_keys3[the_values3.index(encoded_matrix[i,j])]) + int(predict) else: decode_matrix[i][j] = int(the_keys4[the_values4.index(encoded_matrix[i,j])]) + int(predict) return decode_matrix.astype(int) ``` %% Cell type:code id:f959fe93 tags: ``` python def compress_rate(image, new_error, diff, bound, list_dic, bins): def compress_rate(image_array, new_error, diff, bound, huffman_encoding_list, bins): ''' This function is used to calculate the compression rate. Input: image (512, 640): original image image_array (512, 640): original_core image new_error (512, 640): error that includes the boundary diff (510, 638): difference of min and max of the 4 neighbors bound (2300,): the boundary values after subtracting the very first pixel value list_dic (num_dic + 1,): a list of huffman coding table huffman_encoding_list (num_dic + 1,): a list of huffman coding table bins (num_bins - 1,): a list of threshold to cut the bins Return: compression rate ''' # the bits for the original image o_len = 0 # the bits for the compressed image c_len = 0 # initializing the varible im = np.reshape(image,(512, 640)) real_b = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1])) original = image[1:-1,1:-1].reshape(-1) #this was unused # im = np.reshape(image,(512, 640)) real_boundary = np.hstack((image_array[0,:],image_array[-1,:],image_array[1:-1,0],image_array[1:-1,-1])) #Bryce's notes: Why are they all reshaped? original_core = image_array[1:-1,1:-1].reshape(-1) diff = diff.reshape(-1) error = new_error[1:-1,1:-1].reshape(-1) # calculate the bit for boundary for i in range(0,len(bound)): o_len += len(bin(real_b[i])[2:]) c_len += len(list_dic[0][str(bound[i])]) o_len += len(bin(real_boundary[i])[2:]) c_len += len(huffman_encoding_list[0][str(bound[i])]) # calculate the bit for the pixels inside the boundary for i in range(0,len(original)): for i in range(0,len(original_core)): # for the original image o_len += len(bin(original[i])[2:]) o_len += len(bin(original_core[i])[2:]) # check the difference and find the coresponding huffman table # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins if diff[i] <= bins[0]: c_len += len(list_dic[1][str(int(error[i]))]) c_len += len(huffman_encoding_list[1][str(int(error[i]))]) elif diff[i] <= bins[1] and diff[i] > bins[0]: c_len += len(list_dic[2][str(int(error[i]))]) c_len += len(huffman_encoding_list[2][str(int(error[i]))]) elif diff[i] <= bins[2] and diff[i] > bins[1]: c_len += len(list_dic[3][str(int(error[i]))]) c_len += len(huffman_encoding_list[3][str(int(error[i]))]) else: c_len += len(list_dic[4][str(int(error[i]))]) c_len += len(huffman_encoding_list[4][str(int(error[i]))]) return c_len/o_len ``` %% Cell type:code id:3e0e9742 tags: ``` python scenes = file_extractor() images = image_extractor(scenes) list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4, False) encoded_matrix = encoder(new_error, list_dic, diff, bound, bins) reconstruct_image = decoder(A, encoded_matrix, list_dic, bins, False) print(np.allclose(image, reconstruct_image)) print(len(list_dic)) ``` %% Output LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL-411 R-321 R-315 R-286 R-281 R-289 R-256 R-229 R-194 R-142 R-238 R-234 R-219 R-255 R-214 R-151 R-259 R-252 R-114 R-147 R-117 R-191 R-163 R-38 R-469 R-426 R-537 R-541 R-521 R-530 R-526 R-497 R-483 R-491 R-466 R-442 R-455 R-487 R-451 R-480 R-489 R-508 R-493 R-495 R-512 R-506 R-482 R-474 R-505 R-488 R-523 R-445 R-397 R-399 R-387 R-369 R-348 R-360 R-361 R-401 R-416 R-65 R148 R172 R189 R190 R209 R114 R111 R-241 R-213 R-143 R-107 R-44 R-334 R-371 R-317 R-352 R-240 R-66 R-92 R108 R120 R129 R144 R171 R166 R163 R175 R216 R196 R146 R140 R138 R150 R149 R145 R121 R112 R-27 R-77 R-75 R-251 R-294 R-356 R-279 R-290 R-193 R-167 R-274 R-354 R-389 R-454 R-380 R-370 R-305 R-326 R-407 R-398 R-372 R-362 R-414 R-424 R-452 R-383 R-324 R-331 R-381 R-346 R-420 R-409 R-453 R-450 R-460 R-449 R-458 R-42 R118 R104 R103 R22275 R-275 R-216 R-260 R-177 R-168 R-172 R-150 R-253 R-123 R-112 R-139 R-118 R-115 R-468 R-494 R-476 R-496 R-514 R-529 R-486 R-440 R-296 R-276 R-267 R-178 R-124 R-119 R-71 R-415 R-418 R-384 R-344 R-332 R-306 R-242 R-269 R-302 R-330 R-309 R-231 R-248 R-64 R-80 R-250 R-95 R126 R127 R-88 R-162 R-109 R-78 R-83 R-233 R-209 R-204 R-170 R-93 R-122 R-179 R-293 R-295 R-261 R-291 R-277 R-257 R-220 R-226 R-208 R-235 R-243 R-338 R-311 R-301 R-135 R-244 R-323 R-349 R-385 R-421 R-425 R-378 R-390 R-417 R-405 R-461 R-403 R-358 R-340 R-413 R-393 R-400 R-428 R-447 R-463 R-473 R-419 R-434 R-457 R-436 R-446 R-439 R-79 R-60 R-49 R-8 R-48 R-10 R-41 R102 R132 R96 R117 R113 R110 R115 R116 R105 R94 R-37 R-200 R-99 R-478 R-392 R-101 R-24 R-34 R-287 R-136 R-76 R-343 R-310 R-271 R-237 R-145 R-62 R-106 R182 R101 R106 R-84 R-81 R-152 R-222 R-120 R-264 R-206 R-131 R-113 R-96 R-108 R-134 R-258 R-266 R-299 R-239 R-307 R-304 R-284 R-297 R-249 R-196 R-199 R-186 R-265 R-230 R-138 R-192 R-236 R-245 R-273 R-254 R-298 R-337 R-373 R-365 R-345 R-319 R-313 R-335 R-320 R-410 R-443 R-432 R-477 R-444 R-437 R-435 R-57 R-128 R-102 R-61 R-94 R-73 R-68 R-70 R-30 R-51 R-74 R24 R91 R109 R107 R93 R-25 R-1 R-40 R-45 R-182 R-153 R-188 R-197 R-133 R-22 R-329 R-347 R-333 R-189 R-184 R-175 R-171 R-169 R-54 R-121 R-72 R-159 R-82 R-98 R-58 R-246 R-125 R-89 R-90 R-97 R-223 R-282 R-272 R-210 R-164 R-180 R-232 R-225 R-205 R-116 R-154 R-263 R-280 R-314 R-429 R-359 R-422 R-412 R-430 R-53 R-46 R-110 R-59 R-87 R-105 R47 R37 R-18 R-26 R21 R-23 R40 R124 R-47 R-33 R-14 R-56 R-39 R-28 R-16 R-31 R-100 R-85 R-140 R-165 R-155 R-104 R-176 R-312 R-268 R-198 R-195 R-174 R-221 R-146 R-217 R-247 R-308 R-318 R-341 R-325 R-408 R-406 R-55 R-36 R3 R-50 R18 R35 R14 R-32 R1 R89 R95 R100 R-21 R-3 R-43 R-149 R-351 R-173 R-91 R-207 R-157 R-127 R-160 R-218 R-212 R-148 R-203 R-224 R-215 R-126 R-202 R-339 R-355 R-7 R-67 R-69 R-63 R-86 R48 R-5 R59 R86 R76 R81 R99 R49 R-13 R-20 R-9 R-19 R13 R39 R-185 R-166 R-158 R-156 R-144 R-130 R-111 R-201 R-227 R-161 R-132 R-187 R-29 R-52 R5 R7 R15 R57 R45 R51 R26 R97 R64 R67 R98 R87 R46 R4 R-17 R-11 R-15 R38 R17 R-211 R-190 R-137 R8 R55 R62 R72 R74 R19 R52 R-35 R-141 R-6 R27 R2 R42 R-4 R30 R28 R41 R78 R43 R22 R0 R32 R85 R88 R66 R79 R80 R92 R77 R58 R34 R12 R11 R53 R-12 R-2 R6 R33 R10 R-183 R16 R29 R36 R90 R84 R75 R68 R56 R44 R50 R61 R60 R63 R20 R73 R23 R-181 R69 R82 R9 R54 R70 R65 R83 R25 R71 R31 True 5 %% Cell type:code id:004e8ba8 tags: ``` python compress_rate(image, new_error, diff, bound, list_dic, bins) ``` %% Output 2.090535888671875 0.4232928466796875 %% Cell type:code id:a282f9e6 tags: ``` python print(sys.getsizeof(encoded_matrix)) print(sys.getsizeof(reconstruct_image)) ``` %% Output 2621552 2621552 %% Cell type:code id:7efe26b9 tags: ``` python ``` Loading
Encoding_decoding.ipynb +49 −42 Original line number Diff line number Diff line %% Cell type:code id:14f74f21 tags: ``` python import numpy as np from matplotlib import pyplot as plt from itertools import product import os import sys from PIL import Image from scipy.optimize import minimize,linprog import time import seaborn as sns from sklearn.neighbors import KernelDensity import pandas as pd from collections import Counter import time import numpy.linalg as la ``` %% Cell type:code id:c16af61f tags: ``` python def file_extractor(dirname="images"): files = os.listdir(dirname) scenes = [] for file in files: if file == '.DS_Store': continue else: scenes.append(os.path.join(dirname, file)) return scenes def image_extractor(scenes): image_folder = [] for scene in scenes: files = os.listdir(scene) for file in files: if file[-5:] != ".tiff" or file[-7:] == "_6.tiff": continue else: image_folder.append(os.path.join(scene, file)) return image_folder #returns a list of file paths to .tiff files in the specified directory given in file_extractor def im_distribution(images, num): """ Function that extracts tiff files from specific cameras and returns a list of all the tiff files corresponding to that camera. i.e. all pictures labeled "_7.tiff" or otherwise specified camera numbers. Parameters: images (list): list of all tiff files, regardless of classification. This is NOT a list of directories but of specific tiff files that can be opened right away. This is the list that we iterate through and divide. num (str): a string designation for the camera number that we want to extract i.e. "14" for double digits of "_1" for single digits. Returns: tiff (list): A list of tiff files that have the specified designation from num. They are the files extracted from the 'images' list that correspond to the given num. """ tiff = [] for im in images: if im[-7:-5] == num: tiff.append(im) return tiff ``` %% Cell type:code id:53786325 tags: ``` python def predict_pix(tiff_image_path, difference = True): """ This function predict the pixel values excluding the boundary. Using the 4 neighbor pixel values and MSE to predict the next pixel value (-1,1) (0,1) (1,1) => relative position of the 4 other given values (-1,0) (0,0) => (0,0) is the one we want to predict take the derivative of mean square error to solve for the system of equation A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) A @ [a, b, c] = [-z0+z2-z3, z0+z1+z2, -z0-z1-z2-z3] where z0 = (-1,1), z1 = (0,1), z2 = (1,1), z3 = (-1,0) and the predicted pixel value is c. Input: tiff_image_path (string): path to the tiff file Return: image ndarray(512 X 640): original image predict ndarray(325380,): predicted image excluding the boundary diff. ndarray(325380,): IF difference = TRUE, difference between the min and max of four neighbors exclude the boundary ELSE: the residuals of the four nearest pixels to a fitted hyperplane error ndarray(325380,): difference between the original image and predicted image A ndarray(3 X 3): system of equation """ image_obj = Image.open(tiff_image_path) #Open the image and read it as an Image object image_array = np.array(image_obj)[1:,:].astype(int) #Convert to an array, leaving out the first row because the first row is just housekeeping data # image_array = image_array.astype(int) A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation # where z0 = (-1,1), z1 = (0,1), z2 = (1,1), z3 = (-1,0) z0 = image_array[0:-2,0:-2] # get all the first pixel for the entire image z1 = image_array[0:-2,1:-1] # get all the second pixel for the entire image z2 = image_array[0:-2,2::] # get all the third pixel for the entire image z3 = image_array[1:-1,0:-2] # get all the forth pixel for the entire image # calculate the out put of the system of equation y0 = np.ravel(-z0+z2-z3) y1 = np.ravel(z0+z1+z2) y2 = np.ravel(-z0-z1-z2-z3) y = np.vstack((y0,y1,y2)) # use numpy solver to solve the system of equations all at once #predict = np.floor(np.linalg.solve(A,y)[-1]) predict = np.round(np.round((np.linalg.solve(A,y)[-1]),1)) #Matrix system of points that will be used to solve the least squares fitting hyperplane points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]]) # flatten the neighbor pixlels and stack them together z0 = np.ravel(z0) z1 = np.ravel(z1) z2 = np.ravel(z2) z3 = np.ravel(z3) neighbor = np.vstack((z0,z1,z2,z3)).T if difference: # calculate the difference diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1) else: #Compute the best fitting hyperplane using least squares #The res is the residuals of the four points used to fit the hyperplane (summed distance of each of the #points to the hyperplane), it is a measure of gradient f, diff, rank, s = la.lstsq(points, neighbor.T, rcond=None) diff = diff.astype(int) # calculate the error error = np.ravel(image_array[1:-1,1:-1])-predict return image_array, predict, diff, error, A ``` %% Cell type:code id:6b965751 tags: ``` python """ this huffman encoding code is found online https://favtutor.com/blogs/huffman-coding """ class NodeTree(object): def __init__(self, left=None, right=None): self.left = left self.right = right def children(self): return self.left, self.right def __str__(self): return str(self.left) + str(self.right) return self.left, self.right def huffman_code_tree(node, binString=''): ''' Function to find Huffman Code ''' if type(node) is str: return {node: binString} (l, r) = node.children() d = dict() d.update(huffman_code_tree(l, binString + '0')) d.update(huffman_code_tree(r, binString + '1')) return d def make_tree(nodes): ''' Function to make tree :param nodes: Nodes :return: Root of the tree ''' while len(nodes) > 1: (key1, c1) = nodes[-1] (key2, c2) = nodes[-2] nodes = nodes[:-2] node = NodeTree(key1, key2) nodes.append((node, c1 + c2)) #reverse True, decending order sorted_nodes = sorted(nodes, key=lambda x: x[1], reverse=True) return sorted_nodes[0][0] #There is a huge memory leak here, no idea how or why nodes = sorted(nodes, key=lambda x: x[1], reverse=True) return nodes[0][0] ``` %% Cell type:code id:b7561883 tags: ``` python def huffman(tiff_image_path, num_bins=4, difference = True): """ This function is used to encode the error based on the difference and split the difference into different bins Input: tiff_image_path (string): path to the tiff file num_bins (int): number of bins Return: list_dic (num_bins + 1): a list of dictionary image (512, 640): original image new_error (512, 640): error that includes the boundary diff (510, 638): difference of min and max of the 4 neighbors boundary (2300,): the boundary values after subtracting the very first pixel value predict (325380,): the list of predicted values bins (num_bins - 1,): a list of threshold to cut the bins A (3 X 3): system of equation huffman_encoding_list list (num_bins + 1): a list of dictionary image_array ndarray (512, 640): original image new_error ndarray (512, 640): error that includes the boundary diff ndarray (510, 638): difference of min and max of the 4 neighbors boundary ndarray (2300,): the boundary values after subtracting the very first pixel value predict ndarray (325380,): the list of predicted values bins list (num_bins - 1,): a list of threshold to cut the bins A ndarray (3 X 3): system of equation """ # get the image_array, etc image_array, predict, diff, error, A = predict_pix(tiff_image_path, difference) # calculate the number of points that will go in each bin data_points_per_bin = len(diff) // num_bins data_points_per_bin = diff.size // num_bins # sort the difference and create the bins sorted_diff = np.sort(diff.copy()) bins = [sorted_diff[i*data_points_per_bin] for i in range(1,num_bins)] # get the boundary boundary = np.hstack((image_array[0,:],image_array[-1,:],image_array[1:-1,0],image_array[1:-1,-1])) # take the difference of the boundary with the very first pixel boundary = boundary - image_array[0,0] #boundary is 1dim, so boundary[0] is just the first element boundary[0] = image_array[0,0] # huffman encode the boundary bound_vals_as_string = [str(i) for i in boundary] freq = dict(Counter(bound_vals_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) huffman_encoding_dict = huffman_code_tree(node) # create a list of huffman table list_dic = [encode] huffman_encoding_list = [huffman_encoding_dict] n = len(bins) # loop through different bins for i in range (0,n): # the fisrt bin # the first bin if i == 0 : # get the point within the bin and huffman encode # get the point within the bin and huffman huffman_encoding_dict mask = diff <= bins[i] line_as_string = [str(i) for i in error[mask].astype(int)] freq = dict(Counter(line_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) list_dic.append(encode) huffman_encoding_dict = huffman_code_tree(node) huffman_encoding_list.append(huffman_encoding_dict) # the middle bins else: # get the point within the bin and huffman encode # get the point within the bin and huffman huffman_encoding_dict mask = diff > bins[i-1] new_error = error[mask] mask2 = diff[mask] <= bins[i] line_as_string = [str(i) for i in new_error[mask2].astype(int)] freq = dict(Counter(line_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) list_dic.append(encode) huffman_encoding_dict = huffman_code_tree(node) huffman_encoding_list.append(huffman_encoding_dict) # the last bin # get the point within the bin and huffman encode # get the point within the bin and huffman huffman_encoding_dict mask = diff > bins[-1] line_as_string = [str(i) for i in error[mask].astype(int)] freq = dict(Counter(line_as_string)) freq = sorted(freq.items(), key=lambda x: x[1], reverse=True) node = make_tree(freq) encode = huffman_code_tree(node) list_dic.append(encode) huffman_encoding_dict = huffman_code_tree(node) huffman_encoding_list.append(huffman_encoding_dict) # create a error matrix that includes the boundary (used in encoding matrix) new_error = np.copy(image_array) new_error[1:-1,1:-1] = np.reshape(error,(510, 638)) keep = new_error[0,0] new_error[0,:] = new_error[0,:] - keep new_error[-1,:] = new_error[-1,:] - keep new_error[1:-1,0] = new_error[1:-1,0] - keep new_error[1:-1,-1] = new_error[1:-1,-1] - keep new_error[0,0] = keep # huffman_encoding_list = list(set(huffman_encoding_list)) diff = np.reshape(diff,(510,638)) # return the huffman dictionary return list_dic, image_array, new_error, diff, boundary, predict, bins, A return huffman_encoding_list, image_array, new_error, diff, boundary, predict, bins, A ``` %% Cell type:code id:2eb774d2 tags: ``` python def encoder(error, list_dic, diff, bound, bins): """ This function encode the matrix with huffman coding tables Input: error (512, 640): a matrix with all the errors list_dic (num_dic + 1,): a list of huffman coding table bound (2300,): the boundary values after subtracting the very first pixel value bins (num_bins - 1,): a list of threshold to cut the bins Return: encoded (512, 640): encoded matrix """ # copy the error matrix (including the boundary) encoded = np.copy(error).astype(int).astype(str).astype(object) #diff = np.reshape(diff,(510,638)) # loop through all the pixel to encode for i in range(encoded.shape[0]): for j in range(encoded.shape[1]): if i == 0 or i == encoded.shape[0]-1 or j == 0 or j == encoded.shape[1]-1: encoded[i][j] = list_dic[0][encoded[i][j]] elif diff[i-1][j-1] <= bins[0]: encoded[i][j] = list_dic[1][encoded[i][j]] elif diff[i-1][j-1] <= bins[1] and diff[i-1][j-1] > bins[0]: encoded[i][j] = list_dic[2][encoded[i][j]] elif diff[i-1][j-1] <= bins[2] and diff[i-1][j-1] > bins[1]: encoded[i][j] = list_dic[3][encoded[i][j]] else: encoded[i][j] = list_dic[4][encoded[i][j]] return encoded ``` %% Cell type:code id:8eeb40d0 tags: ``` python def decoder(A, encoded_matrix, list_dic, bins, use_diff): """ This function decodes the encoded_matrix. Input: A (3 X 3): system of equation list_dic (num_dic + 1,): a list of huffman coding table encoded_matrix (512, 640): encoded matrix bins (num_bins - 1,): a list of threshold to cut the bins Return: decode_matrix (512, 640): decoded matrix """ # change the dictionary back to list # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins the_keys0 = list(list_dic[0].keys()) the_values0 = list(list_dic[0].values()) the_keys1 = list(list_dic[1].keys()) the_values1 = list(list_dic[1].values()) the_keys2 = list(list_dic[2].keys()) the_values2 = list(list_dic[2].values()) the_keys3 = list(list_dic[3].keys()) the_values3 = list(list_dic[3].values()) the_keys4 = list(list_dic[4].keys()) the_values4 = list(list_dic[4].values()) #Matrix system of points that will be used to solve the least squares fitting hyperplane points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]]) decode_matrix = np.zeros((512,640)) # loop through all the element in the matrix for i in range(decode_matrix.shape[0]): for j in range(decode_matrix.shape[1]): # if it's the very first pixel on the image if i == 0 and j == 0: decode_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) # if it's on the boundary elif i == 0 or i == decode_matrix.shape[0]-1 or j == 0 or j == decode_matrix.shape[1]-1: decode_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) + decode_matrix[0][0] # if not the boundary else: # predict the image with the known pixel value z0 = decode_matrix[i-1][j-1] z1 = decode_matrix[i-1][j] z2 = decode_matrix[i-1][j+1] z3 = decode_matrix[i][j-1] y0 = int(-z0+z2-z3) y1 = int(z0+z1+z2) y2 = int(-z0-z1-z2-z3) y = np.vstack((y0,y1,y2)) if use_diff: difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3) else: f, difference, rank, s = la.lstsq(points, [z0,z1,z2,z3], rcond=None) difference = difference.astype(int) predict = np.round(np.round(np.linalg.solve(A,y)[-1][0],1)) # add on the difference by searching the dictionary # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins if difference <= bins[0]: decode_matrix[i][j] = int(the_keys1[the_values1.index(encoded_matrix[i,j])]) + int(predict) elif difference <= bins[1] and difference > bins[0]: decode_matrix[i][j] = int(the_keys2[the_values2.index(encoded_matrix[i,j])]) + int(predict) elif difference <= bins[2] and difference > bins[1]: decode_matrix[i][j] = int(the_keys3[the_values3.index(encoded_matrix[i,j])]) + int(predict) else: decode_matrix[i][j] = int(the_keys4[the_values4.index(encoded_matrix[i,j])]) + int(predict) return decode_matrix.astype(int) ``` %% Cell type:code id:f959fe93 tags: ``` python def compress_rate(image, new_error, diff, bound, list_dic, bins): def compress_rate(image_array, new_error, diff, bound, huffman_encoding_list, bins): ''' This function is used to calculate the compression rate. Input: image (512, 640): original image image_array (512, 640): original_core image new_error (512, 640): error that includes the boundary diff (510, 638): difference of min and max of the 4 neighbors bound (2300,): the boundary values after subtracting the very first pixel value list_dic (num_dic + 1,): a list of huffman coding table huffman_encoding_list (num_dic + 1,): a list of huffman coding table bins (num_bins - 1,): a list of threshold to cut the bins Return: compression rate ''' # the bits for the original image o_len = 0 # the bits for the compressed image c_len = 0 # initializing the varible im = np.reshape(image,(512, 640)) real_b = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1])) original = image[1:-1,1:-1].reshape(-1) #this was unused # im = np.reshape(image,(512, 640)) real_boundary = np.hstack((image_array[0,:],image_array[-1,:],image_array[1:-1,0],image_array[1:-1,-1])) #Bryce's notes: Why are they all reshaped? original_core = image_array[1:-1,1:-1].reshape(-1) diff = diff.reshape(-1) error = new_error[1:-1,1:-1].reshape(-1) # calculate the bit for boundary for i in range(0,len(bound)): o_len += len(bin(real_b[i])[2:]) c_len += len(list_dic[0][str(bound[i])]) o_len += len(bin(real_boundary[i])[2:]) c_len += len(huffman_encoding_list[0][str(bound[i])]) # calculate the bit for the pixels inside the boundary for i in range(0,len(original)): for i in range(0,len(original_core)): # for the original image o_len += len(bin(original[i])[2:]) o_len += len(bin(original_core[i])[2:]) # check the difference and find the coresponding huffman table # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins if diff[i] <= bins[0]: c_len += len(list_dic[1][str(int(error[i]))]) c_len += len(huffman_encoding_list[1][str(int(error[i]))]) elif diff[i] <= bins[1] and diff[i] > bins[0]: c_len += len(list_dic[2][str(int(error[i]))]) c_len += len(huffman_encoding_list[2][str(int(error[i]))]) elif diff[i] <= bins[2] and diff[i] > bins[1]: c_len += len(list_dic[3][str(int(error[i]))]) c_len += len(huffman_encoding_list[3][str(int(error[i]))]) else: c_len += len(list_dic[4][str(int(error[i]))]) c_len += len(huffman_encoding_list[4][str(int(error[i]))]) return c_len/o_len ``` %% Cell type:code id:3e0e9742 tags: ``` python scenes = file_extractor() images = image_extractor(scenes) list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4, False) encoded_matrix = encoder(new_error, list_dic, diff, bound, bins) reconstruct_image = decoder(A, encoded_matrix, list_dic, bins, False) print(np.allclose(image, reconstruct_image)) print(len(list_dic)) ``` %% Output LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL-411 R-321 R-315 R-286 R-281 R-289 R-256 R-229 R-194 R-142 R-238 R-234 R-219 R-255 R-214 R-151 R-259 R-252 R-114 R-147 R-117 R-191 R-163 R-38 R-469 R-426 R-537 R-541 R-521 R-530 R-526 R-497 R-483 R-491 R-466 R-442 R-455 R-487 R-451 R-480 R-489 R-508 R-493 R-495 R-512 R-506 R-482 R-474 R-505 R-488 R-523 R-445 R-397 R-399 R-387 R-369 R-348 R-360 R-361 R-401 R-416 R-65 R148 R172 R189 R190 R209 R114 R111 R-241 R-213 R-143 R-107 R-44 R-334 R-371 R-317 R-352 R-240 R-66 R-92 R108 R120 R129 R144 R171 R166 R163 R175 R216 R196 R146 R140 R138 R150 R149 R145 R121 R112 R-27 R-77 R-75 R-251 R-294 R-356 R-279 R-290 R-193 R-167 R-274 R-354 R-389 R-454 R-380 R-370 R-305 R-326 R-407 R-398 R-372 R-362 R-414 R-424 R-452 R-383 R-324 R-331 R-381 R-346 R-420 R-409 R-453 R-450 R-460 R-449 R-458 R-42 R118 R104 R103 R22275 R-275 R-216 R-260 R-177 R-168 R-172 R-150 R-253 R-123 R-112 R-139 R-118 R-115 R-468 R-494 R-476 R-496 R-514 R-529 R-486 R-440 R-296 R-276 R-267 R-178 R-124 R-119 R-71 R-415 R-418 R-384 R-344 R-332 R-306 R-242 R-269 R-302 R-330 R-309 R-231 R-248 R-64 R-80 R-250 R-95 R126 R127 R-88 R-162 R-109 R-78 R-83 R-233 R-209 R-204 R-170 R-93 R-122 R-179 R-293 R-295 R-261 R-291 R-277 R-257 R-220 R-226 R-208 R-235 R-243 R-338 R-311 R-301 R-135 R-244 R-323 R-349 R-385 R-421 R-425 R-378 R-390 R-417 R-405 R-461 R-403 R-358 R-340 R-413 R-393 R-400 R-428 R-447 R-463 R-473 R-419 R-434 R-457 R-436 R-446 R-439 R-79 R-60 R-49 R-8 R-48 R-10 R-41 R102 R132 R96 R117 R113 R110 R115 R116 R105 R94 R-37 R-200 R-99 R-478 R-392 R-101 R-24 R-34 R-287 R-136 R-76 R-343 R-310 R-271 R-237 R-145 R-62 R-106 R182 R101 R106 R-84 R-81 R-152 R-222 R-120 R-264 R-206 R-131 R-113 R-96 R-108 R-134 R-258 R-266 R-299 R-239 R-307 R-304 R-284 R-297 R-249 R-196 R-199 R-186 R-265 R-230 R-138 R-192 R-236 R-245 R-273 R-254 R-298 R-337 R-373 R-365 R-345 R-319 R-313 R-335 R-320 R-410 R-443 R-432 R-477 R-444 R-437 R-435 R-57 R-128 R-102 R-61 R-94 R-73 R-68 R-70 R-30 R-51 R-74 R24 R91 R109 R107 R93 R-25 R-1 R-40 R-45 R-182 R-153 R-188 R-197 R-133 R-22 R-329 R-347 R-333 R-189 R-184 R-175 R-171 R-169 R-54 R-121 R-72 R-159 R-82 R-98 R-58 R-246 R-125 R-89 R-90 R-97 R-223 R-282 R-272 R-210 R-164 R-180 R-232 R-225 R-205 R-116 R-154 R-263 R-280 R-314 R-429 R-359 R-422 R-412 R-430 R-53 R-46 R-110 R-59 R-87 R-105 R47 R37 R-18 R-26 R21 R-23 R40 R124 R-47 R-33 R-14 R-56 R-39 R-28 R-16 R-31 R-100 R-85 R-140 R-165 R-155 R-104 R-176 R-312 R-268 R-198 R-195 R-174 R-221 R-146 R-217 R-247 R-308 R-318 R-341 R-325 R-408 R-406 R-55 R-36 R3 R-50 R18 R35 R14 R-32 R1 R89 R95 R100 R-21 R-3 R-43 R-149 R-351 R-173 R-91 R-207 R-157 R-127 R-160 R-218 R-212 R-148 R-203 R-224 R-215 R-126 R-202 R-339 R-355 R-7 R-67 R-69 R-63 R-86 R48 R-5 R59 R86 R76 R81 R99 R49 R-13 R-20 R-9 R-19 R13 R39 R-185 R-166 R-158 R-156 R-144 R-130 R-111 R-201 R-227 R-161 R-132 R-187 R-29 R-52 R5 R7 R15 R57 R45 R51 R26 R97 R64 R67 R98 R87 R46 R4 R-17 R-11 R-15 R38 R17 R-211 R-190 R-137 R8 R55 R62 R72 R74 R19 R52 R-35 R-141 R-6 R27 R2 R42 R-4 R30 R28 R41 R78 R43 R22 R0 R32 R85 R88 R66 R79 R80 R92 R77 R58 R34 R12 R11 R53 R-12 R-2 R6 R33 R10 R-183 R16 R29 R36 R90 R84 R75 R68 R56 R44 R50 R61 R60 R63 R20 R73 R23 R-181 R69 R82 R9 R54 R70 R65 R83 R25 R71 R31 True 5 %% Cell type:code id:004e8ba8 tags: ``` python compress_rate(image, new_error, diff, bound, list_dic, bins) ``` %% Output 2.090535888671875 0.4232928466796875 %% Cell type:code id:a282f9e6 tags: ``` python print(sys.getsizeof(encoded_matrix)) print(sys.getsizeof(reconstruct_image)) ``` %% Output 2621552 2621552 %% Cell type:code id:7efe26b9 tags: ``` python ```