(* 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[ 19351, 626] NotebookOptionsPosition[ 17145, 553] NotebookOutlinePosition[ 17563, 569] CellTagsIndexPosition[ 17520, 566] WindowFrame->Normal ContainsDynamic->False*) (* Beginning of Notebook Content *) Notebook[{ Cell[CellGroupData[{ Cell["Haar Edge Detection", "Subtitle"], 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 edge detection \ 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.408637057625*^9, 3.40863705796875*^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.40863706003125*^9, 3.408637060125*^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.408637061796875*^9, 3.40863706196875*^9}}], Cell[TextData[{ StyleBox["NOTE:", FontWeight->"Bold"], " In ", StyleBox["Mathematica", FontSlant->"Italic"], " 5.2, ShowThumbnails does not exist - use the following command." }], "Text", CellChangeTimes->{{3.408635831734375*^9, 3.408635924390625*^9}, { 3.40863602578125*^9, 3.408636028421875*^9}}], Cell[BoxData[ RowBox[{ RowBox[{ StyleBox["ImageNames", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{ RowBox[{"ImageType", "\[Rule]", "GrayScale"}], ",", RowBox[{"Thumbnails", "\[Rule]", "True"}]}], "]"}], ";"}]], "Input", CellChangeTimes->{{3.408635940671875*^9, 3.4086359565625*^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[{"ImageType", "\[Rule]", "GrayScale"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{"gray", "[", RowBox[{"[", "15", "]"}], "]"}]}], "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.40863604059375*^9, 3.408636053265625*^9}, {3.4086370664375*^9, 3.408637066578125*^9}, {3.421627983828125*^9, 3.421627983921875*^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 fifteenth image in the list.\ \>", "Text", CellChangeTimes->{{3.408566678375*^9, 3.408566710125*^9}, { 3.408674578578125*^9, 3.408674579640625*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"A", "=", RowBox[{ StyleBox["ImageRead", FontColor->RGBColor[1, 0, 0]], "[", RowBox[{"gray", "[", RowBox[{"[", "15", "]"}], "]"}], "]"}]}], ";"}], "\[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.40863604653125*^9, {3.408637068703125*^9, 3.408637068828125*^9}, {3.421627981984375*^9, 3.42162798228125*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["Edge Detection", "Section"], Cell["\<\ To perform edge detection on the image, we first compute the 2D HWT.\ \>", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"B", " ", "=", StyleBox[" ", FontColor->GrayLevel[0]], RowBox[{ StyleBox["HWT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->RGBColor[0.501961, 0, 0]], StyleBox[ RowBox[{ RowBox[{"N", "[", "A", "]"}], ",", RowBox[{"NumIterations", "\[Rule]", "1"}]}], FontColor->RGBColor[0.501961, 0, 0]], StyleBox["]", FontColor->RGBColor[0.501961, 0, 0]]}]}], StyleBox[";", FontColor->RGBColor[0.501961, 0, 0]]}], "\[IndentingNewLine]", StyleBox[ RowBox[{"WaveletDensityPlot", "[", RowBox[{"B", ",", RowBox[{"NumIterations", "\[Rule]", "1"}]}], "]"}], FontColor->RGBColor[0.501961, 0, 0]]}], "Input", CellChangeTimes->{{3.40863576359375*^9, 3.408635790390625*^9}, { 3.40863606578125*^9, 3.40863609296875*^9}, {3.408637070234375*^9, 3.408637070359375*^9}, {3.421627980453125*^9, 3.4216279805625*^9}}], Cell[TextData[{ "The next step is to replace the upper left hand corner with a zero matrix \ of the same dimensions. The ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " module ", StyleBox["PutCorner", FontColor->RGBColor[1, 0, 0]], " will help here. ", StyleBox["PutCorner", FontColor->RGBColor[1, 0, 0]], " takes two arguments and replaces the upper left hand corner of the first \ argument with the second argument." }], "Text", CellChangeTimes->{{3.4086361470625*^9, 3.408636162890625*^9}, { 3.408636291421875*^9, 3.408636295875*^9}, {3.42162785796875*^9, 3.42162786034375*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{"Z", " ", "=", " ", RowBox[{"ConstantArray", "[", RowBox[{"0", ",", RowBox[{ RowBox[{"Dimensions", "[", "A", "]"}], "/", "2"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newB", " ", "=", RowBox[{ StyleBox["PutCorner", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"B", ",", "Z"}], 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]", "1"}]}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{{3.408636116109375*^9, 3.408636138421875*^9}, { 3.40863619628125*^9, 3.408636197921875*^9}, 3.408636320109375*^9, { 3.40863707240625*^9, 3.408637072515625*^9}, {3.421627978828125*^9, 3.421627978984375*^9}}], Cell["\<\ We are left with the vertical, horizontal, and diagonal differences. We \ compute the inverse of the modified transform to obtain the edges.\ \>", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"edges", " ", "=", " ", RowBox[{ StyleBox["IHWT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"newB", ",", RowBox[{"NumIterations", "\[Rule]", "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["edges", FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{{3.40863635059375*^9, 3.40863635409375*^9}, { 3.4086364156875*^9, 3.40863644528125*^9}, {3.408637076015625*^9, 3.408637076109375*^9}, {3.421627976296875*^9, 3.421627976640625*^9}}], Cell["\<\ Sometimes it is easier to look at the image negative to identify the edges.\ \>", "Text", CellChangeTimes->{{3.408636381578125*^9, 3.40863639821875*^9}}], Cell[BoxData[ RowBox[{ StyleBox["ImagePlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"255", "-", "edges"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]], "Input", CellChangeTimes->{{3.40863641071875*^9, 3.40863643565625*^9}, { 3.40863707796875*^9, 3.408637078015625*^9}, {3.421627975*^9, 3.421627975140625*^9}}], Cell["Try the procedure again with different images.", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Iterating the Process", "Section"], Cell["\<\ You can use the iterated transform as part of the algorithm. \ \>", "Text"], Cell[BoxData[{ RowBox[{ StyleBox[ RowBox[{"its", "=", "3"}], FontColor->GrayLevel[0]], StyleBox[";", FontColor->GrayLevel[0]], StyleBox[" ", FontColor->RGBColor[0, 0, 1]], RowBox[{"(*", " ", RowBox[{ "Do", " ", "not", " ", "exceed", " ", "the", " ", "maximum", " ", "number", " ", "of", " ", "iterations", " ", RowBox[{"allowed", "!!"}]}], " ", "*)"}], "\[IndentingNewLine]", RowBox[{"B", " ", "=", StyleBox[" ", FontColor->RGBColor[0.501961, 0, 0]], RowBox[{ StyleBox["HWT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{ RowBox[{"N", "[", "A", "]"}], ",", 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.40863570909375*^9, 3.408635730109375*^9}, { 3.408636465328125*^9, 3.40863648075*^9}, {3.40863665140625*^9, 3.408636656296875*^9}, {3.40863707978125*^9, 3.408637079859375*^9}, { 3.4216279726875*^9, 3.42162797284375*^9}}], Cell[TextData[{ "The next step is to replace the upper left hand corner with a zero matrix \ of the same dimensions. The ", StyleBox["DiscreteWavelets", FontColor->RGBColor[1, 0, 0]], " module ", StyleBox["PutCorner", FontColor->RGBColor[1, 0, 0]], " will help here. ", StyleBox["PutCorner", FontColor->RGBColor[1, 0, 0]], " takes two arguments and replaces the upper left hand corner of the first \ argument with the second argument." }], "Text", CellChangeTimes->{{3.4086361470625*^9, 3.408636162890625*^9}, { 3.408636291421875*^9, 3.408636295875*^9}, 3.4216278758125*^9}], Cell[BoxData[{ RowBox[{ RowBox[{"Z", " ", "=", " ", RowBox[{"ConstantArray", "[", RowBox[{"0", ",", RowBox[{ RowBox[{"Dimensions", "[", "A", "]"}], "/", RowBox[{"2", "^", "its"}]}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"newB", " ", "=", RowBox[{ StyleBox["PutCorner", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"B", ",", "Z"}], 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.408636116109375*^9, 3.408636138421875*^9}, { 3.40863619628125*^9, 3.408636197921875*^9}, 3.408636320109375*^9, { 3.40863682615625*^9, 3.40863684296875*^9}, {3.40863708178125*^9, 3.408637081859375*^9}, {3.421627970921875*^9, 3.4216279710625*^9}}], Cell["Compute the inverse transformation to find the edges.", "Text", CellChangeTimes->{{3.408636859984375*^9, 3.40863686921875*^9}}], Cell[BoxData[{ RowBox[{ RowBox[{ StyleBox["edges", FontColor->GrayLevel[0]], StyleBox["=", FontColor->GrayLevel[0]], RowBox[{ StyleBox["IHWT2D", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"newB", ",", 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["edges", FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}], "Input", CellChangeTimes->{{3.40863570909375*^9, 3.408635730109375*^9}, { 3.408636465328125*^9, 3.40863648075*^9}, 3.408636526453125*^9, { 3.40863687621875*^9, 3.408636882453125*^9}, {3.40863691303125*^9, 3.408636920734375*^9}, {3.408637084171875*^9, 3.408637084296875*^9}, { 3.421627968296875*^9, 3.421627968453125*^9}}], Cell["\<\ Sometimes it is easier to look at the image negative to identify the edges.\ \>", "Text", CellChangeTimes->{{3.408636381578125*^9, 3.40863639821875*^9}}], Cell[BoxData[ RowBox[{ StyleBox["ImagePlot", FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{"255", "-", "edges"}], FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]], "Input", CellChangeTimes->{{3.40863641071875*^9, 3.40863643565625*^9}, { 3.408637086375*^9, 3.40863708659375*^9}, {3.42162796678125*^9, 3.421627967*^9}}] }, Open ]], Cell[CellGroupData[{ Cell["To Consider ...", "Section"], Cell["\<\ 1) What happens to the edge image if you increase the number of iterations? 2) Why do you suppose this happens? 3) How could you modify the process to improve the identification of edges?\ \>", "Text"] }, Open ]] }, Open ]] }, WindowSize->{1272, 683}, WindowMargins->{{0, Automatic}, {Automatic, 0}}, 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, 36, "Subtitle"], 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, 136, 3, 29, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[1171, 52, 30, 0, 75, "Section"], Cell[1204, 54, 1259, 28, 101, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[2500, 87, 82, 1, 75, "Section"], Cell[2585, 90, 281, 4, 41, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[2903, 99, 147, 2, 75, "Section"], Cell[3053, 103, 360, 10, 29, "Text"], Cell[3416, 115, 356, 7, 41, "Input"], Cell[3775, 124, 226, 6, 29, "Text"], Cell[4004, 132, 272, 6, 41, "Input"], Cell[4279, 140, 310, 9, 29, "Text"], Cell[4592, 151, 307, 8, 41, "Input"], Cell[4902, 161, 562, 12, 47, "Text"], Cell[5467, 175, 628, 14, 62, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[6132, 194, 110, 1, 75, "Section"], Cell[6245, 197, 258, 5, 29, "Text"], Cell[6506, 204, 599, 14, 62, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[7142, 223, 33, 0, 75, "Section"], Cell[7178, 225, 92, 2, 29, "Text"], Cell[7273, 229, 928, 26, 62, "Input"], Cell[8204, 257, 619, 16, 47, "Text"], Cell[8826, 275, 1127, 36, 82, "Input"], Cell[9956, 313, 165, 3, 29, "Text"], Cell[10124, 318, 858, 27, 62, "Input"], Cell[10985, 347, 164, 3, 29, "Text"], Cell[11152, 352, 416, 13, 41, "Input"], Cell[11571, 367, 62, 0, 29, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[11670, 372, 40, 0, 75, "Section"], Cell[11713, 374, 86, 2, 29, "Text"], Cell[11802, 378, 1450, 45, 82, "Input"], Cell[13255, 425, 593, 15, 47, "Text"], Cell[13851, 442, 1197, 36, 82, "Input"], Cell[15051, 480, 134, 1, 29, "Text"], Cell[15188, 483, 1058, 33, 62, "Input"], Cell[16249, 518, 164, 3, 29, "Text"], Cell[16416, 523, 412, 13, 41, "Input"] }, Open ]], Cell[CellGroupData[{ Cell[16865, 541, 34, 0, 75, "Section"], Cell[16902, 543, 215, 6, 101, "Text"] }, Open ]] }, Open ]] } ] *) (* End of internal cache information *)