Commit 2659c0f6 authored by Kelly Chang's avatar Kelly Chang

kelly changes

parent 88251d36
No preview for this file type
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 59,
"id": "14f74f21", "id": "14f74f21",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
"from sklearn.neighbors import KernelDensity\n", "from sklearn.neighbors import KernelDensity\n",
"import pandas as pd\n", "import pandas as pd\n",
"from collections import Counter\n", "from collections import Counter\n",
"import time" "import time\n",
"import numpy.linalg as la"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 13, "execution_count": 49,
"id": "c16af61f", "id": "c16af61f",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -78,12 +79,12 @@ ...@@ -78,12 +79,12 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 14, "execution_count": 61,
"id": "aceba613", "id": "8172fa41",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def predict_pix(tiff_image):\n", "def predict_pix(tiff_image, difference = True):\n",
" \"\"\"\n", " \"\"\"\n",
" This function predict the pixel values excluding the boundary.\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", " Using the 4 neighbor pixel values and MSE to predict the next pixel value\n",
...@@ -99,16 +100,15 @@ ...@@ -99,16 +100,15 @@
" \n", " \n",
" Return:\n", " Return:\n",
" image (512 X 640): original image \n", " image (512 X 640): original image \n",
" predict (325380,): predicted image exclude the boundary\n", " predict (325380,): predicted image excluding the boundary\n",
" diff. (325380,): difference between the min and max of four neighbors exclude the boundary\n", " diff. (325380,): IF difference = TRUE, difference between the min and max of four neighbors exclude the boundary\n",
" ELSE: the residuals of the four nearest pixels to a fitted hyperplane\n",
" error (325380,): difference between the original image and predicted image\n", " error (325380,): difference between the original image and predicted image\n",
" A (3 X 3): system of equation\n", " A (3 X 3): system of equation\n",
" \"\"\"\n", " \"\"\"\n",
" image = Image.open(tiff_image) #Open the image and read it as an Image object\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", " # 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",
...@@ -123,23 +123,37 @@ ...@@ -123,23 +123,37 @@
" # 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", " predict = np.round(np.round((np.linalg.solve(A,y)[-1]),1))\n",
" \n",
" #Matrix system of points that will be used to solve the least squares fitting hyperplane\n",
" points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]])\n",
" \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",
" z2 = np.ravel(z2)\n", " z2 = np.ravel(z2)\n",
" z3 = np.ravel(z3)\n", " z3 = np.ravel(z3)\n",
" neighbor = np.vstack((z0,z1,z2,z3)).T\n", " neighbor = np.vstack((z0,z1,z2,z3)).T\n",
" # calculate the difference\n", " \n",
" diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n", " if difference:\n",
" # calculate the difference\n",
" diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n",
" \n",
" else:\n",
" #Compute the best fitting hyperplane using least squares\n",
" #The res is the residuals of the four points used to fit the hyperplane (summed distance of each of the \n",
" #points to the hyperplane), it is a measure of gradient\n",
" f, diff, rank, s = la.lstsq(points, neighbor.T, rcond=None) \n",
" diff = diff.astype(int)\n",
" \n",
" # 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\n" " return image, predict, diff, error, A"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 62,
"id": "6b965751", "id": "6b965751",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -192,12 +206,12 @@ ...@@ -192,12 +206,12 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 24, "execution_count": 63,
"id": "b7561883", "id": "b7561883",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def huffman(image, num_bins=4):\n", "def huffman(image, num_bins=4, difference = True):\n",
" \"\"\"\n", " \"\"\"\n",
" This function is used to encode the error based on the difference\n", " This function is used to encode the error based on the difference\n",
" and split the difference into different bins\n", " and split the difference into different bins\n",
...@@ -218,7 +232,7 @@ ...@@ -218,7 +232,7 @@
" \n", " \n",
" \"\"\"\n", " \"\"\"\n",
" # get the prediction error and difference\n", " # get the prediction error and difference\n",
" image, predict, diff, error, A = predict_pix(image)\n", " image, predict, diff, error, A = predict_pix(image, difference)\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",
...@@ -300,18 +314,23 @@ ...@@ -300,18 +314,23 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 17, "execution_count": 64,
"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",
" \"\"\"\n", " \"\"\"\n",
<<<<<<< HEAD " This function encode the matrix with huffman coding tables\n",
" This function en\n", " \n",
======= " Input:\n",
" This function \n", " error (512, 640): a matrix with all the errors\n",
>>>>>>> a352868acf14cebeaa7ea2a58e879b1d36b066ad " list_dic (num_dic + 1,): a list of huffman coding table \n",
" bound (2300,): the boundary values after subtracting the very first pixel value\n",
" bins (num_bins - 1,): a list of threshold to cut the bins\n",
" \n",
" Return:\n",
" encoded (512, 640): encoded matrix\n",
" \"\"\"\n", " \"\"\"\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",
...@@ -335,15 +354,22 @@ ...@@ -335,15 +354,22 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 23, "execution_count": 79,
"id": "8eeb40d0", "id": "8eeb40d0",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def decoder(A, encoded_matrix, list_dic, bins):\n", "def decoder(A, encoded_matrix, list_dic, bins, use_diff):\n",
" \"\"\"\n", " \"\"\"\n",
" Function that accecpts the prediction matrix A for the linear system,\n", " This function decodes the encoded_matrix.\n",
" the encoded matrix of error values, and the encoding dicitonary.\n", " Input:\n",
" A (3 X 3): system of equation\n",
" list_dic (num_dic + 1,): a list of huffman coding table \n",
" encoded_matrix (512, 640): encoded matrix\n",
" bins (num_bins - 1,): a list of threshold to cut the bins\n",
" \n",
" Return:\n",
" decode_matrix (512, 640): decoded matrix\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", " # !!!!!WARNING!!!! has to change this part, eveytime you change the number of bins\n",
...@@ -362,62 +388,85 @@ ...@@ -362,62 +388,85 @@
" the_keys4 = list(list_dic[4].keys())\n", " the_keys4 = list(list_dic[4].keys())\n",
" the_values4 = list(list_dic[4].values())\n", " the_values4 = list(list_dic[4].values())\n",
" \n", " \n",
" error_matrix = np.zeros((512,640))\n", " #Matrix system of points that will be used to solve the least squares fitting hyperplane\n",
" points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]])\n",
" \n",
" decode_matrix = np.zeros((512,640))\n",
" # loop through all the element in the matrix\n", " # loop through all the element in the matrix\n",
" for i in range(error_matrix.shape[0]):\n", " for i in range(decode_matrix.shape[0]):\n",
" for j in range(error_matrix.shape[1]):\n", " for j in range(decode_matrix.shape[1]):\n",
" # if it's the very first pixel on the image\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_keys0[the_values0.index(encoded_matrix[i,j])])\n", " decode_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])])\n",
" # if it's on the boundary\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 == decode_matrix.shape[0]-1 or j == 0 or j == decode_matrix.shape[1]-1:\n",
" error_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) + error_matrix[0][0]\n", " decode_matrix[i][j] = int(the_keys0[the_values0.index(encoded_matrix[i,j])]) + decode_matrix[0][0]\n",
" # if not the boundary\n", " # if not the boundary\n",
" else:\n", " else:\n",
" # predict the image with the known pixel value\n", " # predict the image with the known pixel value\n",
" z0 = error_matrix[i-1][j-1]\n", " z0 = decode_matrix[i-1][j-1]\n",
" z1 = error_matrix[i-1][j]\n", " z1 = decode_matrix[i-1][j]\n",
" z2 = error_matrix[i-1][j+1]\n", " z2 = decode_matrix[i-1][j+1]\n",
" z3 = error_matrix[i][j-1]\n", " z3 = decode_matrix[i][j-1]\n",
" y0 = int(-z0+z2-z3)\n", " y0 = int(-z0+z2-z3)\n",
" y1 = int(z0+z1+z2)\n", " y1 = int(z0+z1+z2)\n",
" y2 = int(-z0-z1-z2-z3)\n", " y2 = int(-z0-z1-z2-z3)\n",
" y = np.vstack((y0,y1,y2))\n", " y = np.vstack((y0,y1,y2))\n",
" difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3)\n", " if use_diff:\n",
" difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3)\n",
" else:\n",
" \n",
" f, difference, rank, s = la.lstsq(points, [z0,z1,z2,z3], rcond=None) \n",
" difference = difference.astype(int)\n",
" \n",
" 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", " # !!!!!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", " decode_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",
" error_matrix[i][j] = int(the_keys2[the_values2.index(encoded_matrix[i,j])]) + int(predict)\n", " decode_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", " 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", " decode_matrix[i][j] = int(the_keys3[the_values3.index(encoded_matrix[i,j])]) + int(predict)\n",
" else:\n", " else:\n",
" error_matrix[i][j] = int(the_keys4[the_values4.index(encoded_matrix[i,j])]) + int(predict)\n", " decode_matrix[i][j] = int(the_keys4[the_values4.index(encoded_matrix[i,j])]) + int(predict)\n",
" \n", " \n",
" \n", " \n",
" return error_matrix.astype(int)" " return decode_matrix.astype(int)"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 19, "execution_count": 74,
"id": "f959fe93", "id": "f959fe93",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def compress_rate(image, error, diff, bound, list_dic, bins):\n", "def compress_rate(image, new_error, diff, bound, list_dic, bins):\n",
" '''\n",
" This function is used to calculate the compression rate.\n",
" Input:\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",
" bound (2300,): the boundary values after subtracting the very first pixel value\n",
" list_dic (num_dic + 1,): a list of huffman coding table \n",
" bins (num_bins - 1,): a list of threshold to cut the bins\n",
" \n",
" Return:\n",
" compression rate\n",
" '''\n",
" # the bits for the original image\n", " # the bits for the original image\n",
" o_len = 0\n", " o_len = 0\n",
" # the bits for the compressed image\n", " # the bits for the compressed image\n",
" c_len = 0\n", " c_len = 0\n",
" # initializing the varible \n", " # initializing the varible \n",
" im = np.reshape(image,(512, 640))\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", " real_b = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1]))\n",
" original = im[1:-1,1:-1].reshape(-1)\n", " original = image[1:-1,1:-1].reshape(-1)\n",
" diff = diff.reshape(-1)\n", " diff = diff.reshape(-1)\n",
" error = new_error[1:-1,1:-1].reshape(-1)\n",
" \n", " \n",
" # calculate the bit for boundary\n", " # calculate the bit for boundary\n",
" for i in range(0,len(bound)):\n", " for i in range(0,len(bound)):\n",
...@@ -426,6 +475,7 @@ ...@@ -426,6 +475,7 @@
" \n", " \n",
" # calculate the bit for the pixels inside the boundary\n", " # calculate the bit for the pixels inside the boundary\n",
" for i in range(0,len(original)):\n", " for i in range(0,len(original)):\n",
"\n",
" # for the original image\n", " # for the original image\n",
" o_len += len(bin(original[i])[2:])\n", " o_len += len(bin(original[i])[2:])\n",
" \n", " \n",
...@@ -441,14 +491,14 @@ ...@@ -441,14 +491,14 @@
" c_len += len(list_dic[3][str(int(error[i]))])\n", " c_len += len(list_dic[3][str(int(error[i]))])\n",
"\n", "\n",
" else: \n", " else: \n",
" c_len += len(list_dic[5][str(int(error[i]))])\n", " c_len += len(list_dic[4][str(int(error[i]))])\n",
"\n", "\n",
" return c_len/o_len" " return c_len/o_len"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 25, "execution_count": 80,
"id": "3e0e9742", "id": "3e0e9742",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
...@@ -456,7 +506,6 @@ ...@@ -456,7 +506,6 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"(512, 640)\n",
"True\n", "True\n",
"5\n" "5\n"
] ]
...@@ -465,30 +514,32 @@ ...@@ -465,30 +514,32 @@
"source": [ "source": [
"scenes = file_extractor()\n", "scenes = file_extractor()\n",
"images = image_extractor(scenes)\n", "images = image_extractor(scenes)\n",
"list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4)\n", "list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4, False)\n",
"encoded_matrix = encoder(new_error, list_dic, diff, bound, bins)\n", "encoded_matrix = encoder(new_error, 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, False)\n",
"print(np.allclose(image, 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": 32, "execution_count": 81,
"id": "004e8ba8", "id": "004e8ba8",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"name": "stdout", "data": {
"output_type": "stream", "text/plain": [
"text": [ "0.4437662760416667"
"[26, 40, 62]\n" ]
] },
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
} }
], ],
"source": [ "source": [
"\n", "compress_rate(image, new_error, diff, bound, list_dic, bins)"
"print(bins)"
] ]
}, },
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 34, "execution_count": 59,
"id": "14f74f21", "id": "14f74f21",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
"from sklearn.neighbors import KernelDensity\n", "from sklearn.neighbors import KernelDensity\n",
"import pandas as pd\n", "import pandas as pd\n",
"from collections import Counter\n", "from collections import Counter\n",
"import time" "import time\n",
"import numpy.linalg as la"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 35, "execution_count": 49,
"id": "c16af61f", "id": "c16af61f",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -78,12 +79,12 @@ ...@@ -78,12 +79,12 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 36, "execution_count": 61,
"id": "aceba613", "id": "8172fa41",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def predict_pix(tiff_image):\n", "def predict_pix(tiff_image, difference = True):\n",
" \"\"\"\n", " \"\"\"\n",
" This function predict the pixel values excluding the boundary.\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", " Using the 4 neighbor pixel values and MSE to predict the next pixel value\n",
...@@ -99,16 +100,15 @@ ...@@ -99,16 +100,15 @@
" \n", " \n",
" Return:\n", " Return:\n",
" image (512 X 640): original image \n", " image (512 X 640): original image \n",
" predict (325380,): predicted image exclude the boundary\n", " predict (325380,): predicted image excluding the boundary\n",
" diff. (325380,): difference between the min and max of four neighbors exclude the boundary\n", " diff. (325380,): IF difference = TRUE, difference between the min and max of four neighbors exclude the boundary\n",
" ELSE: the residuals of the four nearest pixels to a fitted hyperplane\n",
" error (325380,): difference between the original image and predicted image\n", " error (325380,): difference between the original image and predicted image\n",
" A (3 X 3): system of equation\n", " A (3 X 3): system of equation\n",
" \"\"\"\n", " \"\"\"\n",
" image = Image.open(tiff_image) #Open the image and read it as an Image object\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", " # 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",
...@@ -123,23 +123,37 @@ ...@@ -123,23 +123,37 @@
" # 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", " predict = np.round(np.round((np.linalg.solve(A,y)[-1]),1))\n",
" \n",
" #Matrix system of points that will be used to solve the least squares fitting hyperplane\n",
" points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]])\n",
" \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",
" z2 = np.ravel(z2)\n", " z2 = np.ravel(z2)\n",
" z3 = np.ravel(z3)\n", " z3 = np.ravel(z3)\n",
" neighbor = np.vstack((z0,z1,z2,z3)).T\n", " neighbor = np.vstack((z0,z1,z2,z3)).T\n",
" # calculate the difference\n", " \n",
" diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n", " if difference:\n",
" # calculate the difference\n",
" diff = np.max(neighbor,axis = 1) - np.min(neighbor, axis=1)\n",
" \n",
" else:\n",
" #Compute the best fitting hyperplane using least squares\n",
" #The res is the residuals of the four points used to fit the hyperplane (summed distance of each of the \n",
" #points to the hyperplane), it is a measure of gradient\n",
" f, diff, rank, s = la.lstsq(points, neighbor.T, rcond=None) \n",
" diff = diff.astype(int)\n",
" \n",
" # 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\n" " return image, predict, diff, error, A"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 37, "execution_count": 62,
"id": "6b965751", "id": "6b965751",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -192,12 +206,12 @@ ...@@ -192,12 +206,12 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 38, "execution_count": 63,
"id": "b7561883", "id": "b7561883",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def huffman(image, num_bins=4):\n", "def huffman(image, num_bins=4, difference = True):\n",
" \"\"\"\n", " \"\"\"\n",
" This function is used to encode the error based on the difference\n", " This function is used to encode the error based on the difference\n",
" and split the difference into different bins\n", " and split the difference into different bins\n",
...@@ -218,7 +232,7 @@ ...@@ -218,7 +232,7 @@
" \n", " \n",
" \"\"\"\n", " \"\"\"\n",
" # get the prediction error and difference\n", " # get the prediction error and difference\n",
" image, predict, diff, error, A = predict_pix(image)\n", " image, predict, diff, error, A = predict_pix(image, difference)\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",
...@@ -300,7 +314,7 @@ ...@@ -300,7 +314,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 39, "execution_count": 64,
"id": "2eb774d2", "id": "2eb774d2",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
...@@ -340,12 +354,12 @@ ...@@ -340,12 +354,12 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 40, "execution_count": 79,
"id": "8eeb40d0", "id": "8eeb40d0",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def decoder(A, encoded_matrix, list_dic, bins):\n", "def decoder(A, encoded_matrix, list_dic, bins, use_diff):\n",
" \"\"\"\n", " \"\"\"\n",
" This function decodes the encoded_matrix.\n", " This function decodes the encoded_matrix.\n",
" Input:\n", " Input:\n",
...@@ -353,6 +367,7 @@ ...@@ -353,6 +367,7 @@
" list_dic (num_dic + 1,): a list of huffman coding table \n", " list_dic (num_dic + 1,): a list of huffman coding table \n",
" encoded_matrix (512, 640): encoded matrix\n", " encoded_matrix (512, 640): encoded matrix\n",
" bins (num_bins - 1,): a list of threshold to cut the bins\n", " bins (num_bins - 1,): a list of threshold to cut the bins\n",
" \n",
" Return:\n", " Return:\n",
" decode_matrix (512, 640): decoded matrix\n", " decode_matrix (512, 640): decoded matrix\n",
" \"\"\"\n", " \"\"\"\n",
...@@ -373,6 +388,9 @@ ...@@ -373,6 +388,9 @@
" the_keys4 = list(list_dic[4].keys())\n", " the_keys4 = list(list_dic[4].keys())\n",
" the_values4 = list(list_dic[4].values())\n", " the_values4 = list(list_dic[4].values())\n",
" \n", " \n",
" #Matrix system of points that will be used to solve the least squares fitting hyperplane\n",
" points = np.array([[-1,-1,1], [-1,0,1], [-1,1,1], [0,-1,1]])\n",
" \n",
" decode_matrix = np.zeros((512,640))\n", " decode_matrix = np.zeros((512,640))\n",
" # loop through all the element in the matrix\n", " # loop through all the element in the matrix\n",
" for i in range(decode_matrix.shape[0]):\n", " for i in range(decode_matrix.shape[0]):\n",
...@@ -394,7 +412,13 @@ ...@@ -394,7 +412,13 @@
" y1 = int(z0+z1+z2)\n", " y1 = int(z0+z1+z2)\n",
" y2 = int(-z0-z1-z2-z3)\n", " y2 = int(-z0-z1-z2-z3)\n",
" y = np.vstack((y0,y1,y2))\n", " y = np.vstack((y0,y1,y2))\n",
" difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3)\n", " if use_diff:\n",
" difference = max(z0,z1,z2,z3) - min(z0,z1,z2,z3)\n",
" else:\n",
" \n",
" f, difference, rank, s = la.lstsq(points, [z0,z1,z2,z3], rcond=None) \n",
" difference = difference.astype(int)\n",
" \n",
" 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",
...@@ -414,15 +438,24 @@ ...@@ -414,15 +438,24 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 41, "execution_count": 74,
"id": "f959fe93", "id": "f959fe93",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def compress_rate(image, error, diff, bound, list_dic, bins):\n", "def compress_rate(image, new_error, diff, bound, list_dic, bins):\n",
" '''\n", " '''\n",
" This function is used to calculate the compression rate.\n", " This function is used to calculate the compression rate.\n",
" Input:\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",
" bound (2300,): the boundary values after subtracting the very first pixel value\n",
" list_dic (num_dic + 1,): a list of huffman coding table \n",
" bins (num_bins - 1,): a list of threshold to cut the bins\n",
" \n", " \n",
" Return:\n",
" compression rate\n",
" '''\n", " '''\n",
" # the bits for the original image\n", " # the bits for the original image\n",
" o_len = 0\n", " o_len = 0\n",
...@@ -433,6 +466,7 @@ ...@@ -433,6 +466,7 @@
" real_b = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1]))\n", " real_b = np.hstack((image[0,:],image[-1,:],image[1:-1,0],image[1:-1,-1]))\n",
" original = image[1:-1,1:-1].reshape(-1)\n", " original = image[1:-1,1:-1].reshape(-1)\n",
" diff = diff.reshape(-1)\n", " diff = diff.reshape(-1)\n",
" error = new_error[1:-1,1:-1].reshape(-1)\n",
" \n", " \n",
" # calculate the bit for boundary\n", " # calculate the bit for boundary\n",
" for i in range(0,len(bound)):\n", " for i in range(0,len(bound)):\n",
...@@ -441,6 +475,7 @@ ...@@ -441,6 +475,7 @@
" \n", " \n",
" # calculate the bit for the pixels inside the boundary\n", " # calculate the bit for the pixels inside the boundary\n",
" for i in range(0,len(original)):\n", " for i in range(0,len(original)):\n",
"\n",
" # for the original image\n", " # for the original image\n",
" o_len += len(bin(original[i])[2:])\n", " o_len += len(bin(original[i])[2:])\n",
" \n", " \n",
...@@ -456,14 +491,14 @@ ...@@ -456,14 +491,14 @@
" c_len += len(list_dic[3][str(int(error[i]))])\n", " c_len += len(list_dic[3][str(int(error[i]))])\n",
"\n", "\n",
" else: \n", " else: \n",
" c_len += len(list_dic[5][str(int(error[i]))])\n", " c_len += len(list_dic[4][str(int(error[i]))])\n",
"\n", "\n",
" return c_len/o_len" " return c_len/o_len"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 42, "execution_count": 80,
"id": "3e0e9742", "id": "3e0e9742",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
...@@ -471,7 +506,6 @@ ...@@ -471,7 +506,6 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"(512, 640)\n",
"True\n", "True\n",
"5\n" "5\n"
] ]
...@@ -480,30 +514,32 @@ ...@@ -480,30 +514,32 @@
"source": [ "source": [
"scenes = file_extractor()\n", "scenes = file_extractor()\n",
"images = image_extractor(scenes)\n", "images = image_extractor(scenes)\n",
"list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4)\n", "list_dic, image, new_error, diff, bound, predict, bins, A = huffman(images[0], 4, False)\n",
"encoded_matrix = encoder(new_error, list_dic, diff, bound, bins)\n", "encoded_matrix = encoder(new_error, 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, False)\n",
"print(np.allclose(image, 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": 33, "execution_count": 81,
"id": "004e8ba8", "id": "004e8ba8",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"name": "stdout", "data": {
"output_type": "stream", "text/plain": [
"text": [ "0.4437662760416667"
"(512, 640)\n" ]
] },
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
} }
], ],
"source": [ "source": [
"\n", "compress_rate(image, new_error, diff, bound, list_dic, bins)"
"print(encoded_matrix.shape)"
] ]
}, },
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment