Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
image-compression
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Elphel
image-compression
Commits
1e1a4ced
Commit
1e1a4ced
authored
Apr 14, 2022
by
Kelly Chang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kelly changes
parent
829e9198
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
667 additions
and
204 deletions
+667
-204
Encoding_decoding-checkpoint.ipynb
.ipynb_checkpoints/Encoding_decoding-checkpoint.ipynb
+241
-111
Compression_Rate_Kelly.ipynb
Compression_Rate_Kelly.ipynb
+333
-32
Encoding_decoding.ipynb
Encoding_decoding.ipynb
+93
-61
No files found.
.ipynb_checkpoints/Encoding_decoding-checkpoint.ipynb
View file @
1e1a4ced
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
"cells": [
"cells": [
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 1,
"execution_count": 1
2
,
"id": "14f74f21",
"id": "14f74f21",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
2
,
"execution_count":
13
,
"id": "c16af61f",
"id": "c16af61f",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -33,7 +33,10 @@
...
@@ -33,7 +33,10 @@
" files = os.listdir(dirname)\n",
" files = os.listdir(dirname)\n",
" scenes = []\n",
" scenes = []\n",
" for file in files:\n",
" for file in files:\n",
" scenes.append(os.path.join(dirname, file))\n",
" if file == '.DS_Store':\n",
" continue\n",
" else:\n",
" scenes.append(os.path.join(dirname, file))\n",
" return scenes\n",
" return scenes\n",
"\n",
"\n",
"def image_extractor(scenes):\n",
"def image_extractor(scenes):\n",
...
@@ -41,16 +44,12 @@
...
@@ -41,16 +44,12 @@
" for scene in scenes:\n",
" for scene in scenes:\n",
" files = os.listdir(scene)\n",
" files = os.listdir(scene)\n",
" for file in files:\n",
" for file in files:\n",
" image_folder.append(os.path.join(scene, file))\n",
" #if file[-4:] == \".jp4\" or file[-7:] == \"_6.tiff\":\n",
" images = []\n",
" if file[-5:] != \".tiff\" or file[-7:] == \"_6.tiff\":\n",
" for folder in image_folder:\n",
" ims = os.listdir(folder)\n",
" for im in ims:\n",
" if im[-4:] == \".jp4\" or im[-7:] == \"_6.tiff\":\n",
" continue\n",
" continue\n",
" else:\n",
" else:\n",
" image
s.append(os.path.join(folder, im
))\n",
" image
_folder.append(os.path.join(scene, file
))\n",
" return image
s
#returns a list of file paths to .tiff files in the specified directory given in file_extractor\n",
" return image
_folder
#returns a list of file paths to .tiff files in the specified directory given in file_extractor\n",
"\n",
"\n",
"def im_distribution(images, num):\n",
"def im_distribution(images, num):\n",
" \"\"\"\n",
" \"\"\"\n",
...
@@ -79,23 +78,39 @@
...
@@ -79,23 +78,39 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
3
,
"execution_count":
14
,
"id": "aceba613",
"id": "aceba613",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"def plot_hist(tiff_list):\n",
"def predict_pix(tiff_image):\n",
" \"\"\"\n",
" This function is the leftovers from the first attempt to plot histograms.\n",
" As it stands it needs some work in order to function again. We will\n",
" fix this later. 1/25/22\n",
" \"\"\"\n",
" \"\"\"\n",
" This function predict the pixel values excluding the boundary.\n",
" Using the 4 neighbor pixel values and MSE to predict the next pixel value\n",
" (-1,1) (0,1) (1,1) => relative position of the 4 other given values\n",
" (-1,0) (0,0) => (0,0) is the one we want to predict\n",
" take the derivative of mean square error to solve for the system of equation \n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]])\n",
" 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)\n",
" and the predicted pixel value is c.\n",
" \n",
" Input:\n",
" tiff_image (string): path to the tiff file\n",
" \n",
" \n",
" image = tiff_list\n",
" Return:\n",
" image = Image.open(image) #Open the image and read it as an Image object\n",
" image (512 X 640): original image \n",
" predict (325380,): predicted image exclude the boundary\n",
" diff. (325380,): difference between the min and max of four neighbors exclude the boundary\n",
" error (325380,): difference between the original image and predicted image\n",
" A (3 X 3): system of equation\n",
" \"\"\"\n",
" image = Image.open(tiff_image) #Open the image and read it as an Image object\n",
" image = np.array(image)[1:,:] #Convert to an array, leaving out the first row because the first row is just housekeeping data\n",
" image = np.array(image)[1:,:] #Convert to an array, leaving out the first row because the first row is just housekeeping data\n",
" image = image.astype(int)\n",
" image = image.astype(int)\n",
" print(image.shape)\n",
" # use \n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation\n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation\n",
" # where z0 = (-1,1), z1 = (0,1), z2 = (1,1), z3 = (-1,0)\n",
" z0 = image[0:-2,0:-2] # get all the first pixel for the entire image\n",
" z0 = image[0:-2,0:-2] # get all the first pixel for the entire image\n",
" z1 = image[0:-2,1:-1] # get all the second pixel for the entire image\n",
" z1 = image[0:-2,1:-1] # get all the second pixel for the entire image\n",
" z2 = image[0:-2,2::] # get all the third pixel for the entire image\n",
" z2 = image[0:-2,2::] # get all the third pixel for the entire image\n",
...
@@ -106,7 +121,8 @@
...
@@ -106,7 +121,8 @@
" y2 = np.ravel(-z0-z1-z2-z3)\n",
" y2 = np.ravel(-z0-z1-z2-z3)\n",
" y = np.vstack((y0,y1,y2))\n",
" y = np.vstack((y0,y1,y2))\n",
" # use numpy solver to solve the system of equations all at once\n",
" # use numpy solver to solve the system of equations all at once\n",
" predict = np.floor(np.linalg.solve(A,y)[-1])\n",
" #predict = np.floor(np.linalg.solve(A,y)[-1])\n",
" predict = np.round(np.round((np.linalg.solve(A,y)[-1]),1))\n",
" # flatten the neighbor pixlels and stack them together\n",
" # flatten the neighbor pixlels and stack them together\n",
" z0 = np.ravel(z0)\n",
" z0 = np.ravel(z0)\n",
" z1 = np.ravel(z1)\n",
" z1 = np.ravel(z1)\n",
...
@@ -115,21 +131,24 @@
...
@@ -115,21 +131,24 @@
" neighbor = np.vstack((z0,z1,z2,z3)).T\n",
" neighbor = np.vstack((z0,z1,z2,z3)).T\n",
" # calculate the difference\n",
" # calculate the difference\n",
" diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n",
" diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n",
" # calculate the error\n",
" error = np.ravel(image[1:-1,1:-1])-predict\n",
" \n",
" \n",
" # flatten the image to a vector\n",
" return image, predict, diff, error, A\n"
" image = np.ravel(image[1:-1,1:-1])\n",
" error = image-predict\n",
" \n",
" return image, predict, diff, error, A"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
4
,
"execution_count":
15
,
"id": "6b965751",
"id": "6b965751",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"\"\"\"\n",
"this huffman coding code is found online\n",
"https://favtutor.com/blogs/huffman-coding\n",
"\"\"\"\n",
"\n",
"class NodeTree(object):\n",
"class NodeTree(object):\n",
" def __init__(self, left=None, right=None):\n",
" def __init__(self, left=None, right=None):\n",
" self.left = left\n",
" self.left = left\n",
...
@@ -173,65 +192,97 @@
...
@@ -173,65 +192,97 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
5
,
"execution_count":
24
,
"id": "b7561883",
"id": "b7561883",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"def huffman(image):\n",
"def huffman(image, num_bins=4):\n",
" origin, predict, diff, error, A = plot_hist(image)\n",
" \"\"\"\n",
" This function is used to encode the error based on the difference\n",
" and split the difference into different bins\n",
" \n",
" \n",
"
image = Image.open(image)
\n",
"
Input:
\n",
" image
= np.array(image)[1:,:] #Convert to an array, leaving out the first row because the first row is just housekeeping data
\n",
" image
(string): path to the tiff file
\n",
"
image = image.astype(int)
\n",
"
num_bins (int): number of bins
\n",
" \n",
" \n",
"
boundary = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1]))
\n",
"
Return:
\n",
"
boundary = boundary - image[0,0]
\n",
"
list_dic (num_bins + 1): a list of dictionary
\n",
"
boundary[0] = image[0,0]
\n",
"
image (512, 640): original image
\n",
"\n",
"
new_error (512, 640): error that includes the boundary
\n",
"
string = [str(i) for i in boundary]
\n",
"
diff (510, 638): difference of min and max of the 4 neighbors
\n",
"
freq = dict(Counter(string))
\n",
"
boundary (2300,): the boundary values after subtracting the very first pixel value
\n",
"
freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)
\n",
"
predict (325380,): the list of predicted values
\n",
"
node = make_tree(freq
)\n",
"
bins (num_bins
)\n",
"
encode1 = huffman_code_tree(node)
\n",
"
A (3 X 3): system of equation
\n",
" \n",
" \n",
" \"\"\"\n",
" # get the prediction error and difference\n",
" image, predict, diff, error, A = predict_pix(image)\n",
" \n",
" \n",
" mask = diff <= 25\n",
" # get the number of points in each bins\n",
" string = [str(i) for i in error[mask].astype(int)]\n",
" data_points_per_bin = len(diff) // num_bins\n",
" freq = dict(Counter(string))\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" node = make_tree(freq)\n",
" encode2 = huffman_code_tree(node)\n",
"\n",
" \n",
" \n",
" mask = diff > 25\n",
" # sort the difference and create the bins\n",
" new_error = error[mask]\n",
" sorted_diff = diff.copy()\n",
" mask2 = diff[mask] <= 40\n",
" sorted_diff.sort()\n",
" string = [str(i) for i in new_error[mask2].astype(int)]\n",
" bins = [sorted_diff[i*data_points_per_bin] for i in range(1,num_bins)]\n",
" freq = dict(Counter(string))\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" node = make_tree(freq)\n",
" encode3 = huffman_code_tree(node)\n",
" \n",
" \n",
"\n",
" # get the boundary \n",
" mask = diff > 40\n",
" boundary = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1]))\n",
" new_error = error[mask]\n",
" \n",
" mask2 = diff[mask] <= 70\n",
" # take the difference of the boundary with the very first pixel\n",
" string = [str(i) for i in new_error[mask2].astype(int)]\n",
" boundary = boundary - image[0,0]\n",
" boundary[0] = image[0,0]\n",
" \n",
" # huffman encode the boundary\n",
" string = [str(i) for i in boundary]\n",
" freq = dict(Counter(string))\n",
" freq = dict(Counter(string))\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" node = make_tree(freq)\n",
" node = make_tree(freq)\n",
" encode
4
= huffman_code_tree(node)\n",
" encode = huffman_code_tree(node)\n",
" \n",
" \n",
" # create a list of huffman table\n",
" list_dic = [encode]\n",
" n = len(bins)\n",
" \n",
" \n",
" mask = diff > 70\n",
" # loop through different bins\n",
" for i in range (0,n):\n",
" # the fisrt bin\n",
" if i == 0 :\n",
" # get the point within the bin and huffman encode\n",
" mask = diff <= bins[i]\n",
" string = [str(i) for i in error[mask].astype(int)]\n",
" freq = dict(Counter(string))\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" node = make_tree(freq)\n",
" encode = huffman_code_tree(node)\n",
" list_dic.append(encode)\n",
" \n",
" # the middle bins\n",
" else:\n",
" # get the point within the bin and huffman encode\n",
" mask = diff > bins[i-1]\n",
" new_error = error[mask]\n",
" mask2 = diff[mask] <= bins[i]\n",
" string = [str(i) for i in new_error[mask2].astype(int)]\n",
" freq = dict(Counter(string))\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" node = make_tree(freq)\n",
" encode = huffman_code_tree(node)\n",
" list_dic.append(encode)\n",
" \n",
" # the last bin \n",
" # get the point within the bin and huffman encode\n",
" mask = diff > bins[-1]\n",
" string = [str(i) for i in error[mask].astype(int)]\n",
" string = [str(i) for i in error[mask].astype(int)]\n",
" freq = dict(Counter(string))\n",
" freq = dict(Counter(string))\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)\n",
" node = make_tree(freq)\n",
" node = make_tree(freq)\n",
" encode
5
= huffman_code_tree(node)\n",
" encode = huffman_code_tree(node)\n",
"\n",
"
list_dic.append(encode)
\n",
"\n",
"\n",
" # create a error matrix that includes the boundary (used in encoding matrix)\n",
" new_error = np.copy(image)\n",
" new_error = np.copy(image)\n",
" new_error[1:-1,1:-1] = np.reshape(error,(510, 638))\n",
" new_error[1:-1,1:-1] = np.reshape(error,(510, 638))\n",
" keep = new_error[0,0]\n",
" keep = new_error[0,0]\n",
...
@@ -241,31 +292,24 @@
...
@@ -241,31 +292,24 @@
" new_error[1:-1,-1] = new_error[1:-1,-1] - keep\n",
" new_error[1:-1,-1] = new_error[1:-1,-1] - keep\n",
" new_error[0,0] = keep\n",
" new_error[0,0] = keep\n",
" \n",
" \n",
" \n",
" diff = np.reshape(diff,(510,638))\n",
" #new_error = np.ravel(new_error)\n",
" \n",
" bins = [25,40,70]\n",
" \n",
" # return the huffman dictionary\n",
" # return the huffman dictionary\n",
" return encode1, encode2, encode3, encode4, encode5, np.ravel(image), error, new_error, diff, boundary, bins\n",
" return list_dic, image, new_error, diff, boundary, predict, bins, A\n",
" \n",
" \n"
"scenes = file_extractor()\n",
"images = image_extractor(scenes)\n",
"encode1, encode2, encode3, encode4, encode5, image, error, new_error, diff, boundary, bins = huffman(images[0])"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
6
,
"execution_count":
17
,
"id": "2eb774d2",
"id": "2eb774d2",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"def encoder(error, list_dic, diff, bound, bins):\n",
"def encoder(error, list_dic, diff, bound, bins):\n",
" # copy the error matrix (including the boundary)\n",
" encoded = np.copy(error).astype(int).astype(str).astype(object)\n",
" encoded = np.copy(error).astype(int).astype(str).astype(object)\n",
" \n",
" #diff = np.reshape(diff,(510,638))\n",
" diff = np.reshape(diff,(510,638))\n",
" # loop through all the pixel to encode\n",
" \n",
" for i in range(encoded.shape[0]):\n",
" for i in range(encoded.shape[0]):\n",
" for j in range(encoded.shape[1]):\n",
" for j in range(encoded.shape[1]):\n",
" if i == 0 or i == encoded.shape[0]-1 or j == 0 or j == encoded.shape[1]-1:\n",
" if i == 0 or i == encoded.shape[0]-1 or j == 0 or j == encoded.shape[1]-1:\n",
...
@@ -279,85 +323,171 @@
...
@@ -279,85 +323,171 @@
" else: \n",
" else: \n",
" encoded[i][j] = list_dic[4][encoded[i][j]]\n",
" encoded[i][j] = list_dic[4][encoded[i][j]]\n",
"\n",
"\n",
" \n",
" return encoded"
" return encoded"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
7
,
"execution_count":
23
,
"id": "8eeb40d0",
"id": "8eeb40d0",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"def decoder(A, encoded_matrix,
encoding_dict
):\n",
"def decoder(A, encoded_matrix,
list_dic, bins
):\n",
" \"\"\"\n",
" \"\"\"\n",
" Function that accecpts the prediction matrix A for the linear system,\n",
" Function that accecpts the prediction matrix A for the linear system,\n",
" the encoded matrix of error values, and the encoding dicitonary.\n",
" the encoded matrix of error values, and the encoding dicitonary.\n",
" \"\"\"\n",
" \"\"\"\n",
" the_keys = list(encode_dict.keys())\n",
" # change the dictionary back to list\n",
" the_values = list(encode_dict.values())\n",
" # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
" error_matrix = encoded_matrix.copy()\n",
" the_keys0 = list(list_dic[0].keys())\n",
" the_values0 = list(list_dic[0].values())\n",
" \n",
" the_keys1 = list(list_dic[1].keys())\n",
" the_values1 = list(list_dic[1].values())\n",
" \n",
" the_keys2 = list(list_dic[2].keys())\n",
" the_values2 = list(list_dic[2].values())\n",
" \n",
" the_keys3 = list(list_dic[3].keys())\n",
" the_values3 = list(list_dic[3].values())\n",
" \n",
" \n",
" the_keys4 = list(list_dic[4].keys())\n",
" the_values4 = list(list_dic[4].values())\n",
" \n",
" error_matrix = np.zeros((512,640))\n",
" # loop through all the element in the matrix\n",
" for i in range(error_matrix.shape[0]):\n",
" for i in range(error_matrix.shape[0]):\n",
" for j in range(error_matrix.shape[1]):\n",
" for j in range(error_matrix.shape[1]):\n",
" # if it's the very first pixel on the image\n",
" if i == 0 and j == 0:\n",
" if i == 0 and j == 0:\n",
" error_matrix[i][j] = int(the_keys
[the_values.index(error
_matrix[i,j])])\n",
" error_matrix[i][j] = int(the_keys
0[the_values0.index(encoded
_matrix[i,j])])\n",
"
\n",
"
# if it's on the boundary
\n",
" elif i == 0 or i == error_matrix.shape[0]-1 or j == 0 or j == error_matrix.shape[1]-1:\n",
" elif i == 0 or i == error_matrix.shape[0]-1 or j == 0 or j == error_matrix.shape[1]-1:\n",
" error_matrix[i][j] = int(the_keys[the_values.index(error_matrix[i,j])]) + error_matrix[0][0]\n",
" error_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) + error_matrix[0][0]\n",
" # if not the boundary\n",
" else:\n",
" else:\n",
" \"\"\"z0, z1, z2, z3 = error_matrix[i-1][j-1], error_matrix[i-1][j], \\\n",
" # predict the image with the known pixel value\n",
" error_matrix[i-1][j+1], error_matrix[i][j-1]\n",
" z0 = error_matrix[i-1][j-1]\n",
" y = np.vstack((-z0+z2-z3, z0+z1+z2, -z0-z1-z2-z3))\"\"\"\n",
" z1 = error_matrix[i-1][j]\n",
" z2 = error_matrix[i-1][j+1]\n",
" z3 = error_matrix[i][j-1]\n",
" y0 = int(-z0+z2-z3)\n",
" y1 = int(z0+z1+z2)\n",
" y2 = int(-z0-z1-z2-z3)\n",
" y = np.vstack((y0,y1,y2))\n",
" difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3)\n",
" predict = np.round(np.round(np.linalg.solve(A,y)[-1][0],1))\n",
" \n",
" # add on the difference by searching the dictionary\n",
" # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
" if difference <= bins[0]:\n",
" error_matrix[i][j] = int(the_keys1[the_values1.index(encoded_matrix[i,j])]) + int(predict)\n",
" elif difference <= bins[1] and difference > bins[0]:\n",
" error_matrix[i][j] = int(the_keys2[the_values2.index(encoded_matrix[i,j])]) + int(predict)\n",
" elif difference <= bins[2] and difference > bins[1]:\n",
" error_matrix[i][j] = int(the_keys3[the_values3.index(encoded_matrix[i,j])]) + int(predict)\n",
" else:\n",
" error_matrix[i][j] = int(the_keys4[the_values4.index(encoded_matrix[i,j])]) + int(predict)\n",
" \n",
" \n",
" error_matrix[i][j] = int(the_keys[the_values.index(error_matrix[i,j])])\n",
" \n",
" \n",
" return error_matrix.astype(int)"
" return error_matrix.astype(int)"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
8
,
"execution_count":
19
,
"id": "
3e0e9742
",
"id": "
f959fe93
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"encode1, encode2, encode3, encode4, encode5, image, error, new_error, diff, bound, bins = huffman(images[0])\n",
"def compress_rate(image, error, diff, bound, list_dic, bins):\n",
"encoded_matrix = encoder(np.reshape(new_error,(512,640)), [encode1, encode2, encode3, encode4, encode5], diff, bound, bins)\n",
" # the bits for the original image\n",
"\n"
" o_len = 0\n",
" # the bits for the compressed image\n",
" c_len = 0\n",
" # initializing the varible \n",
" im = np.reshape(image,(512, 640))\n",
" real_b = np.hstack((im[0,:],im[-1,:],im[1:-1,0],im[1:-1,-1]))\n",
" original = im[1:-1,1:-1].reshape(-1)\n",
" diff = diff.reshape(-1)\n",
" \n",
" # calculate the bit for boundary\n",
" for i in range(0,len(bound)):\n",
" o_len += len(bin(real_b[i])[2:])\n",
" c_len += len(list_dic[0][str(bound[i])])\n",
" \n",
" # calculate the bit for the pixels inside the boundary\n",
" for i in range(0,len(original)):\n",
" # for the original image\n",
" o_len += len(bin(original[i])[2:])\n",
" \n",
" # check the difference and find the coresponding huffman table\n",
" # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
" if diff[i] <= bins[0]:\n",
" c_len += len(list_dic[1][str(int(error[i]))])\n",
" \n",
" elif diff[i] <= bins[1] and diff[i] > bins[0]:\n",
" c_len += len(list_dic[2][str(int(error[i]))])\n",
" \n",
" elif diff[i] <= bins[2] and diff[i] > bins[1]:\n",
" c_len += len(list_dic[3][str(int(error[i]))])\n",
"\n",
" else: \n",
" c_len += len(list_dic[5][str(int(error[i]))])\n",
"\n",
" return c_len/o_len"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "3e0e9742",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(512, 640)\n",
"True\n",
"5\n"
]
}
],
"source": [
"scenes = file_extractor()\n",
"images = image_extractor(scenes)\n",
"list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4)\n",
"encoded_matrix = encoder(new_error, list_dic, diff, bound, bins)\n",
"reconstruct_image = decoder(A, encoded_matrix, list_dic, bins)\n",
"print(np.allclose(image, reconstruct_image))\n",
"print(len(list_dic))"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
9
,
"execution_count":
32
,
"id": "
e6ea4f99
",
"id": "
004e8ba8
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
"name": "stdout",
"name": "stdout",
"output_type": "stream",
"output_type": "stream",
"text": [
"text": [
"[['01100010001' '11000110' '100101010' ... '101110011' '00010100'\n",
"[26, 40, 62]\n"
" '1111000100']\n",
" ['10011100' '100001' '111000' ... '10111011' '00111' '1111001101']\n",
" ['10101111' '100100' '100000' ... '111100' '111000' '00010100']\n",
" ...\n",
" ['110001000' '100001' '111011' ... '1010010' '100000' '10011000']\n",
" ['0100011101' '111010' '00110' ... '1000101' '1100100' '10011010']\n",
" ['00100010' '110111101' '110110100' ... '00010010' '10100000'\n",
" '110110101']]\n"
]
]
}
}
],
],
"source": [
"source": [
"print(encoded_matrix)"
"\n",
"print(bins)"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"id": "
0c07a23e
",
"id": "
a282f9e6
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": []
"source": []
...
@@ -379,7 +509,7 @@
...
@@ -379,7 +509,7 @@
"name": "python",
"name": "python",
"nbconvert_exporter": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"pygments_lexer": "ipython3",
"version": "3.
8.1
1"
"version": "3.
9.
1"
}
}
},
},
"nbformat": 4,
"nbformat": 4,
...
...
Compression_Rate_Kelly.ipynb
View file @
1e1a4ced
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
"cells": [
"cells": [
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
null
,
"execution_count":
1
,
"id": "8868bc30",
"id": "8868bc30",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -20,12 +20,13 @@
...
@@ -20,12 +20,13 @@
"import pandas as pd\n",
"import pandas as pd\n",
"from collections import Counter\n",
"from collections import Counter\n",
"import time\n",
"import time\n",
"import numpy.linalg as la"
"import numpy.linalg as la\n",
"from scipy.stats import entropy"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
null
,
"execution_count":
2
,
"id": "0f944705",
"id": "0f944705",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -88,7 +89,7 @@
...
@@ -88,7 +89,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
null
,
"execution_count":
3
,
"id": "b18d5e38",
"id": "b18d5e38",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -137,7 +138,7 @@
...
@@ -137,7 +138,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
200
,
"execution_count":
4
,
"id": "3b0c3eaa",
"id": "3b0c3eaa",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -182,7 +183,7 @@
...
@@ -182,7 +183,7 @@
" \n",
" \n",
" # calculate the difference\n",
" # calculate the difference\n",
" #diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n",
" #diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n",
" diff = (np.max(neighbor,axis = 1)
*5
- np.min(neighbor, axis=1))\n",
" diff = (np.max(neighbor,axis = 1) - np.min(neighbor, axis=1))\n",
" \n",
" \n",
" # flatten the image to a vector\n",
" # flatten the image to a vector\n",
" #image = np.ravel(image[1:-1,1:-1])\n",
" #image = np.ravel(image[1:-1,1:-1])\n",
...
@@ -200,7 +201,7 @@
...
@@ -200,7 +201,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
152
,
"execution_count":
5
,
"id": "35d4f6a0",
"id": "35d4f6a0",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -246,9 +247,92 @@
...
@@ -246,9 +247,92 @@
" return nodes[0][0]"
" return nodes[0][0]"
]
]
},
},
{
"cell_type": "code",
"execution_count": 6,
"id": "9200fa53",
"metadata": {},
"outputs": [],
"source": [
"def encoder(error, list_dic, diff, bound, bins):\n",
" encoded = np.copy(error).astype(int).astype(str).astype(object)\n",
" \n",
" diff = np.reshape(diff,(510,638))\n",
" \n",
" for i in range(encoded.shape[0]):\n",
" for j in range(encoded.shape[1]):\n",
" if i == 0 or i == encoded.shape[0]-1 or j == 0 or j == encoded.shape[1]-1:\n",
" encoded[i][j] = list_dic[0][encoded[i][j]]\n",
" elif diff[i-1][j-1] <= bins[0]:\n",
" encoded[i][j] = list_dic[1][encoded[i][j]]\n",
" elif diff[i-1][j-1] <= bins[1] and diff[i-1][j-1] > bins[0]:\n",
" encoded[i][j] = list_dic[2][encoded[i][j]]\n",
" elif diff[i-1][j-1] <= bins[2] and diff[i-1][j-1] > bins[1]:\n",
" encoded[i][j] = list_dic[3][encoded[i][j]]\n",
" else: \n",
" encoded[i][j] = list_dic[4][encoded[i][j]]\n",
"\n",
" \n",
" return encoded\n",
"\n",
"def decoder(A, encoded_matrix, list_dic, bins):\n",
" \"\"\"\n",
" Function that accecpts the prediction matrix A for the linear system,\n",
" the encoded matrix of error values, and the encoding dicitonary.\n",
" \"\"\"\n",
"\n",
" the_keys0 = list(list_dic[0].keys())\n",
" the_values0 = list(list_dic[0].values())\n",
" \n",
" the_keys1 = list(list_dic[1].keys())\n",
" the_values1 = list(list_dic[1].values())\n",
" \n",
" the_keys2 = list(list_dic[2].keys())\n",
" the_values2 = list(list_dic[2].values())\n",
" \n",
" the_keys3 = list(list_dic[3].keys())\n",
" the_values3 = list(list_dic[3].values())\n",
" \n",
" the_keys4 = list(list_dic[4].keys())\n",
" the_values4 = list(list_dic[4].values())\n",
" \n",
" error_matrix = np.zeros((512,640))\n",
" \n",
" for i in range(error_matrix.shape[0]):\n",
" for j in range(error_matrix.shape[1]):\n",
" if i == 0 and j == 0:\n",
" error_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])])\n",
" \n",
" elif i == 0 or i == error_matrix.shape[0]-1 or j == 0 or j == error_matrix.shape[1]-1:\n",
" error_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) + error_matrix[0][0]\n",
" else:\n",
" z0 = error_matrix[i-1][j-1]\n",
" z1 = error_matrix[i-1][j]\n",
" z2 = error_matrix[i-1][j+1]\n",
" z3 = error_matrix[i][j-1]\n",
" y0 = int(-z0+z2-z3)\n",
" y1 = int(z0+z1+z2)\n",
" y2 = int(-z0-z1-z2-z3)\n",
" y = np.vstack((y0,y1,y2))\n",
" difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3)\n",
" predict = np.round(np.round(np.linalg.solve(A,y)[-1][0],1))\n",
"\n",
" if difference <= bins[0]:\n",
" error_matrix[i][j] = int(the_keys1[the_values1.index(encoded_matrix[i,j])]) + int(predict)\n",
" elif difference <= bins[1] and difference > bins[0]:\n",
" error_matrix[i][j] = int(the_keys2[the_values2.index(encoded_matrix[i,j])]) + int(predict)\n",
" elif difference <= bins[2] and difference > bins[1]:\n",
" error_matrix[i][j] = int(the_keys3[the_values3.index(encoded_matrix[i,j])]) + int(predict)\n",
" else:\n",
" error_matrix[i][j] = int(the_keys4[the_values4.index(encoded_matrix[i,j])]) + int(predict)\n",
" \n",
" \n",
" return error_matrix.astype(int)"
]
},
{
{
"cell_type": "markdown",
"cell_type": "markdown",
"id": "
25abd477
",
"id": "
ca9c0b4a
",
"metadata": {},
"metadata": {},
"source": [
"source": [
"## use res"
"## use res"
...
@@ -256,7 +340,7 @@
...
@@ -256,7 +340,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
154
,
"execution_count":
7
,
"id": "bd7e39d7",
"id": "bd7e39d7",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -436,29 +520,206 @@
...
@@ -436,29 +520,206 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
null
,
"execution_count":
10
,
"id": "
1b2e63e
2",
"id": "
d0a6fac
2",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[8, 32, 88, 181, 383]\n",
"7\n"
]
}
],
"source": [
"source": [
"scenes = file_extractor()\n",
"scenes = file_extractor()\n",
"images = image_extractor(scenes)\n",
"images = image_extractor(scenes)\n",
"rate = []\n",
"list_dic, image, error, new_error, diff, bound, predict, bins, res = huffman(images[0], 6, True)\n",
"A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]])\n",
"print(bins)\n",
"for i in range(len(images)):\n",
"print(len(list_dic))"
" list_dic, image, error, new_error, diff, bound, predict, bins, res = huffman(images[i], 6, True)\n",
]
" r = compress_rate(image, error, diff, bound, list_dic, bins, res, use_res = True)\n",
},
" rate.append(r)\n"
{
"cell_type": "code",
"execution_count": 232,
"id": "2723b062",
"metadata": {},
"outputs": [],
"source": [
"def rel_freq(x):\n",
" freqs = [x.count(value) / len(x) for value in set(x)] \n",
" return freqs"
]
},
{
"cell_type": "code",
"execution_count": 234,
"id": "e9799985",
"metadata": {},
"outputs": [],
"source": [
"list_diff = list(set(diff))\n",
"en = []\n",
"for i in list_diff:\n",
" mask = diff == i\n",
" list_error = list(error[mask])\n",
" fre = rel_freq(list_error)\n",
" \n",
" en.append(entropy(fre))"
]
},
{
"cell_type": "code",
"execution_count": 249,
"id": "78a370f7",
"metadata": {},
"outputs": [],
"source": [
"list_error = list(error)\n",
"ob = rel_freq(list_error)"
]
},
{
"cell_type": "code",
"execution_count": 271,
"id": "21ba29a6",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"n = len(bins)\n",
"for i in range (0,n):\n",
" if i == 0 :\n",
" mask = diff <= bins[i]\n",
" list_error = list(error[mask])\n",
" fre = rel_freq(list_error)\n",
" en.append(entropy(fre))\n",
" else:\n",
" mask = diff > bins[i-1]\n",
" error2 = error[mask]\n",
" mask2 = diff[mask] <= bins[i]\n",
" list_error = list(error2[mask2])\n",
" fre = rel_freq(list_error)\n",
" en.append(entropy(fre))\n",
"\n",
"mask = diff > bins[i]\n",
"list_error = list(error[mask])\n",
"fre = rel_freq(list_error)\n",
"en.append(entropy(fre))"
]
},
{
"cell_type": "code",
"execution_count": 272,
"id": "32a94ee7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.2688193009259807\n",
"0.21792128672839872\n"
]
}
],
"source": [
"print(np.mean(en))\n",
"print(np.mean(en)/15)"
]
},
{
"cell_type": "code",
"execution_count": 258,
"id": "51268478",
"metadata": {},
"outputs": [],
"source": [
"uni = np.unique(diff)\n",
"uni_n = len(np.unique(diff))\n",
"en = []\n",
"for i in range(uni_n):\n",
" mask = diff == uni[i]\n",
" mask_error = error[mask]\n",
" en.append(entropy(rel_freq(list(mask_error))))"
]
},
{
"cell_type": "code",
"execution_count": 266,
"id": "2d3238cb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.2532721868611105\n",
"6.715361332207255\n",
"15\n"
]
}
],
"source": [
"imm = np.ravel(image.reshape(512,640)[1:-1,1:-1])\n",
"print(np.mean(en))\n",
"print(entropy(rel_freq(list(imm))))\n",
"print(len(bin(imm[0])[2:]))"
]
},
{
"cell_type": "code",
"execution_count": 269,
"id": "811f8139",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.44766666666666666"
]
},
"execution_count": 269,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"6.715/15"
]
},
{
"cell_type": "code",
"execution_count": 270,
"id": "6470dfff",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.21666666666666667"
]
},
"execution_count": 270,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3.25/15"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"id": "
c2eaf807
",
"id": "
7a05f000
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"
print(f\"Compression rate of huffman with different bins in res: {np.mean(rate)}\")
"
"
## test compression rate and time
"
]
]
},
},
{
{
...
@@ -566,7 +827,7 @@
...
@@ -566,7 +827,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 94,
"execution_count": 94,
"id": "
7d1985a4
",
"id": "
9d5f9f50
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
...
@@ -591,7 +852,7 @@
...
@@ -591,7 +852,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 97,
"execution_count": 97,
"id": "b
898324e
",
"id": "b
ceeee73
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -615,7 +876,7 @@
...
@@ -615,7 +876,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 102,
"execution_count": 102,
"id": "
45b75db7
",
"id": "
5b02b4a3
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -637,10 +898,29 @@
...
@@ -637,10 +898,29 @@
"plt.show()"
"plt.show()"
]
]
},
},
{
"cell_type": "code",
"execution_count": 155,
"id": "2253908b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[46 26 8 ... 13 16 34]\n"
]
}
],
"source": [
"list_dic, image, error, new_error, diff, bound, predict, bins, res = huffman(images[22], 6, False)\n",
"r = compress_rate(image, error, diff, bound, list_dic, bins, res, False)"
]
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 108,
"execution_count": 108,
"id": "
55251c97
",
"id": "
88ed2a4e
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -673,7 +953,7 @@
...
@@ -673,7 +953,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 109,
"execution_count": 109,
"id": "
92d3ae31
",
"id": "
b0a58386
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
...
@@ -684,7 +964,7 @@
...
@@ -684,7 +964,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 110,
"execution_count": 110,
"id": "
4abd8b82
",
"id": "
1a913350
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -719,7 +999,7 @@
...
@@ -719,7 +999,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 111,
"execution_count": 111,
"id": "
07bb76a
7",
"id": "
6e9bc2e
7",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -734,10 +1014,31 @@
...
@@ -734,10 +1014,31 @@
"print(slope,intercept)"
"print(slope,intercept)"
]
]
},
},
{
"cell_type": "code",
"execution_count": 100,
"id": "8ccd4336",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([315196, 495220, 360208, ..., 748984, 340447, 885631])"
]
},
"execution_count": 100,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"new"
]
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 113,
"execution_count": 113,
"id": "
fca0420b
",
"id": "
689f98c0
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -770,7 +1071,7 @@
...
@@ -770,7 +1071,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 197,
"execution_count": 197,
"id": "
70285459
",
"id": "
b08d924b
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -794,7 +1095,7 @@
...
@@ -794,7 +1095,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 195,
"execution_count": 195,
"id": "
21b94965
",
"id": "
98c47af2
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -815,7 +1116,7 @@
...
@@ -815,7 +1116,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": 196,
"execution_count": 196,
"id": "
68eb383d
",
"id": "
3c37a08f
",
"metadata": {},
"metadata": {},
"outputs": [
"outputs": [
{
{
...
@@ -833,7 +1134,7 @@
...
@@ -833,7 +1134,7 @@
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"id": "3
fdebf92
",
"id": "3
ca79c1f
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": []
"source": []
...
...
Encoding_decoding.ipynb
View file @
1e1a4ced
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
"cells": [
"cells": [
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
63
,
"execution_count":
12
,
"id": "14f74f21",
"id": "14f74f21",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
64
,
"execution_count":
13
,
"id": "c16af61f",
"id": "c16af61f",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -78,23 +78,39 @@
...
@@ -78,23 +78,39 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
65
,
"execution_count":
14
,
"id": "aceba613",
"id": "aceba613",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"def plot_hist(tiff_list):\n",
"def predict_pix(tiff_image):\n",
" \"\"\"\n",
" This function is the leftovers from the first attempt to plot histograms.\n",
" As it stands it needs some work in order to function again. We will\n",
" fix this later. 1/25/22\n",
" \"\"\"\n",
" \"\"\"\n",
" This function predict the pixel values excluding the boundary.\n",
" Using the 4 neighbor pixel values and MSE to predict the next pixel value\n",
" (-1,1) (0,1) (1,1) => relative position of the 4 other given values\n",
" (-1,0) (0,0) => (0,0) is the one we want to predict\n",
" take the derivative of mean square error to solve for the system of equation \n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]])\n",
" 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)\n",
" and the predicted pixel value is c.\n",
" \n",
" Input:\n",
" tiff_image (string): path to the tiff file\n",
" \n",
" \n",
" image = tiff_list\n",
" Return:\n",
" image = Image.open(image) #Open the image and read it as an Image object\n",
" image (512 X 640): original image \n",
" predict (325380,): predicted image exclude the boundary\n",
" diff. (325380,): difference between the min and max of four neighbors exclude the boundary\n",
" error (325380,): difference between the original image and predicted image\n",
" A (3 X 3): system of equation\n",
" \"\"\"\n",
" image = Image.open(tiff_image) #Open the image and read it as an Image object\n",
" image = np.array(image)[1:,:] #Convert to an array, leaving out the first row because the first row is just housekeeping data\n",
" image = np.array(image)[1:,:] #Convert to an array, leaving out the first row because the first row is just housekeeping data\n",
" image = image.astype(int)\n",
" image = image.astype(int)\n",
" print(image.shape)\n",
" # use \n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation\n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation\n",
" # where z0 = (-1,1), z1 = (0,1), z2 = (1,1), z3 = (-1,0)\n",
" z0 = image[0:-2,0:-2] # get all the first pixel for the entire image\n",
" z0 = image[0:-2,0:-2] # get all the first pixel for the entire image\n",
" z1 = image[0:-2,1:-1] # get all the second pixel for the entire image\n",
" z1 = image[0:-2,1:-1] # get all the second pixel for the entire image\n",
" z2 = image[0:-2,2::] # get all the third pixel for the entire image\n",
" z2 = image[0:-2,2::] # get all the third pixel for the entire image\n",
...
@@ -118,16 +134,21 @@
...
@@ -118,16 +134,21 @@
" # calculate the error\n",
" # calculate the error\n",
" error = np.ravel(image[1:-1,1:-1])-predict\n",
" error = np.ravel(image[1:-1,1:-1])-predict\n",
" \n",
" \n",
" return image, predict, diff, error, A"
" return image, predict, diff, error, A
\n
"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
66
,
"execution_count":
15
,
"id": "6b965751",
"id": "6b965751",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"\"\"\"\n",
"this huffman coding code is found online\n",
"https://favtutor.com/blogs/huffman-coding\n",
"\"\"\"\n",
"\n",
"class NodeTree(object):\n",
"class NodeTree(object):\n",
" def __init__(self, left=None, right=None):\n",
" def __init__(self, left=None, right=None):\n",
" self.left = left\n",
" self.left = left\n",
...
@@ -171,14 +192,33 @@
...
@@ -171,14 +192,33 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
67
,
"execution_count":
24
,
"id": "b7561883",
"id": "b7561883",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": [
"source": [
"def huffman(image, num_bins):\n",
"def huffman(image, num_bins=4):\n",
" \"\"\"\n",
" This function is used to encode the error based on the difference\n",
" and split the difference into different bins\n",
" \n",
" Input:\n",
" image (string): path to the tiff file\n",
" num_bins (int): number of bins\n",
" \n",
" Return:\n",
" list_dic (num_bins + 1): a list of dictionary\n",
" image (512, 640): original image\n",
" new_error (512, 640): error that includes the boundary\n",
" diff (510, 638): difference of min and max of the 4 neighbors\n",
" boundary (2300,): the boundary values after subtracting the very first pixel value\n",
" predict (325380,): the list of predicted values\n",
" bins (num_bins)\n",
" A (3 X 3): system of equation\n",
" \n",
" \"\"\"\n",
" # get the prediction error and difference\n",
" # get the prediction error and difference\n",
" image, predict, diff, error, A = p
lot_hist
(image)\n",
" image, predict, diff, error, A = p
redict_pix
(image)\n",
" \n",
" \n",
" # get the number of points in each bins\n",
" # get the number of points in each bins\n",
" data_points_per_bin = len(diff) // num_bins\n",
" data_points_per_bin = len(diff) // num_bins\n",
...
@@ -252,14 +292,15 @@
...
@@ -252,14 +292,15 @@
" new_error[1:-1,-1] = new_error[1:-1,-1] - keep\n",
" new_error[1:-1,-1] = new_error[1:-1,-1] - keep\n",
" new_error[0,0] = keep\n",
" new_error[0,0] = keep\n",
" \n",
" \n",
" diff = np.reshape(diff,(510,638))\n",
" # return the huffman dictionary\n",
" # return the huffman dictionary\n",
" return list_dic,
np.ravel(image), error, new_error, diff, boundary, predict, bins
\n",
" return list_dic,
image, new_error, diff, boundary, predict, bins, A
\n",
" \n"
" \n"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
68
,
"execution_count":
17
,
"id": "2eb774d2",
"id": "2eb774d2",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -267,7 +308,7 @@
...
@@ -267,7 +308,7 @@
"def encoder(error, list_dic, diff, bound, bins):\n",
"def encoder(error, list_dic, diff, bound, bins):\n",
" # copy the error matrix (including the boundary)\n",
" # copy the error matrix (including the boundary)\n",
" encoded = np.copy(error).astype(int).astype(str).astype(object)\n",
" encoded = np.copy(error).astype(int).astype(str).astype(object)\n",
" diff = np.reshape(diff,(510,638))\n",
"
#
diff = np.reshape(diff,(510,638))\n",
" # loop through all the pixel to encode\n",
" # loop through all the pixel to encode\n",
" for i in range(encoded.shape[0]):\n",
" for i in range(encoded.shape[0]):\n",
" for j in range(encoded.shape[1]):\n",
" for j in range(encoded.shape[1]):\n",
...
@@ -287,7 +328,7 @@
...
@@ -287,7 +328,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
69
,
"execution_count":
23
,
"id": "8eeb40d0",
"id": "8eeb40d0",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -298,6 +339,7 @@
...
@@ -298,6 +339,7 @@
" the encoded matrix of error values, and the encoding dicitonary.\n",
" the encoded matrix of error values, and the encoding dicitonary.\n",
" \"\"\"\n",
" \"\"\"\n",
" # change the dictionary back to list\n",
" # change the dictionary back to list\n",
" # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
" the_keys0 = list(list_dic[0].keys())\n",
" the_keys0 = list(list_dic[0].keys())\n",
" the_values0 = list(list_dic[0].values())\n",
" the_values0 = list(list_dic[0].values())\n",
" \n",
" \n",
...
@@ -338,6 +380,7 @@
...
@@ -338,6 +380,7 @@
" predict = np.round(np.round(np.linalg.solve(A,y)[-1][0],1))\n",
" predict = np.round(np.round(np.linalg.solve(A,y)[-1][0],1))\n",
" \n",
" \n",
" # add on the difference by searching the dictionary\n",
" # add on the difference by searching the dictionary\n",
" # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
" if difference <= bins[0]:\n",
" if difference <= bins[0]:\n",
" error_matrix[i][j] = int(the_keys1[the_values1.index(encoded_matrix[i,j])]) + int(predict)\n",
" error_matrix[i][j] = int(the_keys1[the_values1.index(encoded_matrix[i,j])]) + int(predict)\n",
" elif difference <= bins[1] and difference > bins[0]:\n",
" elif difference <= bins[1] and difference > bins[0]:\n",
...
@@ -353,7 +396,7 @@
...
@@ -353,7 +396,7 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
70
,
"execution_count":
19
,
"id": "f959fe93",
"id": "f959fe93",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
...
@@ -380,6 +423,7 @@
...
@@ -380,6 +423,7 @@
" o_len += len(bin(original[i])[2:])\n",
" o_len += len(bin(original[i])[2:])\n",
" \n",
" \n",
" # check the difference and find the coresponding huffman table\n",
" # check the difference and find the coresponding huffman table\n",
" # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
" if diff[i] <= bins[0]:\n",
" if diff[i] <= bins[0]:\n",
" c_len += len(list_dic[1][str(int(error[i]))])\n",
" c_len += len(list_dic[1][str(int(error[i]))])\n",
" \n",
" \n",
...
@@ -397,65 +441,53 @@
...
@@ -397,65 +441,53 @@
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count":
null
,
"execution_count":
25
,
"id": "3e0e9742",
"id": "3e0e9742",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(512, 640)\n",
"True\n",
"5\n"
]
}
],
"source": [
"source": [
"scenes = file_extractor()\n",
"scenes = file_extractor()\n",
"images = image_extractor(scenes)\n",
"images = image_extractor(scenes)\n",
"#bins = [25,40,70]\n",
"list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4)\n",
"A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]])\n",
"encoded_matrix = encoder(new_error, list_dic, diff, bound, bins)\n",
"list_dic, image, error, new_error, diff, bound, predict, bins = huffman(images[0], 4)\n",
"encoded_matrix = encoder(np.reshape(new_error,(512,640)), list_dic, diff, bound, bins)\n",
"reconstruct_image = decoder(A, encoded_matrix, list_dic, bins)\n",
"reconstruct_image = decoder(A, encoded_matrix, list_dic, bins)\n",
"print(np.allclose(image
.reshape(512,640)
, reconstruct_image))\n",
"print(np.allclose(image, reconstruct_image))\n",
"print(len(list_dic))"
"print(len(list_dic))"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": 32,
"id": "f0948ab2",
"id": "004e8ba8",
"metadata": {},
"outputs": [],
"source": [
"rate1 = []\n",
"rate2 = []\n",
"rate3 = []\n",
"bins1 = [25,40,70]\n",
"bins2 = [50,100,150]\n",
"bins3 = [30,50,100]\n",
"B = [bins1, bins2, bins3]\n",
"for i in range(len(images)):\n",
" for j, bins in enumerate(B):\n",
" list_dic, image, error, new_error, diff, bound, predict = huffman(images[i], bins)\n",
" r = compress_rate(image, error, diff, bound, list_dic, bins)\n",
" if j == 0:\n",
" rate1.append(r)\n",
" elif j == 1:\n",
" rate2.append(r)\n",
" else:\n",
" rate3.append(r)\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7d615dcd",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[26, 40, 62]\n"
]
}
],
"source": [
"source": [
"print(f\"Compression rate of huffman with bins {bins1}: {np.mean(rate1)}\")\n",
"\n",
"print(f\"Compression rate of huffman with bins {bins2}: {np.mean(rate2)}\")\n",
"print(bins)"
"print(f\"Compression rate of huffman with bins {bins3}: {np.mean(rate3)}\")\n"
]
]
},
},
{
{
"cell_type": "code",
"cell_type": "code",
"execution_count": null,
"execution_count": null,
"id": "
67cb360d
",
"id": "
a282f9e6
",
"metadata": {},
"metadata": {},
"outputs": [],
"outputs": [],
"source": []
"source": []
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment