" tiff_image_path (string): path to the tiff file\n",
" \n",
" Return:\n",
" image ndarray(512 X 640): original image \n",
" predict ndarray(325380,): predicted image excluding the boundary\n",
" diff. ndarray(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 ndarray(325380,): difference between the original image and predicted image\n",
" A ndarray(3 X 3): system of equation\n",
" \"\"\"\n",
" image_obj = Image.open(tiff_image_path) #Open the image and read it as an Image object\n",
" 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\n",
" # image_array = image_array.astype(int) \n",
" A = np.array([[3,0,-1],[0,3,3],[1,-3,-4]]) # the matrix for system of equation\n",
"\u001b[1;32m/home/bryce/git/master/SameTableEncoder.ipynb Cell 19'\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000019?line=0'>1</a>\u001b[0m \u001b[39mprint\u001b[39m(check_bin_size(images))\n",
"\u001b[1;32m/home/bryce/git/master/SameTableEncoder.ipynb Cell 18'\u001b[0m in \u001b[0;36mcheck_bin_size\u001b[0;34m(tiff_image_path_list, num_bins, difference)\u001b[0m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000017?line=20'>21</a>\u001b[0m all_bins \u001b[39m=\u001b[39m []\n\u001b[1;32m <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000017?line=21'>22</a>\u001b[0m \u001b[39mfor\u001b[39;00m i, tiff_image_path \u001b[39min\u001b[39;00m \u001b[39menumerate\u001b[39m(tiff_image_path_list):\n\u001b[1;32m <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000017?line=22'>23</a>\u001b[0m \u001b[39m# get the image_array, etc\u001b[39;00m\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000017?line=23'>24</a>\u001b[0m image_array, predict, diff, error\u001b[39m=\u001b[39m predict_pix(tiff_image_path, difference)\n\u001b[1;32m <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000017?line=25'>26</a>\u001b[0m \u001b[39m# calculate the number of points that will go in each bin\u001b[39;00m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/bryce/git/master/SameTableEncoder.ipynb#ch0000017?line=26'>27</a>\u001b[0m data_points_per_bin \u001b[39m=\u001b[39m diff\u001b[39m.\u001b[39msize \u001b[39m/\u001b[39m\u001b[39m/\u001b[39m num_bins\n",
"\u001b[0;31mValueError\u001b[0m: not enough values to unpack (expected 4, got 3)"
\title{Scanning Compression Algorithm for Thermal Images}
\author{Dr. Andrey Filippov, Bryce Hepner, Nathaniel Callens Jr., and Kelly Chang}
\begin{document}
\maketitle
\begin{abstract}
This algorithm operates by scanning through each pixel first laterally, using already scanned pixels to decompress the next pixel's value. By encoding the error between the predicted pixel value and the actual value and saving that, we were able to get the compressed image to be about 40\% of the original size losslessly.
\end{abstract}
\section{Introduction}
The idea is based off of how images are scanned in originally. Like a cathode-ray tube in a television, the algorithm goes line by line, reading/writing each pixel individually. Each pixel, as long as it is not on the top or side boundaries, will have 4 neighbors that have already been read into the machine. Those points can be interpolated and used to predict the next pixel's value.
The goal is to encode the error between that value and the original value and use that to compress and decompress the image. Even though a possibly larger integer may need to be stored, it's more likely that the guess will be correct, or off by a small margin, making the distribution more normalized and less uniform.
\caption{\label{fig:pixels}The other 4 pixels are used to find the value of the 5th.}
\end{figure}
\section{Background}
The images that were used in the backing of this paper are all thermal images. The images were taken at day and at night, giving a broad range. The sensors that were used store numbers as integers on a range from
For other uses of this algorithm, if it were to be used on floating point values with much higher precision, it would be advantageous to change this to a lossy format and round to whatever decimal place is best for the specific application. Our sensors do not need this because they round values to the optical equivalent of 3 decimal points on a 256 pixel value scale.
\section{The Approach}
To begin, the border is just encoded into the system. There are not very many values here and the algorithm needs a place to start. Guessing the first and encoding it would be the same. Once the middle points are reached, the pixel to the left, top left, directly above, and top right have already been read in. Each of these values is given a point in the x-y plane, with the top left at (-1,1), top pixel at (0,1), top right pixel at (1,1), and the middle left pixel at (-1,0), giving the target (0,0). Using the formula for a plane in 3D ($ax + by + c = z$) we get the system of equations$$-a + b + c = z_0$$ $$b + c = z_1$$ $$a + b + c = z_2$$ $$-a + c = z_3$$.
These complete the form $Ax = b$ as
$$A =
\begin{bmatrix}
-1 & 1 & 1\\
0 & 1 & 1 \\
1 & 1 & 1 \\
-1 & 0 & 1
\end{bmatrix}
$$
$$b =
\begin{bmatrix}
z_0\\
z_1 \\
z_2 \\
z_3
\end{bmatrix}
$$
Which, due to there being 4 equations and 4 unknowns, is unsolvable.
This can be corrected by making
$$A =
\begin{bmatrix}
3 & 0 & -1\\
0 & 3 & 3 \\
1 & -3 & -4
\end{bmatrix}
$$
and
$$b =
\begin{bmatrix}
-z_0 + z_2 - z_3\\
z_0 + z_1 + z_2 \\
-z_0 - z_1 - z_2 - z_3
\end{bmatrix}
$$
.
The new matrix is full rank and can therefore be solved using \textbf{numpy.linalg.solve}. This is then converted back to the $ax+by+c=z$ to find the c value, which is the predicted pixel value.
Huffman encoding performs well on data with a normalized distribution, which makes the error numbers a good candidate. Most pixels will be off by 0 or 1 since most objects have close to uniform surface temperature or have a regular temperature gradient.
In order to control for objects in images that are known to have an unpredictable temperature (fail the cases before), a bin system is used. The residuals from \textbf{np.linalg.lstsq} are used to determine the difference across the 4 known points, which is then used to place it in a category. This number is the difference between trying to fit a plane between 4 different points. If a plane is able to be drawn that contains all 4 points, it makes sense that the error will be much smaller than if the best fitted plane was not very close to any of the points. 5 bins were used with splits chosen by evenly distributing the difference numbers into evenly sized bins. Many of the images had several different bin sizes ranging from 11 in the first category to a difference of 30 as the first category. An average number between all of them was chosen, since using the average versus specific bins had an effect on compression of less than half a percent, and made implementation easier.
\section{Results}
We attained an average compression ratio of $.404$ on a set of 250 images, with values ranging from $.368$ to $.496$. When the size of the saved dictionary was included, the compression ratio only changed from $.404$ to $.405$, but on a single image it only compressed it down to $.705$. Despite no explicit use of other images in the compression, the total ratio decreases by using other images due to the shared dictionary. A universal dictionary cannot be created then applied on a new image due to how the border is saved. The values are just stored as part of the dictionary, and it is unlikely that the universal dictionary would have these values, and if it did, it would be too large due to the Huffman encoded nature. There are ways around this but they were not explored here.
% \subsection{How to include Figures}
% First you have to upload the image file from your computer using the upload link in the file-tree menu. Then use the includegraphics command to include it in your document. Use the figure environment and the caption command to add a number and a caption to your figure. See the code for Figure \ref{fig:frog} in this section for an example.
% Note that your figure will automatically be placed in the most appropriate place for it, given the surrounding text and taking into account other figures or tables that may be close by. You can find out more about adding images to your documents in this help article on \href{https://www.overleaf.com/learn/how-to/Including_images_on_Overleaf}{including images on Overleaf}.
% \begin{figure}
% \centering
% \includegraphics[width=0.3\textwidth]{frog.jpg}
% \caption{\label{fig:frog}This frog was uploaded via the file-tree menu.}
% \end{figure}
% \subsection{How to add Tables}
% Use the table and tabular environments for basic tables --- see Table~\ref{tab:widgets}, for example. For more information, please see this help article on \href{https://www.overleaf.com/learn/latex/tables}{tables}.
% \begin{table}
% \centering
% \begin{tabular}{l|r}
% Item & Quantity \\\hline
% Widgets & 42 \\
% Gadgets & 13
% \end{tabular}
% \caption{\label{tab:widgets}An example table.}
% \end{table}
% \subsection{How to add Comments and Track Changes}
% Comments can be added to your project by highlighting some text and clicking ``Add comment'' in the top right of the editor pane. To view existing comments, click on the Review menu in the toolbar above. To reply to a comment, click on the Reply button in the lower right corner of the comment. You can close the Review pane by clicking its name on the toolbar when you're done reviewing for the time being.
% Track changes are available on all our \href{https://www.overleaf.com/user/subscription/plans}{premium plans}, and can be toggled on or off using the option at the top of the Review pane. Track changes allow you to keep track of every change made to the document, along with the person making the change.
% \subsection{How to add Lists}
% You can make lists with automatic numbering \dots
% \begin{enumerate}
% \item Like this,
% \item and like this.
% \end{enumerate}
% \dots or bullet points \dots
% \begin{itemize}
% \item Like this,
% \item and like this.
% \end{itemize}
% \subsection{How to write Mathematics}
% \LaTeX{} is great at typesetting mathematics. Let $X_1, X_2, \ldots, X_n$ be a sequence of independent and identically distributed random variables with $\text{E}[X_i] = \mu$ and $\text{Var}[X_i] = \sigma^2 < \infty$, and let
% \[S_n = \frac{X_1 + X_2 + \cdots + X_n}{n}
% = \frac{1}{n}\sum_{i}^{n} X_i\]
% denote their mean. Then as $n$ approaches infinity, the random variables $\sqrt{n}(S_n - \mu)$ converge in distribution to a normal $\mathcal{N}(0, \sigma^2)$.
% \subsection{How to change the margins and paper size}
% Usually the template you're using will have the page margins and paper size set correctly for that use-case. For example, if you're using a journal article template provided by the journal publisher, that template will be formatted according to their requirements. In these cases, it's best not to alter the margins directly.
% If however you're using a more general template, such as this one, and would like to alter the margins, a common way to do so is via the geometry package. You can find the geometry package loaded in the preamble at the top of this example file, and if you'd like to learn more about how to adjust the settings, please visit this help article on \href{https://www.overleaf.com/learn/latex/page_size_and_margins}{page size and margins}.
% \subsection{How to change the document language and spell check settings}
% Overleaf supports many different languages, including multiple different languages within one document.
% To configure the document language, simply edit the option provided to the babel package in the preamble at the top of this example project. To learn more about the different options, please visit this help article on \href{https://www.overleaf.com/learn/latex/International_language_support}{international language support}.
% To change the spell check language, simply open the Overleaf menu at the top left of the editor window, scroll down to the spell check setting, and adjust accordingly.
% \subsection{How to add Citations and a References List}
% You can simply upload a \verb|.bib| file containing your BibTeX entries, created with a tool such as JabRef. You can then cite entries from it, like this: \cite{greenwade93}. Just remember to specify a bibliography style, as well as the filename of the \verb|.bib|. You can find a \href{https://www.overleaf.com/help/97-how-to-include-a-bibliography-using-bibtex}{video tutorial here} to learn more about BibTeX.
% If you have an \href{https://www.overleaf.com/user/subscription/plans}{upgraded account}, you can also import your Mendeley or Zotero library directly as a \verb|.bib| file, via the upload menu in the file-tree.
% \subsection{Good luck!}
% We hope you find Overleaf useful, and do take a look at our \href{https://www.overleaf.com/learn}{help library} for more tutorials and user guides! Please also let us know if you have any feedback using the Contact Us link at the bottom of the Overleaf menu --- or use the contact form at \url{https://www.overleaf.com/contact}.