(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 6.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 41874, 1350] NotebookOptionsPosition[ 37933, 1218] NotebookOutlinePosition[ 38372, 1235] CellTagsIndexPosition[ 38329, 1232] WindowFrame->Normal ContainsDynamic->False*) (* Beginning of Notebook Content *) Notebook[{ Cell[CellGroupData[{ Cell["Haar Image Compression", "Title"], Cell["\<\ Wavelet Workshop June 4-7, 2008 University of St. Thomas\ \>", "Subtitle", CellChangeTimes->{{3.421426484890625*^9, 3.42142648821875*^9}}], Cell["\<\ Catherine Beneteau Caroline Haddad David Ruch Patrick Van Fleet\ \>", "Subsubtitle", CellChangeTimes->{{3.42144927371875*^9, 3.42144928703125*^9}}], Cell[CellGroupData[{ Cell["Objective", "Section"], Cell["\<\ In this notebook, we will learn how to perform naive image compression using \ the 2D Haar Wavelet Transform.\ \>", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Conventions", "Section"], Cell[TextData[{ "This notebook uses the package ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " (written by Patrick Van Fleet). All commands from the ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " library will be denoted in ", StyleBox["red", FontColor->RGBColor[1, 0, 0]], ". Help is available for every command in ", StyleBox["the package", FontColor->GrayLevel[0]], ". Click on Help and then Documentation Center. At the bottom-right of the \ page is a link for Installed AddOns. Click this link and one of the options \ is DiscreteWavelets. Click this link to go to the Help Browser. Like all ", StyleBox["Mathematica", FontSlant->"Italic"], " help screens, the help is \"live\" - you can either execute the commands \ in the help to see the effects of the command or cut and paste them into your \ own notebook.\n\nComments are useful within cells of code. Any code enclosed \ by (* *) is a comment and ignored by the ", StyleBox["Mathematica", FontSlant->"Italic"], " kernel." }], "Text", CellChangeTimes->{{3.4085631561875*^9, 3.408563201375*^9}, { 3.4085632433125*^9, 3.408563315796875*^9}, {3.40856339940625*^9, 3.4085634034375*^9}, {3.408565167890625*^9, 3.40856516825*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Load DiscreteWavelets", "Section", CellChangeTimes->{3.408563584328125*^9}], Cell[BoxData[ RowBox[{"<<", "DiscreteWavelets`DiscreteWavelets`"}]], "Input", CellChangeTimes->{{3.408563455078125*^9, 3.408563467234375*^9}, { 3.408565207546875*^9, 3.40856520834375*^9}, {3.4085675625625*^9, 3.408567562828125*^9}, {3.42163052*^9, 3.421630520078125*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Available Images", "Section", CellChangeTimes->{{3.408566424859375*^9, 3.40856642509375*^9}, { 3.40856666034375*^9, 3.40856666378125*^9}}], Cell[TextData[{ "The ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " packages comes with 18 grayscale images. You can see information about \ these images (name, size, etc.) by issuing the command ", StyleBox["ImageList", FontColor->RGBColor[1, 0, 0]], "." }], "Text", CellChangeTimes->{{3.40856643015625*^9, 3.408566482328125*^9}}], Cell[BoxData[ RowBox[{ StyleBox["ImageList", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"ImageType", "\[Rule]", "GrayScale"}], "]"}]], "Input", CellChangeTimes->{{3.408566491578125*^9, 3.40856650215625*^9}, { 3.408567558484375*^9, 3.408567558796875*^9}, {3.4085700635625*^9, 3.408570064296875*^9}, {3.42163051815625*^9, 3.42163051821875*^9}}], Cell[TextData[{ "You can also get a look at these images by using the command ", StyleBox["ShowThumbnails", FontColor->RGBColor[1, 0, 0]], ". " }], "Text", CellChangeTimes->{{3.408635831734375*^9, 3.40863590271875*^9}}], Cell[BoxData[ RowBox[{ StyleBox["ShowThumbnails", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"ImageType", "\[Rule]", "GrayScale"}], "]"}]], "Input", CellChangeTimes->{{3.408635905203125*^9, 3.408635912609375*^9}, { 3.421630516671875*^9, 3.421630516734375*^9}}], Cell[TextData[{ "No matter where you installed the ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " package on your computer, you can retrieve the absolute path and file name \ for each included image. The command ", StyleBox["ImageNames", FontColor->RGBColor[1, 0, 0]], " produces a list of file names. We will add a second directive to the call \ so that the routine will use smaller versions of the image." }], "Text", CellChangeTimes->{{3.40856651390625*^9, 3.408566597796875*^9}, { 3.408568365765625*^9, 3.408568388078125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"gray", "=", RowBox[{ StyleBox["ImageNames", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{ RowBox[{"ImageType", "\[Rule]", "GrayScale"}], ",", RowBox[{"ListThumbnails", "\[Rule]", "True"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"gray", "[", RowBox[{"[", "1", "]"}], "]"}]}], "Input", CellChangeTimes->{{3.40856660190625*^9, 3.40856662253125*^9}, { 3.408567556296875*^9, 3.4085675565625*^9}, {3.4085683919375*^9, 3.408568396140625*^9}, {3.408570066625*^9, 3.408570067*^9}, { 3.421630514796875*^9, 3.421630514875*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Loading and Plotting Images", "Section", CellChangeTimes->{{3.40856667084375*^9, 3.40856669671875*^9}}], Cell["\<\ Once you have the list of file names, it is very easy to load and plot \ images. Let's load the first image in the list.\ \>", "Text", CellChangeTimes->{{3.408566678375*^9, 3.408566710125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"A", "=", RowBox[{ StyleBox["ImageRead", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"gray", "[", RowBox[{"[", "1", "]"}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ StyleBox["ImagePlot", FontColor->RGBColor[1, 0, 0]], "[", "A", "]"}]}], "Input", CellChangeTimes->{{3.408566701640625*^9, 3.408566736734375*^9}, { 3.408567553625*^9, 3.408567553875*^9}, {3.4085700694375*^9, 3.408570069765625*^9}, {3.42163051278125*^9, 3.421630512859375*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Compute the Wavelet Transform", "Section"], Cell[TextData[{ "We first compute the 2D HWT. Since we are interested in compression, we \ will use a modified version of the Haar transformation. We will multiply the \ Haar matrix by Sqrt[2] so that the output are integers. Since we are not \ using the Haar filter per se, we will use the more general DiscreteWavelets \ routine ", StyleBox["WT2D", FontColor->RGBColor[1, 0, 0]], ". This routine requires three arguments. The first is the input matrix, \ the second is the filter used to construct the wavelet matrix, and the third \ is the number of iterations." }], "Text", CellChangeTimes->{{3.408568027328125*^9, 3.408568138796875*^9}}], Cell[BoxData[{ StyleBox[ RowBox[{ RowBox[{"its", "=", "2"}], ";"}], FontColor->GrayLevel[0]], "\[IndentingNewLine]", RowBox[{ RowBox[{"h", "=", RowBox[{ RowBox[{"Sqrt", "[", "2", "]"}], "*", RowBox[{ StyleBox["Haar", FontColor->RGBColor[1, 0, 0]], "[", "]"}]}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"B", " ", "=", " ", RowBox[{ StyleBox["WT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{ RowBox[{"N", "[", "A", "]"}], ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ StyleBox["WaveletDensityPlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"B", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{{3.408567932203125*^9, 3.408568008765625*^9}, 3.4085681608125*^9, 3.4085684340625*^9, {3.408569497515625*^9, 3.40856950015625*^9}, {3.40857007240625*^9, 3.408570072671875*^9}, { 3.421628055828125*^9, 3.4216280575625*^9}, {3.421630510953125*^9, 3.4216305110625*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Lossless Compression", "Section"], Cell[TextData[{ "In this form of compression, we simply encode the transform. The image can \ be recovered exactly in lossless compression. We use the function ", StyleBox["MakeHuffmanCodes", FontColor->RGBColor[1, 0, 0]], " from ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " to build the codes. The routine requires nonnegative integers." }], "Text", CellChangeTimes->{{3.408568464203125*^9, 3.408568503859375*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"rows", ",", "cols"}], "}"}], "=", RowBox[{"Dimensions", "[", "A", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"codes", ",", "totalbits", ",", "encodedbits"}], "}"}], "=", RowBox[{ StyleBox["MakeHuffmanCodes", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"Round", "[", RowBox[{"B", "-", RowBox[{"Min", "[", "B", "]"}]}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"bpp", " ", "=", " ", RowBox[{ RowBox[{"N", "[", "encodedbits", "]"}], "/", RowBox[{"(", RowBox[{"rows", "*", "cols"}], ")"}]}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "\"\\"", ",", "rows", ",", "\"\< x \>\"", ",", "cols", ",", "\"\< x 8 = \>\"", ",", "totalbits", ",", "\"\<.\>\""}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "\"\\"", ",", "encodedbits", ",", "\"\< or \>\"", ",", "bpp", ",", "\"\< bpp.\>\""}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", RowBox[{ RowBox[{"Round", "[", RowBox[{"10000", "*", RowBox[{"bpp", "/", "8"}]}], "]"}], "/", "100."}], ",", "\"\<% of the original bitstream length.\>\""}], "]"}], ";"}]}], "Input", CellChangeTimes->{{3.408568228125*^9, 3.4085682296875*^9}, { 3.408568885640625*^9, 3.4085688964375*^9}, {3.408570075828125*^9, 3.40857007615625*^9}, {3.408676687734375*^9, 3.408676693*^9}, { 3.42163050903125*^9, 3.421630509125*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["To Consider...", "Section"], Cell["\<\ 1) What happens if we increase the number of iterations? 2) Try lossless compression with different images and different numbers of \ iterations.\ \>", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Lossy Compression", "Section"], Cell["\<\ We now add a quantization step between transforming the data and encoding the \ transform. The idea here is that we convert transform values that are \ \"small\" to zero and thus improve the performance by the Huffman encoder.\ \>", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Cumulative Energy", "Section"], Cell[TextData[{ "We will use cumulative energy to perform quantization. The command in ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " to compute the cumulative energy is ", StyleBox["CE", FontColor->RGBColor[1, 0, 0]], ". It takes either a vector or a matrix as input.\n\nHere is the cumulative \ energy vector for our original image." }], "Text", CellChangeTimes->{{3.408569215796875*^9, 3.408569218640625*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"ceA", " ", "=", " ", RowBox[{ StyleBox["CE", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox["A", FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->RGBColor[0.501961, 0, 0]]}], "\[IndentingNewLine]", RowBox[{"ListPlot", "[", RowBox[{"ceA", ",", RowBox[{"PlotStyle", "\[Rule]", "Red"}]}], "]"}]}], "Input", CellChangeTimes->{ 3.408567646796875*^9, {3.408570090515625*^9, 3.40857009078125*^9}, { 3.421630505875*^9, 3.421630506015625*^9}}], Cell["\<\ Here is the cumulative energy vector for our transformed image. I've \ printed out an element from the vector to give you an idea how to read the \ elements of the vector.\ \>", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"ceB", " ", "=", " ", RowBox[{ StyleBox["CE", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox["B", FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{"plot", " ", "=", " ", RowBox[{"ListPlot", "[", RowBox[{"ceB", ",", RowBox[{"PlotStyle", "\[Rule]", "Blue"}]}], "]"}]}], "\[IndentingNewLine]", StyleBox[ RowBox[{ RowBox[{"i", "=", RowBox[{"rows", "*", RowBox[{"cols", "/", "8"}]}]}], ";"}], FontColor->RGBColor[0, 0, 1]], "\[IndentingNewLine]", RowBox[{ RowBox[{"pct", " ", "=", " ", RowBox[{ RowBox[{"Round", "[", RowBox[{ RowBox[{"ceB", "[", RowBox[{"[", "i", "]"}], "]"}], "*", "10000"}], "]"}], "/", "100."}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "pct", ",", "\"\< of the energy is stored in the largest (in absolute value) \>\"", ",", "i", ",", "\"\< elements of B.\>\""}], "]"}], ";"}]}], "Input", CellChangeTimes->{ 3.408567658890625*^9, {3.40857009271875*^9, 3.408570093*^9}, { 3.42163049925*^9, 3.421630499359375*^9}}] }, Open ]], Cell[CellGroupData[{ Cell[" Quantizing with Cumulative Energy", "Section"], Cell[TextData[{ "To quantize with cumulative energy, we will first pick an energy level 0 \ \[LessEqual] p \[LessEqual] 1 and then determine the largest elements (in \ absolute value) in B that comprise p units of the energy. There is a command \ in ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " called ", StyleBox["nCE", FontColor->RGBColor[1, 0, 0]], " that will perform this task. The module takes the cumulative energy \ vector and p and returns the number of elements m from B that constitute p \ units of energy." }], "Text", CellChangeTimes->{{3.408569243609375*^9, 3.408569246203125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"p", "=", ".998"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"k", "=", RowBox[{ StyleBox["nCE", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"ceB", ",", "p"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "\"\\"", ",", "k", ",", "\"\< elements of B constitute \>\"", ",", RowBox[{"100", "*", "p"}], ",", "\"\<% of the energy of B.\>\""}], "]"}], ";"}]}], "Input", CellChangeTimes->{{3.408570096265625*^9, 3.408570096515625*^9}, { 3.42163049765625*^9, 3.421630497796875*^9}}], Cell[TextData[{ "Here is a graphical interpretation of ", StyleBox["nCE", FontColor->RGBColor[1, 0, 0]], "." }], "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"line1", "=", RowBox[{"Graphics", "[", RowBox[{"{", RowBox[{"Red", ",", RowBox[{"Line", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "p"}], "}"}], ",", RowBox[{"{", RowBox[{ RowBox[{"rows", "*", "cols"}], ",", "p"}], "}"}]}], "}"}], "]"}]}], "}"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"line2", "=", RowBox[{"Graphics", "[", RowBox[{"{", RowBox[{"Green", ",", RowBox[{"Line", "[", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{"k", ",", RowBox[{"First", "[", "ceB", "]"}]}], "}"}], ",", RowBox[{"{", RowBox[{"k", ",", "1"}], "}"}]}], "}"}], "]"}]}], "}"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"Show", "[", RowBox[{ RowBox[{"{", RowBox[{"plot", ",", "line1", ",", "line2"}], "}"}], ",", RowBox[{"PlotRange", "\[Rule]", RowBox[{"{", RowBox[{".8", ",", "1"}], "}"}]}]}], "]"}]}], "Input", CellChangeTimes->{ 3.408567684046875*^9, {3.408569294109375*^9, 3.40856937865625*^9}, { 3.408569511171875*^9, 3.40856951296875*^9}, {3.40857009971875*^9, 3.408570100015625*^9}, 3.421630496453125*^9}], Cell[TextData[{ "We next convert all but the largest (in absolute value) k values of B to 0. \ The module in ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " to perform this task is ", StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], ". ", StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], " takes a matrix or vector and the value k and first finds the kth largest \ element (in absolute value) q in the input. ", StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], " then sets to 0 all values in the input that are smaller (in absolute \ value) than q and returns the result.\n\nHere is a simple example of ", StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], "." }], "Text", CellChangeTimes->{{3.40856940790625*^9, 3.40856941015625*^9}}], Cell[BoxData[ RowBox[{ StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{ RowBox[{"{", RowBox[{"1", ",", RowBox[{"-", "2"}], ",", "3", ",", "4", ",", RowBox[{"-", "5"}]}], "}"}], ",", "3"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]], "Input", CellChangeTimes->{{3.40857010321875*^9, 3.408570103515625*^9}, { 3.421630494234375*^9, 3.421630494359375*^9}}], Cell[TextData[{ "For our transform B, here is the result of ", StyleBox["Comp", FontColor->RGBColor[0.501961, 0, 0]], ". Try replacing k by other values (smaller than rows*cols). " }], "Text", CellChangeTimes->{3.408675829125*^9}], Cell[BoxData[{ RowBox[{ RowBox[{"newB", "=", RowBox[{ StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"B", ",", "2500"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ StyleBox["WaveletDensityPlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"newB", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{ 3.4085676899375*^9, {3.408569485625*^9, 3.40856948775*^9}, { 3.408570105671875*^9, 3.40857010596875*^9}, {3.421630492015625*^9, 3.42163049215625*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Lossy Compression", "Section"], Cell["\<\ We are ready to put everything together and compress an image using lossy \ compression. Understand that we can never exactly recover the original image \ using lossy compression. First we read an image and compute its 2D HWT. Feel free to change the image \ or the value for its.\ \>", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"A", "=", RowBox[{ StyleBox["ImageRead", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"gray", "[", RowBox[{"[", "1", "]"}], "]"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ StyleBox["ImagePlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox["A", FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"rows", ",", "cols"}], "}"}], "=", RowBox[{"Dimensions", "[", "A", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", RowBox[{"rows", "*", "cols", "*", "8"}], ",", "\"\<.\>\""}], "]"}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", StyleBox[ RowBox[{ RowBox[{"its", "=", "3"}], ";"}], FontColor->GrayLevel[0]], "\[IndentingNewLine]", StyleBox[ RowBox[{ RowBox[{"h", "=", RowBox[{ RowBox[{"Sqrt", "[", "2", "]"}], "*", RowBox[{"Haar", "[", "]"}]}]}], ";"}], FontColor->GrayLevel[0]], "\[IndentingNewLine]", RowBox[{ RowBox[{"B", "=", RowBox[{ StyleBox["WT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"A", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ StyleBox["WaveletDensityPlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"B", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{{3.408569539859375*^9, 3.408569574734375*^9}, { 3.408569608609375*^9, 3.408569641796875*^9}, {3.408570111015625*^9, 3.408570111421875*^9}, {3.421630490390625*^9, 3.4216304905*^9}}], Cell["\<\ Next we compute the cumulative energy vector and compress it. Feel free to \ change the value for p. I have \"wrapped\" B in N[ ] - this converts the \ input to decimal values and decreases computation time.\ \>", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{ StyleBox["ceB", FontColor->GrayLevel[0]], StyleBox["=", FontColor->GrayLevel[0]], RowBox[{ StyleBox["CE", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"N", "[", "B", "]"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ RowBox[{"ListPlot", "[", RowBox[{"ceB", ",", RowBox[{"PlotStyle", "\[Rule]", "Blue"}]}], "]"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", StyleBox[ RowBox[{ RowBox[{"p", "=", ".9995"}], ";"}], FontColor->RGBColor[0, 0, 1]], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"k", "=", RowBox[{ StyleBox["nCE", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"ceB", ",", "p"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "\"\\"", ",", "k", ",", "\"\< elements of B constitute \>\"", ",", RowBox[{ RowBox[{"Round", "[", RowBox[{"10000", "*", "p"}], "]"}], "/", "100."}], ",", "\"\<% of the energy of B.\>\""}], "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"Print", "[", RowBox[{ RowBox[{ RowBox[{"rows", "*", "cols"}], "-", "k"}], ",", "\"\< of the \>\"", ",", RowBox[{"rows", "*", "cols"}], ",", "\"\< elements of B are now converted to 0.\>\""}], "]"}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newB", "=", RowBox[{ StyleBox["Comp", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"B", ",", "k"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{ 3.40856771003125*^9, {3.40856967328125*^9, 3.408569674015625*^9}, { 3.40856984540625*^9, 3.408569845484375*^9}, {3.408569929984375*^9, 3.408569931796875*^9}, {3.408570116125*^9, 3.40857011640625*^9}, { 3.421630487953125*^9, 3.421630488046875*^9}}], Cell["Now we Huffman encode the modified transform.", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"codes", ",", "bitstream", ",", "encodestream"}], "}"}], "=", RowBox[{ StyleBox["MakeHuffmanCodes", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"Round", "[", RowBox[{"newB", "-", RowBox[{"Min", "[", "newB", "]"}]}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"bpp", " ", "=", " ", RowBox[{"N", "[", RowBox[{"encodestream", "/", RowBox[{"(", RowBox[{"rows", "*", "cols"}], ")"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "\"\\"", ",", "encodestream", ",", "\"\< or \>\"", ",", "bpp", ",", "\"\< bpp!\>\""}], "]"}], ";"}]}], "Input", CellChangeTimes->{{3.408569706046875*^9, 3.408569713390625*^9}, { 3.408570132609375*^9, 3.408570132890625*^9}, {3.421630486125*^9, 3.42163048625*^9}}], Cell["\<\ If we compute the inverse transform, we can see the uncompressed image. We \ plot the original for comparative purposes. Note that we have to divide our \ filter now by Sqrt[2].\ \>", "Text", CellChangeTimes->{{3.408569761703125*^9, 3.40856977325*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"h", "=", RowBox[{ RowBox[{"Haar", "[", "]"}], "/", RowBox[{"Sqrt", "[", "2", "]"}]}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"compressedA", " ", "=", " ", RowBox[{ StyleBox["IWT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"newB", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], StyleBox[";", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ StyleBox["ImagePlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"compressedA", ",", RowBox[{"PlotLabel", "->", "\"\\""}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}], "\[IndentingNewLine]", RowBox[{ StyleBox["ImagePlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"A", ",", RowBox[{"PlotLabel", "->", "\"\\""}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{{3.408569780078125*^9, 3.4085698224375*^9}, { 3.408570134859375*^9, 3.4085701351875*^9}, {3.421630484140625*^9, 3.421630484625*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["To Consider ...", "Section"], Cell["\<\ 1) What happens if you increase the number of iterations? 2) What happens if you increase/decrease the energy level p? 3) Pick an image and then set its and p so that the encoded bit stream \ results in a compression rate of 1.5 bpp. How does the uncompressed image \ look?\ \>", "Text", CellChangeTimes->{3.421629378515625*^9}] }, Open ]], Cell[CellGroupData[{ Cell["Color Image Compression", "Section", CellChangeTimes->{{3.421629388359375*^9, 3.421629395359375*^9}}], Cell["\<\ It is easy to compress color images. We load a color image and then \ convert the R,G,B channels to Y, Cb, Cr. We perform grayscale lossy \ compression on each of Y, Cb, and Cr to obtain modified Y, Cb, and Cr. We \ then convert back to R,G,B.\ \>", "Text", CellChangeTimes->{{3.421629401453125*^9, 3.421629470875*^9}}], Cell[CellGroupData[{ Cell["Load an Image", "Subsection", CellChangeTimes->{{3.421629575765625*^9, 3.421629578265625*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"color", "=", RowBox[{"ImageNames", "[", RowBox[{ RowBox[{"ImageType", "\[Rule]", "Color"}], ",", RowBox[{"ListThumbnails", "\[Rule]", "True"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"r", ",", "g", ",", "b"}], "}"}], "=", RowBox[{"ImageRead", "[", RowBox[{"color", "[", RowBox[{"[", "6", "]"}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"ImagePlot", "[", RowBox[{"{", RowBox[{"r", ",", "g", ",", "b"}], "}"}], "]"}]}], "Input", CellChangeTimes->{{3.421629474234375*^9, 3.42162956340625*^9}, { 3.421630481234375*^9, 3.4216304815625*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Convert to YCbCr Space", "Subsection", CellChangeTimes->{{3.42162958753125*^9, 3.42162959553125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"y", ",", "cb", ",", "cr"}], "}"}], "=", RowBox[{"RGBToYCbCr", "[", RowBox[{ RowBox[{"{", RowBox[{"r", ",", "g", ",", "b"}], "}"}], ",", RowBox[{"DisplayMode", "\[Rule]", "True"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"ImagePlot", "[", "y", "]"}], "\[IndentingNewLine]", RowBox[{"ImagePlot", "[", "cb", "]"}], "\[IndentingNewLine]", RowBox[{"ImagePlot", "[", "cr", "]"}]}], "Input", CellChangeTimes->{{3.421629602796875*^9, 3.42162963784375*^9}, { 3.42163047546875*^9, 3.4216304755625*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Compute the HWT of each channel", "Subsection", CellChangeTimes->{{3.4216296453125*^9, 3.4216296501875*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"h", "=", RowBox[{ RowBox[{"Sqrt", "[", "2.", "]"}], "*", RowBox[{"Haar", "[", "]"}]}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"its", "=", "3"}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"ywt", "=", RowBox[{"WT2D", "[", RowBox[{"y", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"cbwt", "=", RowBox[{"WT2D", "[", RowBox[{"cb", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"crwt", "=", RowBox[{"WT2D", "[", RowBox[{"cr", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{"WaveletDensityPlot", "[", RowBox[{"ywt", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}], "\[IndentingNewLine]", RowBox[{"WaveletDensityPlot", "[", RowBox[{"cbwt", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}], "\[IndentingNewLine]", RowBox[{"WaveletDensityPlot", "[", RowBox[{"crwt", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], "Input", CellChangeTimes->{{3.421629669859375*^9, 3.421629749796875*^9}, { 3.42163047396875*^9, 3.421630474078125*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Use Cumulative Energy to Quantize the Tranforms", "Subsection", CellChangeTimes->{{3.421629762109375*^9, 3.421629773328125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"cey", "=", RowBox[{"CE", "[", "ywt", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"cecb", "=", RowBox[{"CE", "[", "cbwt", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"cecr", "=", RowBox[{"CE", "[", "crwt", "]"}]}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"pct", "=", ".999"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"ky", "=", RowBox[{"nCE", "[", RowBox[{"cey", ",", "pct"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"kcb", "=", RowBox[{"nCE", "[", RowBox[{"cecb", ",", "pct"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"kcr", "=", RowBox[{"nCE", "[", RowBox[{"cecr", ",", "pct"}], "]"}]}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newywt", "=", RowBox[{"Comp", "[", RowBox[{"ywt", ",", "ky"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newcbwt", "=", RowBox[{"Comp", "[", RowBox[{"cbwt", ",", "kcb"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"newcrwt", "=", RowBox[{"Comp", "[", RowBox[{"crwt", ",", "kcr"}], "]"}]}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{"WaveletDensityPlot", "[", RowBox[{"newywt", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}], "\[IndentingNewLine]", RowBox[{"WaveletDensityPlot", "[", RowBox[{"newcbwt", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}], "\[IndentingNewLine]", RowBox[{"WaveletDensityPlot", "[", RowBox[{"newcrwt", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], "Input", CellChangeTimes->{{3.42162977896875*^9, 3.421629907015625*^9}, 3.4216302325*^9, {3.421630472515625*^9, 3.421630472640625*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Encode the Quantized Transformations", "Subsection", CellChangeTimes->{{3.421630061953125*^9, 3.421630069671875*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"codes", ",", "bitstream", ",", "encodestreamy"}], "}"}], "=", RowBox[{ StyleBox["MakeHuffmanCodes", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"Round", "[", RowBox[{"newywt", "-", RowBox[{"Min", "[", "newywt", "]"}]}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"codes", ",", "bitstream", ",", "encodestreamcb"}], "}"}], "=", RowBox[{ StyleBox["MakeHuffmanCodes", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"Round", "[", RowBox[{"newcbwt", "-", RowBox[{"Min", "[", "newcbwt", "]"}]}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"codes", ",", "bitstream", ",", "encodestreamcr"}], "}"}], "=", RowBox[{ StyleBox["MakeHuffmanCodes", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"Round", "[", RowBox[{"newcrwt", "-", RowBox[{"Min", "[", "newcrwt", "]"}]}], "]"}], "]"}]}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"bpp", " ", "=", " ", RowBox[{"N", "[", RowBox[{ RowBox[{"(", RowBox[{"encodestreamy", "+", "encodestreamcb", "+", "encodestreamcr"}], ")"}], "/", RowBox[{"(", RowBox[{"3", "*", "rows", "*", "cols"}], ")"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"Print", "[", RowBox[{ "\"\\"", ",", "bpp", ",", "\"\< bpp!\>\""}], "]"}], ";"}]}], "Input", CellChangeTimes->{{3.42162993828125*^9, 3.42163002540625*^9}, 3.421630080484375*^9, {3.4216304701875*^9, 3.4216304703125*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Compute the Inverse Transformations", "Subsection", CellChangeTimes->{{3.421630103859375*^9, 3.421630112328125*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"h", "=", RowBox[{ RowBox[{"Haar", "[", "]"}], "/", RowBox[{"Sqrt", "[", "2.", "]"}]}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newy", "=", RowBox[{"IWT2D", "[", RowBox[{"newywt", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newcb", "=", RowBox[{"IWT2D", "[", RowBox[{"newcbwt", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newcr", "=", RowBox[{"IWT2D", "[", RowBox[{"newcrwt", ",", "h", ",", RowBox[{"NumIterations", "\[Rule]", "its"}]}], "]"}]}], ";"}]}], "Input",\ CellChangeTimes->{{3.421630117234375*^9, 3.42163016275*^9}, { 3.421630468796875*^9, 3.4216304689375*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Convert back to R, G, B", "Subsection", CellChangeTimes->{{3.42163016871875*^9, 3.421630172140625*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"{", RowBox[{"newr", ",", "newg", ",", "newb"}], "}"}], "=", RowBox[{"YCbCrToRGB", "[", RowBox[{ RowBox[{"{", RowBox[{"newy", ",", "newcb", ",", "newcr"}], "}"}], ",", RowBox[{"DisplayMode", "\[Rule]", "True"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"ImagePlot", "[", RowBox[{"{", RowBox[{"newr", ",", "newg", ",", "newb"}], "}"}], "]"}], "\[IndentingNewLine]", RowBox[{"ImagePlot", "[", RowBox[{"{", RowBox[{"r", ",", "g", ",", "b"}], "}"}], "]"}], "\[IndentingNewLine]", RowBox[{"PSNR", "[", RowBox[{ RowBox[{"{", RowBox[{"r", ",", "g", ",", "b"}], "}"}], ",", RowBox[{"{", RowBox[{"newr", ",", "newg", ",", "newb"}], "}"}]}], "]"}]}], "Input", CellChangeTimes->{{3.421630177234375*^9, 3.421630216125*^9}, { 3.421630351078125*^9, 3.421630377234375*^9}, {3.421630467125*^9, 3.421630467375*^9}}] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["To Consider ...", "Section"], Cell["\<\ 1) What happens if you increase the number of iterations? 2) What happens if you increase/decrease the energy level p? 3) Pick an image and then set its and p so that the encoded bit stream \ results in a compression rate of 2 bpp. How does the uncompressed image \ look? 4) Can you pick different percentages for quantizing the different \ wavelet-transformed channels and achieve better results?\ \>", "Text", CellChangeTimes->{ 3.421629378515625*^9, {3.421630413296875*^9, 3.421630457484375*^9}}] }, Open ]] }, Open ]] }, WindowSize->{1272, 683}, WindowMargins->{{1, Automatic}, {Automatic, 3}}, ShowSelection->True, FrontEndVersion->"6.0 for Microsoft Windows (32-bit) (April 20, 2007)", StyleDefinitions->FrontEnd`FileName[{"Creative"}, "NaturalColor.nb", CharacterEncoding -> "WindowsANSI"] ] (* End of Notebook Content *) (* Internal cache information *) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[590, 23, 39, 0, 73, "Title"], Cell[632, 25, 149, 5, 96, "Subtitle"], Cell[784, 32, 158, 6, 89, "Subsubtitle"], Cell[CellGroupData[{ Cell[967, 42, 28, 0, 75, "Section"], Cell[998, 44, 133, 3, 29, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[1168, 52, 30, 0, 75, "Section"], Cell[1201, 54, 1259, 28, 101, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[2497, 87, 82, 1, 75, "Section"], Cell[2582, 90, 278, 4, 41, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[2897, 99, 147, 2, 75, "Section"], Cell[3047, 103, 360, 10, 29, "Text"], Cell[3410, 115, 358, 7, 41, "Input"], Cell[3771, 124, 226, 6, 29, "Text"], Cell[4000, 132, 273, 6, 41, "Input"], Cell[4276, 140, 562, 12, 47, "Text"], Cell[4841, 154, 606, 15, 62, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[5484, 174, 110, 1, 75, "Section"], Cell[5597, 177, 205, 4, 29, "Text"], Cell[5805, 183, 525, 13, 62, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[6367, 201, 48, 0, 75, "Section"], Cell[6418, 203, 653, 12, 65, "Text"], Cell[7074, 217, 1381, 44, 102, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[8492, 266, 39, 0, 75, "Section"], Cell[8534, 268, 448, 10, 47, "Text"], Cell[8985, 280, 1763, 46, 142, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[10785, 331, 33, 0, 75, "Section"], Cell[10821, 333, 170, 5, 65, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[11028, 343, 36, 0, 75, "Section"], Cell[11067, 345, 251, 4, 47, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[11355, 354, 36, 0, 75, "Section"], Cell[11394, 356, 442, 10, 65, "Text"], Cell[11839, 368, 613, 19, 62, "Input"], Cell[12455, 389, 197, 4, 29, "Text"], Cell[12655, 395, 1270, 41, 122, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[13962, 441, 53, 0, 75, "Section"], Cell[14018, 443, 629, 14, 47, "Text"], Cell[14650, 459, 809, 25, 82, "Input"], Cell[15462, 486, 125, 5, 29, "Text"], Cell[15590, 493, 1294, 39, 82, "Input"], Cell[16887, 534, 773, 21, 83, "Text"], Cell[17663, 557, 489, 16, 41, "Input"], Cell[18155, 575, 238, 6, 29, "Text"], Cell[18396, 583, 852, 29, 62, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[19285, 617, 36, 0, 75, "Section"], Cell[19324, 619, 307, 7, 65, "Text"], Cell[19634, 628, 2269, 75, 202, "Input"], Cell[21906, 705, 233, 4, 29, "Text"], Cell[22142, 711, 2435, 81, 222, "Input"], Cell[24580, 794, 61, 0, 29, "Text"], Cell[24644, 796, 938, 27, 82, "Input"], Cell[25585, 825, 265, 5, 29, "Text"], Cell[25853, 832, 1380, 45, 102, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[27270, 882, 34, 0, 75, "Section"], Cell[27307, 884, 344, 9, 101, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[27688, 898, 108, 1, 75, "Section"], Cell[27799, 901, 335, 6, 47, "Text"], Cell[CellGroupData[{ Cell[28159, 911, 101, 1, 37, "Subsection"], Cell[28263, 914, 687, 19, 82, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[28987, 938, 108, 1, 37, "Subsection"], Cell[29098, 941, 606, 15, 102, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[29741, 961, 115, 1, 37, "Subsection"], Cell[29859, 964, 1412, 41, 222, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[31308, 1010, 135, 1, 37, "Subsection"], Cell[31446, 1013, 1877, 54, 342, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[33360, 1072, 124, 1, 37, "Subsection"], Cell[33487, 1075, 1718, 51, 142, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[35242, 1131, 123, 1, 37, "Subsection"], Cell[35368, 1134, 846, 25, 102, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[36251, 1164, 110, 1, 37, "Subsection"], Cell[36364, 1167, 937, 26, 102, "Input"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[37350, 1199, 34, 0, 75, "Section"], Cell[37387, 1201, 518, 13, 137, "Text"] }, Open ]] }, Open ]] } ] *) (* End of internal cache information *)