diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7cfba08 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,56 @@ +PROJECT(PD-Flow) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4) +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) # Required by CMake 2.7+ +endif(COMMAND cmake_policy) + + +FIND_PACKAGE(MRPT REQUIRED base gui opengl slam maps) +FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(CUDA REQUIRED) + +INCLUDE_DIRECTORIES($ENV{OPENNI2_INCLUDE}) +LINK_DIRECTORIES($ENV{OPENNI2_LIB}) +#SET(OpenNI_lib "/usr/lib/libOpenNI2.so") +SET(OpenNI_lib "C:/Users/Mariano/Programas/OpenNI2_32/Lib/OpenNI2.lib") + +INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS}) +#set(CUDA_NVCC_FLAGS "-arch=sm_30 -O3 -use_fast_math") +set(CUDA_NVCC_FLAGS "-arch=sm_30") +#set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-gencode arch=compute_35,code=sm_35) +CUDA_ADD_LIBRARY(pdflow_cudalib pdflow_cudalib.h pdflow_cudalib.cu) +#message( ${CUDA_LIBRARIES} ) + + +ADD_EXECUTABLE(Scene-Flow-Visualization + main_scene_flow_visualization.cpp + scene_flow_visualization.cpp + scene_flow_visualization.h + legend_pdflow.xpm) + +TARGET_LINK_LIBRARIES(Scene-Flow-Visualization + ${MRPT_LIBS} + ${CUDA_LIBRARIES} + ${OpenNI_lib} + pdflow_cudalib) + +ADD_EXECUTABLE(Scene-Flow-Impair + main_scene_flow_impair.cpp + scene_flow_impair.cpp + scene_flow_impair.h + ) + +TARGET_LINK_LIBRARIES(Scene-Flow-Impair + ${OpenCV_LIBS} + ${CUDA_LIBRARIES} + ${MRPT_LIBS} + pdflow_cudalib) + + + +# Set optimized building: +IF(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_BUILD_TYPE MATCHES "Debug") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mtune=native") +ENDIF(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_BUILD_TYPE MATCHES "Debug") + diff --git a/legend_pdflow.xpm b/legend_pdflow.xpm new file mode 100644 index 0000000..d92e351 --- /dev/null +++ b/legend_pdflow.xpm @@ -0,0 +1,729 @@ +/* XPM */ +static const char * legend_pdflow_xpm[] = { +"201 252 474 2", +" c #404040", +". c #575757", +"+ c #828282", +"@ c #636363", +"# c #FFFFFF", +"$ c #A4A4A4", +"% c #727272", +"& c #090909", +"* c #4C4C4C", +"= c #E4E4E4", +"- c #FAFAFA", +"; c #858585", +"> c #414141", +", c #EEEEEE", +"' c #FCFCFC", +") c #6B6B6B", +"! c #313131", +"~ c #C1C1C1", +"{ c #6F6F6F", +"] c #2E2E2E", +"^ c #BCBCBC", +"/ c #848484", +"( c #000000", +"_ c #171717", +": c #9D9D9D", +"< c #F4F4F4", +"[ c #7E7E7E", +"} c #484848", +"| c #DEDEDE", +"1 c #EDEDED", +"2 c #E2E2E2", +"3 c #7C7C7C", +"4 c #C8C8C8", +"5 c #E1E1E1", +"6 c #7F7F7F", +"7 c #454545", +"8 c #C4C4C4", +"9 c #A6A6A6", +"0 c #0C0C0C", +"a c #1B1B1B", +"b c #3E3E3E", +"c c #D4D4D4", +"d c #909090", +"e c #5F5F5F", +"f c #E7E7E7", +"g c #737373", +"h c #303030", +"i c #E9E9E9", +"j c #787878", +"k c #292929", +"l c #E8E8E8", +"m c #2D2D2D", +"n c #767676", +"o c #131313", +"p c #F6F6F6", +"q c #F7F7F7", +"r c #323232", +"s c #393939", +"t c #A3A3A3", +"u c #565656", +"v c #D2D2D2", +"w c #DDDDDD", +"x c #5B5B5B", +"y c #363636", +"z c #C3C3C3", +"A c #242424", +"B c #D3D3D3", +"C c #A8A8A8", +"D c #5C5C5C", +"E c #606060", +"F c #BFBFBF", +"G c #5A5A5A", +"H c #AAAAAA", +"I c #F8F8F8", +"J c #FDFDFD", +"K c #C9C9C9", +"L c #5E5E5E", +"M c #FEFEFE", +"N c #F9F9F9", +"O c #9A9A9A", +"P c #585858", +"Q c #646464", +"R c #BEBEBE", +"S c #B5B5B5", +"T c #050505", +"U c #101010", +"V c #4E4E4E", +"W c #E5E5E5", +"X c #D5D5D5", +"Y c #F2F2F2", +"Z c #8C8C8C", +"` c #EAEAEA", +" . c #959595", +".. c #939393", +"+. c #626262", +"@. c #F3F3F3", +"#. c #9B9B9B", +"$. c #919191", +"%. c #BABABA", +"&. c #080808", +"*. c #0E0E0E", +"=. c #D1D1D1", +"-. c #C7C7C7", +";. c #6C6C6C", +">. c #E3E3E3", +",. c #9C9C9C", +"'. c #6A6A6A", +"). c #141414", +"!. c #666666", +"~. c #525252", +"{. c #202020", +"]. c #373737", +"^. c #989898", +"/. c #161616", +"(. c #595959", +"_. c #EBEBEB", +":. c #4F4F4F", +"<. c #D6D6D6", +"[. c #B2B2B2", +"}. c #777777", +"|. c #A7A7A7", +"1. c #020202", +"2. c #555555", +"3. c #F0F0F0", +"4. c #CDCDCD", +"5. c #3D3D3D", +"6. c #BBBBBB", +"7. c #4A4A4A", +"8. c #515151", +"9. c #ECECEC", +"0. c #7B7B7B", +"a. c #494949", +"b. c #979797", +"c. c #191919", +"d. c #282828", +"e. c #DBDBDB", +"f. c #2A2A2A", +"g. c #CECECE", +"h. c #333333", +"i. c #505050", +"j. c #A2A2A2", +"k. c #212121", +"l. c #696969", +"m. c #262626", +"n. c #D7D7D7", +"o. c #B1B1B1", +"p. c #2B2B2B", +"q. c #6E6E6E", +"r. c #D0D0D0", +"s. c #3B3B3B", +"t. c #151515", +"u. c #A5A5A5", +"v. c #222222", +"w. c #343434", +"x. c #969696", +"y. c #C6C6C6", +"z. c #464646", +"A. c #272727", +"B. c #444444", +"C. c #B0B0B0", +"D. c #949494", +"E. c #111111", +"F. c #FBFBFB", +"G. c #010101", +"H. c #ACACAC", +"I. c #E6E6E6", +"J. c #383838", +"K. c #4D4D4D", +"L. c #0B0B0B", +"M. c #B4B4B4", +"N. c #545454", +"O. c #1C1C1C", +"P. c #8B8B8B", +"Q. c #2F2F2F", +"R. c #717171", +"S. c #F5F5F5", +"T. c #9F9F9F", +"U. c #868686", +"V. c #8D8D8D", +"W. c #060606", +"X. c #E0E0E0", +"Y. c #0F0F0F", +"Z. c #0A0A0A", +"`. c #676767", +" + c #B6B6B6", +".+ c #CACACA", +"++ c #121212", +"@+ c #898989", +"#+ c #1A1A1A", +"$+ c #232323", +"%+ c #6D6D6D", +"&+ c #353535", +"*+ c #DCDCDC", +"=+ c #DADADA", +"-+ c #8E8E8E", +";+ c #888888", +">+ c #CBCBCB", +",+ c #424242", +"'+ c #ABABAB", +")+ c #1E1E1E", +"!+ c #535353", +"~+ c #ADADAD", +"{+ c #434343", +"]+ c #3A3A3A", +"^+ c #DFDFDF", +"/+ c #A9A9A9", +"(+ c #7D7D7D", +"_+ c #757575", +":+ c #F1F1F1", +"<+ c #1F1F1F", +"[+ c #040404", +"}+ c #929292", +"|+ c #2C2C2C", +"1+ c #818181", +"2+ c #5D5D5D", +"3+ c #8F8F8F", +"4+ c #797979", +"5+ c #070707", +"6+ c #4B4B4B", +"7+ c #999999", +"8+ c #C5C5C5", +"9+ c #B9B9B9", +"0+ c #252525", +"a+ c #656565", +"b+ c #BDBDBD", +"c+ c #D9D9D9", +"d+ c #B7B7B7", +"e+ c #030303", +"f+ c #747474", +"g+ c #474747", +"h+ c #EFEFEF", +"i+ c #B8B8B8", +"j+ c #AEAEAE", +"k+ c #8A8A8A", +"l+ c #CCCCCC", +"m+ c #3F3F3F", +"n+ c #0D0D0D", +"o+ c #181818", +"p+ c #C2C2C2", +"q+ c #3C3C3C", +"r+ c #7A7A7A", +"s+ c #707070", +"t+ c #B3B3B3", +"u+ c #D8D8D8", +"v+ c #A0A0A0", +"w+ c #9E9E9E", +"x+ c #878787", +"y+ c #A1A1A1", +"z+ c #686868", +"A+ c #1D1D1D", +"B+ c #CFCFCF", +"C+ c #C0C0C0", +"D+ c #616161", +"E+ c #838383", +"F+ c #AFAFAF", +"G+ c #808080", +"H+ c #EBEBF9", +"I+ c #9F9FE5", +"J+ c #7E7EDC", +"K+ c #9E9EE5", +"L+ c #F1F1FB", +"M+ c #D7D7F1", +"N+ c #4D4DCE", +"O+ c #1212C0", +"P+ c #4A4ACE", +"Q+ c #E2E2F4", +"R+ c #D1D1EB", +"S+ c #4A4ACA", +"T+ c #4747CA", +"U+ c #DCDCEE", +"V+ c #CACAE5", +"W+ c #4747C8", +"X+ c #4444C7", +"Y+ c #D6D6E7", +"Z+ c #C7C7E1", +"`+ c #4545C6", +" @ c #4242C5", +".@ c #D2D2E4", +"+@ c #C5C5E0", +"@@ c #4444C5", +"#@ c #D1D1E3", +"$@ c #D8D8E3", +"%@ c #9494CA", +"&@ c #7474BC", +"*@ c #6F6FB7", +"=@ c #6D6DB5", +"-@ c #9393CA", +";@ c #DDDDE5", +">@ c #FAF2F2", +",@ c #ECCBCA", +"'@ c #E4AEAD", +")@ c #E1A3A2", +"!@ c #E6B6B5", +"~@ c #EED4D4", +"{@ c #FCF9F9", +"]@ c #F0D9D9", +"^@ c #D67574", +"/@ c #DC4C4A", +"(@ c #E42E2D", +"_@ c #E82624", +":@ c #E23533", +"<@ c #DA5655", +"[@ c #DA908E", +"}@ c #F4E6E6", +"|@ c #E3B2B1", +"1@ c #D04F4C", +"2@ c #F50D0D", +"3@ c #FD0202", +"4@ c #FE0101", +"5@ c #FC0404", +"6@ c #ED1D1C", +"7@ c #D66E6C", +"8@ c #F0D5D4", +"9@ c #FDFCFC", +"0@ c #EDD3D3", +"a@ c #D45350", +"b@ c #FF0000", +"c@ c #EE1A19", +"d@ c #DD7E7D", +"e@ c #F5E8E8", +"f@ c #F4EBEB", +"g@ c #D87776", +"h@ c #F40F0F", +"i@ c #E12A2A", +"j@ c #E4AFAE", +"k@ c #FBF9F9", +"l@ c #E5C2C2", +"m@ c #DD4846", +"n@ c #FB0505", +"o@ c #F11010", +"p@ c #D56463", +"q@ c #F5F2F2", +"r@ c #DCA7A6", +"s@ c #E32C2B", +"t@ c #FD0302", +"u@ c #FA0606", +"v@ c #CF4644", +"w@ c #EDE9E9", +"x@ c #D69B9A", +"y@ c #E7201F", +"z@ c #CC3D3B", +"A@ c #E7E3E2", +"B@ c #D5A4A3", +"C@ c #DF2F2F", +"D@ c #FC0303", +"E@ c #F80909", +"F@ c #CD4846", +"G@ c #E2DEDE", +"H@ c #D5BBBB", +"I@ c #D4514F", +"J@ c #FA0706", +"K@ c #EC1716", +"L@ c #CB6E6C", +"M@ c #E1DFDF", +"N@ c #DAD5D5", +"O@ c #C78281", +"P@ c #EA2120", +"Q@ c #FA0807", +"R@ c #D93F3D", +"S@ c #CAA6A5", +"T@ c #E3E2E2", +"U@ c #C8B8B8", +"V@ c #CA5C5A", +"W@ c #FB0606", +"X@ c #E12D2B", +"Y@ c #C77D7B", +"Z@ c #D0C9C9", +"`@ c #C0A7A7", +" # c #C56362", +".# c #DE302F", +"+# c #F10F0F", +"@# c #F90807", +"## c #ED1614", +"$# c #D63F3D", +"%# c #C27977", +"&# c #C6B8B7", +"*# c #DCDBDB", +"=# c #BCB2B2", +"-# c #B98B89", +";# c #C35654", +"># c #C64543", +",# c #C6413F", +"'# c #C64745", +")# c #C15F5D", +"!# c #B89999", +"~# c #C1BCBC", +"{# c #F3FBFE", +"]# c #CEEFFB", +"^# c #B3E7F9", +"/# c #A9E4F9", +"(# c #BAE9FA", +"_# c #D6F2FB", +":# c #FAFDFE", +"<# c #D7F2FB", +"[# c #6CD1F6", +"}# c #3CC2F3", +"|# c #1DB9F1", +"1# c #13B6F1", +"2# c #25BCF2", +"3# c #47C6F4", +"4# c #89DAF7", +"5# c #E5F6FC", +"6# c #ABE2F7", +"7# c #38C2F4", +"8# c #06B2F0", +"9# c #02B0F0", +"0# c #00B0F0", +"a# c #03B1F0", +"b# c #12B6F1", +"c# c #5ECCF4", +"d# c #D2F0FA", +"e# c #D6EFF8", +"f# c #2DBEF3", +"g# c #01B0F0", +"h# c #0BB4F1", +"i# c #6CD0F3", +"j# c #E9F6FA", +"k# c #F0F7F9", +"l# c #54C8F4", +"m# c #AAE2F5", +"n# c #FAFBFC", +"o# c #B4E2F3", +"p# c #27BAF0", +"q# c #41C1EF", +"r# c #F2F5F7", +"s# c #8FD6F0", +"t# c #10B4EF", +"u# c #15B5EE", +"v# c #E9EEF0", +"w# c #7BCEED", +"x# c #06B1EF", +"y# c #E1E7E9", +"z# c #85CEE8", +"A# c #0EB2EE", +"B# c #11B3ED", +"C# c #DDE2E4", +"D# c #A5D0E0", +"E# c #23B6EB", +"F# c #3AB9E6", +"G# c #DDE1E2", +"H# c #CED8DB", +"I# c #4DBDE5", +"J# c #11B4EF", +"K# c #88C3D9", +"L# c #A3C4D0", +"M# c #28B5E8", +"N# c #03B2F1", +"O# c #0BB2EE", +"P# c #51B7DC", +"Q# c #BFCDD3", +"R# c #81BACF", +"S# c #30B3E2", +"T# c #07B3F1", +"U# c #01B1F0", +"V# c #49B4DA", +"W# c #A5C2CC", +"X# c #D9DADA", +"Y# c #9AB8C3", +"Z# c #5CB2D2", +"`# c #1DAFE4", +" $ c #06B0ED", +".$ c #0BB0EC", +"+$ c #28B0E1", +"@$ c #71B4CC", +"#$ c #ABBEC5", +"$$ c #D1D1D2", +"%$ c #C9CACA", +"&$ c #B5BCBF", +"*$ c #A1B4BB", +"=$ c #99B1BA", +"-$ c #97B0B9", +";$ c #9BB2BA", +">$ c #A6B7BD", +",$ c #BCC0C1", +" ", +" ", +" . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # % & & * = # # - ; & & > , # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ' ) ! ~ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # { ] ^ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # / ( _ : - # # < [ } | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1 2 ' # # # ' 3 } 4 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # , 5 ' # # # # 6 7 8 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 9 0 a b c # # - d e f # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # g h i # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # j k l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 9 m n o ; p # - d e f # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # q r h i # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # q s k l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # p t . u v w x u j l # # # # # # # # # # # # # # # # # # # # # # # 9 y z } A B # - d e f # # # ' C D u E F # # : u u G H I # l E $ J # K u u L 8 M # # # # # - n u u [ = # # # N O P u u Q R S x T U V u j W n u % X # Y D u Z ` .P P ..' l % u +.~ # # # # @.#.u u u $.J # %.D &.*.V u n 2 j u { =.# # # M -.Q u u ;., # # >.E u 3 >.$.. u ,.J # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # J W '.).!.~.v d {.% # # # # # # # # # # # # # # # # # # # # # # # 9 ].f ^./.(.' - d e f # # _.n :.F <.3 ] [.M f '.0 }.i J # |.1.2.` # Y ^././ 3.# # # # # 4.5.'.<.6.7.8.9.# 1 0.a.%.<.b.c.: 9.v m d.8 <.| N e.u f.F # ' g.h.! i.j.X e k.l.Q R g.m.7 n.# # o.p.q.B r.s.t.u.# , v h.v.z <.| I | (.m.%.# # ' b.w.x.X y.*.z.r.# I =.A.k 2.: <.B.k.C.# # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # D.E.q.# # W a. F.# # # # # # # # # # # # # # # # # # # # # # 9 ].` < V G.8 - d e f # J H.).9 J # I.J.K.| # 4 L.;.F.# # V ] X # # M.s.| # # # # # < N.O.q # # j._ P.# X Q.R.3.# S.d T.M q y h i # # # J U.f.F # # q E k.S M # =.&.a.e.# # V.m.%.# # t p.e.# # C.W.}.J # q 5.k l # # # # Z m.%.# # X.Y.% F.# # 6.Z.`.Y # # z.v. +# # .+++@+J # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # D.E.6.# # S.P a q # # # # # # # # # # # # # # # # # # # # # # 9 ].` # S #+$+5 d e f # S.%+].4.# # @.% &+4.# S.&+> *+# =+] -+$+H J J { ;+J # # # # # >+r `.# # # r.h E M =+5.].M._.# # # # q y h i # # # J U.f.F # # q E ,+n.# # c ++{ @.# # '+)+u.M # # # # # # c & !+- # q 5.k l # # # # Z m.%.# # % #+~+# # # Y {+ X # # z.]+^+# # ` *.l.F.# # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # D.E.6.# # S.P a q # # # # # # W u.j.j.j.j.j.j./+_.# # # # # # 9 ].` # F.0.W.{ @+e f # , ]+m P.j.j.#.a.)+%.M M (+{.~+' _+g r.h.j :+e.]+r.# # # # # # C #+N.j.j.j./ <+y - q C ! [+L /+I.# # q y h i # # # J U.f.F # # q E ,+n.# # ^+k { @.# # '+)+u.M # # M 5 H j.x.&.!+- # q 5.k l # # # # Z m.%.# # K.k.z # # # S.e ! -.# # z.]+^+# # ` *.l.F.# # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # D.E.6.# # S.P a q # # # # # # | V.@+@+@+@+@+@+}+I.# # # # # # 9 ].` # # i |+m.P e f # , ]+Q.(+@+@+@+@+d =+# # z v.0.w ]+8 _.Q {+e.1+2+' # # # # # # C #+(.@+@+@+@+@+x.' # J y.3+r &.%+2 # q y h i # # # J U.f.F # # q E ,+n.# # ^+k { @.# # '+)+u.M # 3.4+}.; @+6 5+!+- # q 5.k l # # # # Z m.%.# # K.k.z # # # S.e ! -.# # z.]+^+# # ` *.l.F.# # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # D.E.6.# # S.P a q # # # # # # # # # # # # # # # # # # # # # # 9 ].` # # # M.0 E.x f # Y ~.6+| # # # # # # # # ` G a.$.e p - 7+k %.s 8+# # # # # # # 9+0+-+# # # # # # # # # # # r.'.O.H M q y h i # # # J U.f.F # # q E ,+n.# # ^+k { @.# # '+)+u.M N a+m 6.q # 9.0 !+- # q 5.k l # # # # Z m.%.# # q.t.T.M # # Y z.b B # # z.]+^+# # ` *.l.F.# # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # D.E.6.# # S.P a q # # # # # # # # # # # # # # # # # # # # # # 9 ].` # # # S.P ( G f # N -+f.b+M # # # # # # # - D.o p.H # # +v.s.} I # # # # # # # X.{+a.F.# # # # # M ~ (+@.# # C.#+: M q y {.c+# # # J U.f.F # # q E ,+n.# # ^+k { @.# # '+)+u.M , U } I # # d+e+!+- # q 5.c.n.# # # # Z m.%.# # %.& a+:+# # *+t.f+I # # z.]+^+# # ` *.l.F.# # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # < n Z.V.q J *+B.*.r.' # # # # # # # # # # # # # # # # # # # # p n v.g.' # # M >+v.G f # # | :.g+c h+, o.D B # # # ~ d.c.^+# # w } 1.i+# # # # # # # # # j+)+q.h+h+_.q.f+M +)...1 h+) ].4.# # k+U [ i 6 .+:+E a j.- M f s m ^ ' ' 8 &.N.5 M q / & / p p 5.d.l+h+i+N.p.m+2 M # -+n+j i ; 8+< @ o+: N # F.q.++V.1 f ] b ^+# M l k |+p+' F.b+&.~.I.M # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # F.$ m+q+q+j.` [ q+q+5.c+# # # # # # # # # # # # # # # # # # # # 3+q+q+`.*+# # # 3.;+1+1 # # # 5 ;.q+q+5.0.Y # # # # f }.r+Y # # I P.:.1 # # # # # # # # # # y.q+q+q+{+9+' M c ~.q+q+q+* | # # # # s+q+{+t+F.}.q+q+} .+q E q+q+L w u+ q+q+;+3.T.q+q+{+t+F.< G q+q+0.1 e q+0.1 # # % q+,+~+- 0.q+q+g+8 M # q ,.b q+q+E - # # @.K.q+q+a+c+4 5.q+q+@+3.# # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # f H.^+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # J B v+w+n.# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # X.f+% % % r+, # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M v+h ~ # # J 4 f+% % % x+Y # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # J >+2.Z. .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # o.J.b.9+o.J.T t+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ' u !+l # # #.* y+9+j+o _ y.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # H #+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ^+! z+- # M >+a j.# # b+,+B # # # # # # # # # # # # # # # # # # # # # # # + D h+# # # # # # # # .+<+T.M # c _ k+' # J ^ /.9+# # j.f.I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # '+t.#.# # # N P /+# M b.{.g.# # # # # # # # # # # # # # # # # # # # # # J 7 7.1 # # # # # # # M }.d.*+# # V.Z.[.# # # q K.R # M %+++>.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # - ~ R R R B+M # # # # # # # # # # # # # # # # # # # # [._ u @.# # # # # S.8 :.0 O R 8 W M # i R R R >+q # M W C+R 2 J n.R B+X o.& ].o.R g.J # # # # I.m.+.F.# # x.T r+p # # # # # _.^ k n+/+R 4 3.# # @.y.R R p+q # # q >+R 4 S.=+F R y.J # # # # # M = C+R 2 J n.R r.q # # , 8+R R e.# # # # # f R R R l+- # # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # 2 k+b %++.<+ F.# # # # # # # # # # # # # # # # # # # # | b G.6 u+# # # # l U.s L.P %+4+8+I.y+q.'.) m+0+/+# J 8 g+Z.7+j+J.( ,+d ;.).{.a+%+d - # # # # .L.y.# # # v {.#+}+I.# # # # =.0.0+&.D+%+E+w M u+(+V ;.!.o+; ^+# 1 x+#+v.y+E+%+> ++H J # # # # J z g+& #.~+].( B.^+# r.r+D %+V ,+C+M # W ,.%+'.) ]+m.[.# # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # $.T F+# S.D.8.F.# # # # # # # # # # # # # # # # # # # # # 8+* &.> k+I.# # # F.; c.g.# # # 4 $+(+' M 6.d.K.J # # o.<+0.`.x.u 7 *+p Q.7.1 # # # # # # q z.J.Y # # # # [.]+o V 7+- # # # N P ++>.# # # < } r B+M N k+&.s+< # q b t.}+u+# =.k.k <.# # # # # # F+)+(+z+x.N.z.^+@.,+z.^+# 2 r ]+n.# z _ U.J J t+{.!+J # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # n e+ .# # Y e.M # # # # # # # # # # # # # # # # # # # # # # 2 j.c.*.s v # # F.; c.g.# # # @.g.3.# # X.B.$+I # # 6.0+a.| M I.<.q p Q.7.1 # # # # # # 9+#+H M # # # # J =+G+U o {+l # # N P ++>.# # # |.T 6 M # # < q+|+g.# q b $+w # # J s+).|.# # # # # # 9+$+7.^+M W <.I %.n+V.M # # .t.|.# Y >+Y # # w J.0+N # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # r.n+5+s.B+# # # # # # # # # # # # # # # # # # # # # # # # # # J 1 q.e+$+q # F.; c.g.# # # # # # # # < 2.a q # # 6.0+x+# # # # # p Q.7.1 # # # # # - _+{.< # # # # # # # - l b 1.m+N # N P ++>.# # # %+[+F+# # # # _+A+j+# q b d.f # # # 9 0 ;+J # # # # # 9+$+@+# # # # # L ++i+# # # C n+;+J # # # # # Y z.O.I # # [.A+ .# ' w+)+n+n+<+|.# # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # p z.c.T G 5 # # # # # # = d.{.{.{.{.{.{.p.F+J # # # # # # # # # F.}.&.: # F.; c.g.# # # J I.<.m+{.<+L.c.q # # 6.0+P.# # # # # p Q.7.1 # # # # # w > '.# # # # # # # # # # I K.U S # N P ++>.# # # ) [+o.# # # # }.O.~+# q b d.f # # # C 0 x+J # # # # # 9+$+V.# # # # # G e+a {.{.{.{.A r+' J = =.5.{.)+& a I # # [.A+ .# ' 9 h {.{.! j+# # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # =+2+E.q.M # # # # # # # # # # # # # # # # # # # # *+B # # # # ~ ).r+# F.; c.g.# # M B+Q.> e.# S.u a q # # 6.0+P.# # # # # p Q.7.1 # # # # J O $+d+# # # # # r.n.# # # # ~+0 O # N P ++>.# # # }.e+: M # # # '.<+S # q b $+5 # # # ,.*.3+M # # # # # 9+$+V.# # # # # `.t.4.# # # # # # J .+A } w # @.g+O.I # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # N /+9.# # w > F.# # # # # # # # # # # # # # # # # # # # P.6+F.# # # M.++w+# F.; o p+# # N q.c.>.# # W } #+q # # 6.0+P.# # # # # p ] > I.# # # # , l.:.l # # # # # @ u ' # # # ,.U S # N P Z.u+# # # C.[+u @.# # p m s.^+# q b /.c # # F.2+o+6.# # # # # # 9+$+V.# # # # # |.U T.M # # # # # q +.o+` # # 2 s.O.I # # [.A+ .# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # Y L - # g.y ) M # # # # # # # # # # # # # # # # # # # # P./.@+J # 5 G ! l # M u.c.%+' c+H.l.U B+# 1 x.&+/.f # # H O.% # # # # # ' G k.t+- ,.f # =.5.@+p # # # # # @ o $ M # c ].z., # J + 1.P.F.F K 9.!+o+O ' - 1+n+u.J # q b & 0.@.# 9+).@ :+# # # # # # C a f+# # # # # 1 V ,+g.# # N 1+p+I a+*.n.# i d h /.i # # v+/.r+# # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # I u 5+|+m v.R.5 # # # # # # # # # # # # # # # # # # # # # 4.v.*.|+m 0+r+u+M # # Y ;.E.] e e.5 * $+m z.|.l.Z.k X ^ Q.[+++i.- # # # # n.h.a w.|.I I x.]+4 M # # # # # ^ W.t.|+m k.^.>.M # # 1 7 ++! 6 f M f x+_ |+|+$+B+q # # q b E.0+f.m a T.` # # # # # J 6.] [+++!+- # # # # | `.{.m m s y., M X.> $+m 6+~+L &.w.u+[.p.e+o [ J # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 9.u D+_.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # q b d.f # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # >+m x.J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # q b d.f # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # _+5.c+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # < ! v.X.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # >.p.%+p # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # , V.0 Z.n n.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # h+ +=+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # S.~ o.o.6.l # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 6.m.Q # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # F k D+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 8 ] 2+J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # < g.>.M # # # 4.E -+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # S.B+2 J # # # r.@ Z # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # q r.X.J # # # c !.@+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # r.m+^.- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # X ,+}+N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # e.7 P.q # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # J [.a ^.- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+O.}+N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M C+A+P.q # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ) v.e+<+w.y k+R g+&+/ # F.|.s &+8 l 8.&+B.X # F J.&+R.1 # # # # N { &+&+(.r.# # # # # # # # M y.a.&+&+}+# # # # 3.5.&+&+&+@ Y %+$+e+)+w.&+U.p+a.&++ # ' ~+s &+F 1 !+&+{+r.# z J.&+{ ` # # # # B+} &+&+* R M # { 0+e+A+h.&+1+-.7.&+6 J # # # N % &+&+]+: I # ' ~+].&+~+1 5.&+8.>+M # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # q [.k...:+p - ' S 0+Q # # F.x.o D+|+X.F Q.,+~.z+3.d o ;+# # # v ].Q p >.D+r v # # # # # # # }+f.[.p F+W.g ' # p+#+}.p 5 N.q+h+I d+v.V.3.p - ' 9+d.D+# # F.O /.L m.^+z h. ~.Q 3.x.).E+J # >.P #+=.p y.<+{+c+# I R $+U., p N J R |+2+J # # c q+,+Y Y d & j S.# I ,.A+* d.3.8 f.K.f # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+v.^.- # # # r.r Q # # # +{.8.' # p e [+y+# # <.]+D M # < q.k.X.# # b+m.% I # # # # # 2 *.;.' # # G A+b+# + & ^ # # v 4+:+M R $+}+N # # # B y D+# # # 9+A :.' # p !.T ,.# # u+m+P ' # I.'.x.q # , ) A.K # M 8+A P.q # # # <.q+2+J # @.s+{.e.# # 1 !.Y.p+# # M.{.D+N # 3.s+h =+# # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+v.^.- # # # r.r Q # # # +{.$.# # I z+o u+# # = } ,+F.# X > x 3.# # e.z.K.@.# # # # # -+o C # # # $ ).w+M : Y.N.%.1 # # # M R $+}+N # # # B y D+# # # 9+A Z # # I { o =.# # I.K.m+I # # # # # # p x+).^ M M 8+A P.q # # # <.q+2+J # B+].. 1 # # # 9 #++ # # M.{.b.' # N 1+_ r.# # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+v.^.- # # # r.r Q # # # +{.$.# # F.3 o+u+# # = } ,+F.# F 0+s 3 1+1+{ A k 9.# # # # # 2.0 e 1+1+1+!+L.[ ' _.x+_ o Q F+@.# M R $+}+N # # # B y D+# # # 9+A Z # # F.+ c.=.# # I.K.m+I # # # ' C 1+6 * o ^ M M 8+A P.q # # # <.q+2+J # 8 A.) :+# # # i+v.`.# # M.{.b.' # N 1+_ r.# # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+v.^.- # # # r.r Q # # # +{.$.# # F.3 o+u+# # = } ,+F.# F 0+D u./+/+/+/+o.q # # # # # 2.o -+/+/+/+/+'+g.M # ' 9+V.<+<+: - M R $+}+N # # # B y D+# # # 9+A Z # # F.+ c.=.# # I.K.m+I # - 9 u @+/+|.Q ).^ M M 8+A P.q # # # <.q+2+J # 8 A.) :+# # # i+v.`.# # M.{.b.' # N 1+_ r.# # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+v.^.- # # # r.r Q # # # +{.$.# # F.3 o+u+# # = } ,+F.# g.].f+S.# # # # # # # # # # # 3 o+C+# # # # # # # # # # I F ]+B.3.M R $+}+N # # # B y D+# # # 9+A Z # # F.+ c.=.# # I.K.m+I J F Q./ 1 # F.x.t.^ M M 8+A P.q # # # <.q+2+J # =.]+b W # # # j.o+;+# # M.{.b.' # N 1+_ r.# # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # M i+a G+S.# J # r.r Q # # # +{.d # # F.3 o+u+# # = } > F.# _.+.J.W # # # J J # # # # # # >+++/ ' # # # ' M < . y.# # i u 5.h+M R O.r+@.# ' # B y D+# # # 9+A P.# # F.+ c.=.# # I.K.b I ' v+t.C.M # 9.`.E.^ M M 8+)+g :+# ' # <.q+2+J # 1 !.*.R # # p %+a 2 # # M.{.b.' # N 1+_ r.# # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ^+2.Q.M..+4+2 T.<+].c M h++ U 2.5 ' w V 1.O h+I i+] ).l+- # 4 ,+u B+B+4.; [ q # # # # # # ; h.x.B+B+4 2+d+S.8.o+.+B+u. -+N # 2 (.m C..+_+2 t k.&+B M 3.U.o !+X.' | !+1. .h+I 6.r ).K I p+h { 4 g.$.:.A+x+, # I.2+|+'+.+s+>.|.0+h.r.M # .+a.a K g.Z ] t - # , ; U +.^+J u+(.L.x.@.# # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # K q.2+l., u+_+2+2+}.- -.'.2+2+^.< u.L 2+2+.+I.; 2+2+l., # # n.l.2+2+D+t+- # # # # # # # q u.2+2+2+'., # ' v+E 2+2+2+u.S.# # # l+s+2+`.1 e.n 2+2+g - >+) 2+2+ .S.C L 2+2+4 l ;+2+2+`.1 J %.`.2+e +.+) 2+l+# # r.% 2+`.1 ^+j 2+2+s+F.# # f % 2+2+Q ^ M # M 4.E 2+2+y+I |.2+2+2+u+# # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +~.~.~.~.~.~.~.~.x+1 # # # # # # # # # # # # +~.o.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 3.-+T D n.=+=+c N.V W # # # # # # # # # # # # D.G.Z # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -.Z.) F.# # M >+R.I.# # # # # # # # # # # # # # # # # # V.A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -.Z.) F.# # # # # # # # # # # # # # # # # # # # # # # ' P A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # :+H.w+w+p+# # # # # # # # # # # # # # # # # # # # # # # -.Z.) F.# ' M., # # e.j.w+w+F p = v+w+H.2 .+y+T.B # e.w+_ ++3+w+F+1 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # r.'.`.V.%+]+: J # # # # # # # # # # # # # # # # # # # # # -.Z.) F.# 5 $+=.# # c a+( A+j.S.X.6+Y.x+w ~ u G.Z # X D.d.U G+V.y+` # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # @.5.Q.X.# h+P /.z # # # # # # # # # # # # # # # # # # # # # -.W.A+B.7 J.0 =.# # # i N.)+H.M @.h ,.< # # H.G.Z # # I a.A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # F &.[ M # # F+( -+# # # # # # # # # # # # # # # # # # # # # -.Z.D+2 I.y+L.=.# # # # 2 y 5.z 6+P.- # # # S G.Z # # I a.A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # n e+: _._._.C ( l.' # # # # N 9._._._._._._.9.F.# # # # # # -.Z.) F.# q a.X # # # # M 8 A G.G+' # # # # S G.Z # # I a.A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # n e+w.> > > > > g F.# # # M .+z.> > > > > > V n.# # # # # # -.Z.) F.# # # # # # # # # , n E.V.- # # # # S G.Z # # I a.A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # U.[+b+# # # # # # # # # # # # # # # # # # # # # # # # # # # -.Z.) F.# # # , %.W # # I 7+z+. c.H M # # # S G.Z # # I a.A+I.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # R Z.G+J # # # # # # # # # # # # # # # # # # # # # # # # # # -.Z.) F.# # M 8 7 z # # 9 2.c ^+i.{.S # # # S G.Z # # I a.++c+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # p ) v.[.# # N E u.# # # # # # # # # # # # # # # # # # # # # ~+5+) F.# # q (.5.=.# t k i+M # F Z.f.M.# # #.G._+J # J 6 W.@+- |.4 J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # N k+&.n+n+#+X N # # # # # # # # # # # # # # # # # # # # 7+&.( T n+n+n+0 e+m+r.) L.G.5.X.^+y G.G.<+C 3+).( L.f+F.# N g+W.o ;+< # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # < ^+e.^+p # # # # # # # # # # # # # # ' w e.W - # # # # # # # I.e.^+< # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # I.d+j+[.u+M # # # # # 5 +j+[.3.# # # # # # # # # # # # # # # # # # # # e.o.w # # # # # # # # # # # # # # # # # # # # # # # # # # # # # W d 2.7.O.C.p+-.N # # # # # # # # # # # :+8.++a.*+# # # # # # # / f.A+j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # n.z+1.5+) p # # # # S.+ n+5+f+l # # # # # # # # # # # # # # # # # # # # V.5+D.# # # # # # # # # # # # # # # # # # # # # # # # # # # # @.; (.>.< 3+t+m+K._.# # # # # # # # # # # # 1 a.a.*+# # # # # # # ' }+<+j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # >+/.h.5.u+# # # # =+} G./.h+# # # # # # # # # # # # # # y.;.` # # # # c+H.e.# # # # # # # # # # # # # # # # # # # # # # # # # # # # X s.f+:+# # :+F z I # # # # # # # # # # # # 3.G a.*+# # # # # # # J y+k.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # c Y.R.).D.' # # ' j.7.A.O.q # # # # # # # # # # # # # # -+O.^+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 4.p.3 < # # # # # # # # # # # # # # # # # # 3.G a.*+# # # # # # # J y+k.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # c 0 u.$+e _.# # h+s+f+,+O.q # # # # # ' F.F.F.M # # M Y !+U *+F.F.M J F.F.J # # # # # ' F.F.F.M # # # ' F.F.M J F.F.' # # # # # # J %.a r+3.F.M ' F.' # # # # # J F.F.F.M # # # 3.G a.*+# # # # J F.F.N T.k.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # c 0 ~ 0.h y.M # 4 a.9+6+O.q # # # @..+y Q.] a .._.# v :.t.[+f.h g+ +/ <+5+D.# # # 3.i+&+Q.m /.o.h+# i `.U &.t+d h.o+]+>.# # # # # ~ A.T _ ] } u+{+0 K._.# # N u+@ ! Q.] ..:+# # 3.G a.*+# # F.r.(.m.h |+A {.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # M M M M M M M M M M M M M M M M M M M M M M M # # # # # # # # # # # # # # # # # # c 0 K C.o+x+p M ; @ 5 6+O.q # # F.d ++b.J N V.++z+S.# - % /.^+# # # # O 5+D.# # N j c.'+M q s+[+6 q # F.G n+a+t ' y+Y.{ M # # # # M b+a 3 < # # =+z.K._.# M 8 ].4+p F.: 0+D.p # 3.G a.*+# # v s.* u+M _.y A+j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # M H+I+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+J+K+L+M # # # # # # # # # # # # # # # c 0 >+n.> 6+I.:+s /+@.6+O.q # # v Q.g+' # # h+!+& 8+# - % /.^+# # # # o.5+D.# # z U L ' # # _.! $+=.# # ) [+o.# # W <+> - # # # # M b+a 3 < # # 2 ~.K._.# @.(+|+>+# # ^+a.i.>.# 3.G a.*+# # x+a u.M # J D.<+j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # J M+N+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+P+Q+J # # # # # # # # # # # # # # # c 0 >+S.E+$+-.i+5.` < 6+O.q # # y+_ U.# # # # -+e+}+# - % /.^+# # # # o.5+D.# # / W.: # # # # f+o C # # ) T B+# # 3.$+|+N # # # # M b+a 3 < # # 2 ~.K._.# X.,+:.5 # # i D+w.<.# 3.G a.*+# # V ! K # # J y+k.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # M - R+S+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+T+U+F.M # # # # # # # # # # # # # # c 0 >+# 6.k @ / M < 6+O.q # # 7+).}+# # # # 7+e+x+# - % /.^+# # # # o.5+D.# # r+T C # # # # + E.v+# # ) T B+# # 3.$+|+N # # # # M b+a 3 < # # 2 ~.K._.# e.r Z.#+A+A+#+L.t.-.# 3.G a.*+# p m > X.# # J y+k.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # J I V+W+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+X+Y+I J # # # # # # # # # # # # # # c 0 >+# I.* 1._ I.# < 6+O.q # # #.t.V.# # # # b.e+@+# - % /.^+# # # # o.5+D.# # 3 T $ # # # # 6 E.j.# # ) T B+# # 3.$+|+N # # # # M b+a 3 < # # 2 ~.K._.# *+w.'., # # # # # # # 3.G a.*+# p |+&+B+# # J y+k.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # J p Z+`+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+ @.@q J # # # # # # # # # # # # # # c 0 >+# # 7+U ) J # < 6+O.q # # F A s.S.# # ' a+&.R # - % o c+# # # # o.5+D.# # '+L.~.q # # F.{+k.l+# # ) T B+# # 3.$+|+N # # # # M b+a 3 < # # 2 ~.K._.# i x * | # # # # # # # 3.G a.*+# # N.Q.8+# # J ..{.j+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # J S.+@@@O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+O+ @#@p J # # # # # # # # # # # # # # K & R # # w 4+*+# # 1 z._ , # # 1 D+n+O J J ~ 0+e F.# ' @+n+D.J X.c F.j.W.;+M # f {+o+j+J J C.& 4+' # ' E T z # # I.{.A.:+# # # # M b+a % :+# # w 7.{+f # N v+r O N # M c+6.Y # , * > X # # H A+E+Y # n.G o+$ M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # J p $@%@&@*@=@=@=@=@=@=@=@=@=@=@=@=@=@=@=@=@=@=@=@*@&@-@;@q J # # # # # # # # # # # # # =.D 1.i.-.# # # # # = G+#+5+@ = # # n.3 o+`.z+b 3 = # # # e.g+k.l.G+>+[. 1.&+j+J # g.) d.z+`.h.3+` # N b.v.1.. >+>._+L.n+0.` # # # = !+L.k ^.M h+}.#+/.%+- # _.$.5.Q '.) G+[.Y - 0.o+/.R.` # 9.}.Q.2+'.;+(+Z.b ^ F.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # J I l c z 6.9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+9+6.z c i I J # # # # # # # # # # # # # 9.4 p+y.l # # # # # < r.p+p+8+< # # # @.z p+p+-.@.# # # # # *+p+z u+F.5 8 p+8 ^+M # # 1 z p+p+4 ' # # J <.z p+4 ` < 4.p+p+4.q # # # < 8 p+p+u+# N B+p+p+4 J # # < 4.p+p+z e.' # J 4.p+p+g.p # # 1 4 p+p+| i z p+= M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # M - 3.>.u+c =.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.B u+>.:+F.M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # J I @.1 9._._._._._._._._._._._._._._._._._._._.9.1 @.N J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # M J F.N N N N N N N N N N N N N N N N N N N N N N N F.M M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # M M M M M M M M M M M M M M M M M M M M M M M M M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # F.%...}+*+# # # # # # # # u+^.}+t f # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # M >@,@'@)@!@~@{@M # # # # # # # # # # # # # # # # # # # # # # w + !.!.g n.# # # # # # # # # # # # # 8+) t+# # # # # # # # # # o.g K # # # # # # # # # # # F.F 7 G.H.# # # # # # # 8+s+$./ p.y.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # M J ]@^@/@(@_@:@<@[@}@M # # # # # # # # # # # # # # # # # # # # # Y 9 a ( t 3.# # # # # # # # # # # # # T.& G+# # # # # # # # # # (+/.9 # # # # # # # # # # # # # d 1.H.# # # # # # W L l.Y q r.Y # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # M J |@1@2@3@4@4@4@5@6@7@8@M # # # # # # # # # # # # # # # # # # # # # *+m U 2 # # # # # # # # # # # # # # - @.N # # # w+{.= # # # # I @.- # # # # # # # # # # # # # ^.1.H.# # # # # # C+m.P.N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # 9@0@a@b@b@b@b@b@b@b@b@c@d@e@M # # # # # # # # # # # # # # # # # # # # Y s E.>.# # # # # # # # # # # # # # # # # # # J ;.o >.# # # # # # # # # # # # # # # # # # # # ^.1.H.# # # # # # ^ v.Z N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # J f@g@h@b@b@b@b@b@b@b@b@4@i@j@k@M # # # # # # # # # # # # # # # # # # # Y s E.>.# q 4 t+t+h+X.M.[.-.M # M =+ +[.c+# f [.m.0 T.[.R _..+[.9+= # # # J c+[.[.[.4 M # # # ^.1.H.# # # # # 2 r+U +.j+F I.M.[.<.J c [.p+3.# # w [.[.[.y.M # J c t+[., , 6.[.9+N J | t+[.g.M # # # # ' ~ [.[.8+< # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # F.l@m@n@b@b@b@b@b@b@b@b@b@o@p@q@' # # # # # # # # # # # # # # # # # # # Y s E.>.# :+,.A.Z.3+/ r+b d.R # J F ~.[+G+# <.U.f.& ;.r+V.e.t q+/.9 # # =+/ '.}.}.] A.~ # # # ^.1.H.# # # # M 4.2.L.{+}.d c G U U.H.s.( &+l+w x+z+}.}.&+m.^ # F.M.m+[+x.x+G+2.#+w+|.;+j s &+g.# # # 2 Z ~.r+l.B.Z S.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # J q r@s@t@b@b@b@b@b@b@b@b@b@u@v@w@- M # # # # # # # # # # # # # # # # # # Y s E.>.# # J @ 5+n l+M 6./.@ J # # [.L.G+# # N (.++>.# # # # x./.9 # # o.&.$ J J ,.&.;.J # # ^.1.H.# # # # # J ~+_ Z N # # z m `.z+$ q.J.l+i+e+#.J J 9 ++e J # # x.L.D 6.I w r #+;+v J '+_ G+# # I r+#+.+# @.G+v.j+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' < x@y@4@b@b@b@b@b@b@b@b@b@4@z@A@I M # # # # # # # # # # # # # # # # # # Y s E.>.# # # ;.1.p+# # 9.A h.- # # b+0 G+# # N (.++>.# # # # $ /.9 # # :+c q # # =.++5.- # # ^.1.H.# # # # # J ~+_ Z N # # .+w.b =+# 3.*+p @.B p # # <.{.|+- # # j.n+b.M # @.b *.u+# # u+d.!+J # u+]+u M # # y.k q.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' 3.B@C@D@b@b@b@b@b@b@b@b@b@E@F@G@p M # # # # # # # # # # # # # # # # # # Y s E.>.# # # ;.1.g.# # 3.0+p.N # # b+0 G+# # N (.++>.# # # # $ /.9 # # # # # # # h+#+y N # # ^.1.H.# # # # # J ~+_ Z N # # .+w.j N # # # # # # # # # :+p.A N # # j.n+$ # # N e o 2 # # *+f.* ' # u.c.x+# # # g.m 7 F.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' h+H@I@J@b@b@b@b@b@b@b@b@b@K@L@M@S.J # # # # # # # # # # # # # # # # # # Y s E.>.# # # ;.1.g.# # 3.0+p.N # # b+0 G+# # N (.++>.# # # # $ /.9 # # ' c ~+b |+k [+y N # # ^.1.H.# # # # # J ~+_ Z N # # .+w.j N # # # # ' <.d+ |+k 5+A N # # j.n+$ # # N e o 2 # # *+f.* ' # u.c.A+|+|+|+|+|+,+N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' :+N@O@P@b@b@b@b@b@b@b@b@Q@R@S@T@p J # # # # # # # # # # # # # # # # # # Y s E.>.# # # ;.1.g.# # 3.0+p.N # # b+0 G+# # N (.++>.# # # # $ /.9 # J t+E.q.l # h+#+y N # # ^.1.H.# # # # # J ~+_ Z N # # .+w.j N # # # J %.Y.+.W # :+p.A N # # j.n+$ # # N e o 2 # # *+f.* ' # j+)+: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # J < 5 U@V@c@4@b@b@b@b@b@W@X@Y@Z@l I M # # # # # # # # # # # # # # # # # # f h.E.>.# # # ;.1.g.# # 3.0+p.N # # b+0 G+# # N (.& n.# # # # $ /.9 # < w.0+3.# # c ++y N # # ^.1.H.# # # # # J ~+_ Z N # # .+w.j N # # # S.z.o+, # # c+k.A N # # j.n+$ # # N e o 2 # # *+f.* ' # =.].@ J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # M I ` c `@ #.#+#5@b@@###$#%#&#*#h+- M # # # # # # # # # # # # # # # # # # w ] T v # # - (.1.i+# # X.<+k.9.# # C Z.l.J # J U.1.U.F.6.8+' @+E. .M p q+/.w # e.}.$+|+9.# # [ 1.}+# # # # # J ~+_ 4+p # # ^ A.D+q # # # q K.Z.c+# X.6 k a _.# # k+Z.;+# # S.} W.=.# # 4.v.|+N # p k+k.T.# # F. .7+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # ' @.2 l+=#-#;#>#,#'#)#!#~#c i q J # # # # # # # # # # # # # # # # # # 4.z.W.( m 8+p ) 0 ( k o.<.z.[+[+7 X.9 m.G.Y.{ ' # Y 7.n+A 3 _.(+U 1.O.y+' ^+f.a k.2.8+5.T V ^+P._ ( O.x.J # # # y.O.e+Y.j M 4.! [+L.J.N # # M 2 ] #+k.V b+7.e+ e.7+A+G.t.@+i l.& ( f.z l+,+[+[+* 9.# < w+Y.k.k.d.T.i # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # J N h+X.4.F +[.o.t+9+z c I.< ' M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # J N 3.= n.4.-.8+K r.=+l < F.M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # M J F.S.1 I.5 X.>.l h+p F.M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # M ' - q < < S.q - J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # M J J J J J M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ' v p+y., # # # # # # # # W p+p+r.S.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # {#]#^#/#(#_#:## # # # # # # # # # # # # # # # # # # # # # # # # # # z x.x.x.x.x.x.x.O c+J ' F /+f # # # # # # # # # # # # # # # # # # # # # # I 3+m.E.9+# # # # # # # B+n `.V 5.B # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # M M <#[#}#|#1#2#3#4#5#M # # # # # # # # # # # # # # # # # # # # # # # # # ^ {+& !. . .D.!./.t F.I +.] 8 # # # # # # # # # # # # # # # # # # # # # # # # n E.9+# # # # # # W P q.J = C.1 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # M J 6#7#8#9#0#0#0#a#b#c#d#M # # # # # # # # # # # # # # # # # # # # # # # # p ; E.j+M # # *+P u.F.J =+4.:+# # # # # # # # # # # # # # # # # # # # # # # # ;+E.9+# # # # # # [.k.: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # J e#f#g#0#0#0#0#0#0#0#h#i#j#M # # # # # # # # # # # # # # # # # # # # # # # q P.++j+M # # M S.N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ;+E.9+# # # # # # C #+u.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # M k#l#a#0#0#0#0#0#0#0#0#0#h#m#n#M # # # # # # # # # # # # # # # # # # # # # # q P.++j+M # N , J # M l >.l N # - = >.1 F.i >.= Y # # # # J h+>.>.>.1 # # # # ;+E.9+# # # # M h+/ *...>._.@.= >.Y M , >.` F.# M 3.>.>.>._.# # M 9.>.= - p I.>.I.M M 3.>.>.h+# # # # # M l >.>.9.J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # F.o#p#g#0#0#0#0#0#0#0#0#0#0#q#r#' # # # # # # # # # # # # # # # # # # # # # # q P.++j+M # M.D+3.# N z+O.] 8 # e.B.0 K.'+D+a.a '.i # # W H.) } g+).> | # # # ;+E.9+# # # # N H |+T Q.a.r+o.! 5+x.y.7 ( {+| l C.{ } g+c.].e.# q E+<+[+'+x.N.] _ -.z G+} a V I.# # # ` C.7 a.q+g+6.M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # M I s#t#0#0#0#0#0#0#0#0#0#0#0#u#v#F.M # # # # # # # # # # # # # # # # # # # # # q P.L.L @+@+* x 3.# # N s+] 8 # # f ! r 4+= # f+k.j+# # $ ).T.J F.j W.U.M # # ;+E.9+# # # # # ' D.U u.# # # '+A+;+D+g > 7 | ~+0 ..J ' / 1.4+M # # 3 e+D+|.q y._ Q.3 y.F.@+W.b.# # N 0.Y.^ # f x k =.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' < w#x#0#0#0#0#0#0#0#0#0#0#0#a#y#N M # # # # # # # # # # # # # # # # # # # # # q P.0 q.y+y+(.x 3.# # - 1+] 8 # # 1 ]+7.| # # R t...J # | F+:+# # 8 5+e F.# # ;+E.9+# # # # # ' D.U u.# # # 9+A K.l+J X ^ @.5 /+h+# # K 5+:.F.# # }+e+7+M # 3.v.c.c # # >+*.%+J # n.A.!+' # # ~+o U.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' :+z#A#0#0#0#0#0#0#0#0#0#0#0#B#C#p M # # # # # # # # # # # # # # # # # # # # # q P.++j+M # 9+D+3.# # - 1+] 8 # # 1 ]+P i # # K E.k+' # # # # # # I.L.~.- # # ;+E.9+# # # # # ' D.U u.# # # 9+A [ M # # # # # # # # # i n+ - # # }+[+o.# # p m+{.I.# # X E.D+' # O ++..# # # z _ G J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' h+D#E#g#0#0#0#0#0#0#0#0#0#0#F#G#S.J # # # # # # # # # # # # # # # # # # # # # q P.++j+M # M J # # # - 1+] 8 # # 1 ]+P i # # K E.k+' # # J j+a [+[+1.~.- # # ;+E.9+# # # # # ' D.U u.# # # 9+A Z # # # # # # M R <+[+[+( - # # }+[+o.# # I z.{.I.# # X E.D+' # 3+Y.1.[+[+[+e+( A.N # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' 3.H#I#8#0#0#0#0#0#0#0#0#g#J#K#2 p J # # # # # # # # # # # # # # # # # # # # # q P.++j+M # # # # # # - 1+] 8 # # 1 ]+P i # # K E.k+' M .+U D+f # 9.0 ~.- # # ;+E.9+# # # # # ' D.U u.# # # 9+A Z # # # # M r.Y.!+= # , *. - # # }+[+o.# # I z.{.I.# # X E.D+' # D.U 6.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # ' @.^+L#M#N#0#0#0#0#0#0#g#O#P#Q#f I M # # # # # # # # # # # # # # # # # # # # # q P.++j+M # # # # # # - 1+] 8 # # 1 ]+P i # # K E.k+' < A 5.h+# # u+& ~.- # # ;+E.9+# # # # # ' D.U u.# # # 9+A Z # # # # < r m 1 # # *+Z. - # # }+[+o.# # I z.{.I.# # X E.D+' # b+A+1+M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # M I l v R#S#T#0#0#0#0#U#B#V#W#X#, - M # # # # # # # # # # # # # # # # # # # # # S.[ & b.N # # # # # # N R.m.6.M # f Q.:.5 # # %.n+G+I Y )+y i # ^+(+_ 7.@.# # % *./+# # # # # ' D.U .# # # H.A+4+# # # # @.|+m.I.# >.; o+J.:+# # (+e+v+# # < w._ *+# # 4 n+* - # , D+m.p+# # F.u.%.# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # F.:+X..+Y#Z#`# $0#.$+$@$#$$$I.p ' # # # # # # # # # # # # # # # # # # # # # # ^.0+( k d # # # # # # + <+Z.7 X :+:.0 _ n 9.8+].e+m.|.p M.A.z.~._+S ] t.+ ` D.{.[+ ^ M # # J R h.T p.y+M -.{+5+k.s+F.# # ' 6.0+B.~.R.C.r U }.f w+m.G.s [.i _+0 [+L u+>+i.e+o / @.# | g |+~.~.P ,.B # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # J I 1 w %$&$*$=$-$;$>$,$=.>.@.F.M # # # # # # # # # # # # # # # # # # # # # # ` =+=+=+l # # # # # # W =+=+w p ' *+=+=+= F.@.=+=+=+1 M J X.=+=+I.' 5 =+I.F.l e.=+w :+# # # # :+e.=+=+_.# @.w =+=+5 M # # # M 5 =+=+W - 2 =+= - ` e.=+*+h+- >.=+=+X.q < | =+=+W ' # # Y =+=+=+*+p # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # J I , 5 c K z ~ 8+l+n.W Y - M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # M J - @.` >.w *+^+W 1 S.- J # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # M M ' N S.Y Y @.S.N ' M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # M J ' ' ' J M # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ ", +" . E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+E+@ ", +" "}; diff --git a/main_scene_flow_impair.cpp b/main_scene_flow_impair.cpp new file mode 100644 index 0000000..f65e2ae --- /dev/null +++ b/main_scene_flow_impair.cpp @@ -0,0 +1,63 @@ +// Author: Mariano Jaimez Tarifa +// Organization: MAPIR, University of Malaga +// Date: January 2014 +// License: GNU + +#include +#include +#include "scene_flow_impair.h" + + + +// ------------------------------------------------------ +// MAIN +// ------------------------------------------------------ + +int main(int num_arg, char *argv[]) +{ + //============================================================================== + // Read function arguments + //============================================================================== + unsigned int rows = 240; //Default values + + if (num_arg <= 1); //No arguments + else if ( string(argv[1]) == "--help") + { + printf("\n\t Arguments of the function 'main' \n"); + printf("==============================================================\n\n"); + printf(" --help: Shows this menu... \n\n"); + printf(" --rows r: Number of rows at the finest level of the pyramid. \n"); + printf("\t Options: r=15, r=30, r=60, r=120, r=240, r=480 (if VGA)\n"); + system::os::getch(); + return 1; + } + else + { + if ( string(argv[1]) == "--rows") + rows = stof(string(argv[2])); + } + + + PD_flow_opencv sceneflow(rows); + + //Initialize CUDA + sceneflow.initializeCUDA(); + + bool imloaded = sceneflow.loadRGBDFrames(); + + if (imloaded == 1) + { + sceneflow.showImages(); + sceneflow.solveSceneFlowGPU(); + //sceneflow.updateScene(); + sceneflow.showAndSaveResults(); + sceneflow.freeGPUMemory(); + } + + printf("\nPush any key over the scene flow image to finish"); + //mrpt::system::os::getch(); + + return 0; +} + + diff --git a/main_scene_flow_visualization.cpp b/main_scene_flow_visualization.cpp new file mode 100644 index 0000000..80c1ea8 --- /dev/null +++ b/main_scene_flow_visualization.cpp @@ -0,0 +1,124 @@ +// Author: Mariano Jaimez Tarifa +// Organization: MAPIR, University of Malaga +// Date: January 2014 +// License: GNU + +#include +#include +#include "scene_flow_visualization.h" + + + +// ------------------------------------------------------ +// MAIN +// ------------------------------------------------------ + +int main(int num_arg, char *argv[]) +{ + //============================================================================== + // Read function arguments + //============================================================================== + unsigned int cam_mode = 1, fps = 30, rows = 240; //Default values + + if (num_arg <= 1); //No arguments + else if ( string(argv[1]) == "--help") + { + printf("\n\t Arguments of the function 'main' \n"); + printf("==============================================================\n\n"); + printf(" --help: Shows this menu... \n\n"); + printf(" --cam_mode cm: Open Camera with the following resolution: \n"); + printf("\t\t VGA (cm = 1), QVGA (cm = 2) \n\n"); + printf(" --fps f: The scene flow frame rate (Hz). \n\n"); + printf(" --rows r: Number of rows at the finest level of the pyramid. \n"); + printf("\t Options: r=15, r=30, r=60, r=120, r=240, r=480 (if VGA)\n"); + system::os::getch(); + return 1; + } + else + { + for (int i=1; i 1.05f/sceneflow.fps) + printf("\n Not enough time to compute the scene flow at %f Hz", sceneflow.fps); + + sceneflow.CaptureFrame(); + clock.Tic(); + sceneflow.createImagePyramidGPU(); + sceneflow.solveSceneFlowGPU(); + const float total_time = 1000.f*clock.Tac(); + cout << endl << "PD-Flow runtime (ms): " << total_time; + + sceneflow.updateScene(); + } + } + + sceneflow.freeGPUMemory(); + sceneflow.CloseCamera(); + return 0; + +} + + diff --git a/pdflow_cudalib.cu b/pdflow_cudalib.cu new file mode 100644 index 0000000..ab0df7b --- /dev/null +++ b/pdflow_cudalib.cu @@ -0,0 +1,1451 @@ +// Author: Mariano Jaimez Tarifa +// Organization: MAPIR, University of Malaga +// Date: Juin 2014 +// License: GNU + +#include "pdflow_cudalib.h" + + +// Memory allocation - device +//============================================================================= +__host__ void CSF_cuda::allocateDevMemory() +{ + const unsigned int width = 640/cam_mode; + const unsigned int height = 480/cam_mode; + unsigned int s; + + //Allocate the unfiltered depth and colour images on GPU + cudaError_t err = cudaMalloc((void**)&depth_wf_dev, width*height*sizeof(float) ); + //printf("%s", cudaGetErrorString(err)); + cudaMalloc((void**)&colour_wf_dev, width*height*sizeof(float) ); + + //Resize pyramid. Allocate memory for the different levels + const unsigned int pyr_levels = roundf(log2f(width/cols)) + ctf_levels; + + for (unsigned int i = 0; i0)&&(v0)&&(u 0.f)&&(fabsf(depth_dev[level-1][ind_loop_prev]-dcenter) < max_depth_dif)) + { + const float aux_w = mask_shared[ind_mask]*(max_depth_dif - fabsf(depth_dev[level-1][ind_loop_prev] - dcenter)); + acu_weights_d += aux_w; + sumd += aux_w*depth_dev[level-1][ind_loop_prev]; + } + } + + if (sumd > 0.f) + depth_dev[level][index] = sumd/acu_weights_d; + else + depth_dev[level][index] = 0.f; + + colour_dev[level][index] = sumc; + } + + //Boundary + else + { + for (int k=-2; k<3; k++) + for (int l=-2; l<3; l++) + { + const int indv = 2*v+k, indu = 2*u+l; + if ((indv>=0)&&(indv<2*rows_i)&&(indu>=0)&&(indu<2*cols_i)) + { + const unsigned int ind_loop_prev = 2*v+k + 2*(2*u+l)*rows_i; + const unsigned int ind_mask = 12+k+5*l; //2+k+(2+l)*5 + + //Colour + sumc += mask_shared[ind_mask]*colour_dev[level-1][ind_loop_prev]; + acu_weights_c += mask_shared[ind_mask]; + + //Depth + if ((depth_dev[level-1][ind_loop_prev] > 0.f)&&(fabsf(depth_dev[level-1][ind_loop_prev]-depth_dev[level-1][ind_cent_prev]) < max_depth_dif)) + { + const float aux_w = mask_shared[ind_mask]*(max_depth_dif - fabsf(depth_dev[level-1][ind_loop_prev] - depth_dev[level-1][ind_cent_prev])); + acu_weights_d += aux_w; + sumd += aux_w*depth_dev[level-1][ind_loop_prev]; + } + } + } + + colour_dev[level][index] = sumc/acu_weights_c; + + if (sumd > 0.f) + depth_dev[level][index] = sumd/acu_weights_d; + else + depth_dev[level][index] = 0.f; + } + } + + //Calculate coordinates "xy" of the points + const float inv_f_i = float(640/cols_i)*f_dist; + const float disp_u_i = 0.5f*(cols_i-1); + const float disp_v_i = 0.5f*(rows_i-1); + + xx_dev[level][index] = (u - disp_u_i)*depth_dev[level][index]*inv_f_i + lens_disp; + yy_dev[level][index] = (v - disp_v_i)*depth_dev[level][index]*inv_f_i; +} + + +// Initiallize some variables +//============================================================================= +__device__ void CSF_cuda::assignZeros(unsigned int index) +{ + du_upsamp_dev[index] = 0.f; dv_upsamp_dev[index] = 0.f; dw_upsamp_dev[index] = 0.f; + pd_upsamp_dev[index] = 0.f; + puu_upsamp_dev[index] = 0.f; puv_upsamp_dev[index] = 0.f; + pvu_upsamp_dev[index] = 0.f; pvv_upsamp_dev[index] = 0.f; + pwu_upsamp_dev[index] = 0.f; pwv_upsamp_dev[index] = 0.f; + + du_prev_dev[index] = 0.f; dv_prev_dev[index] = 0.f; + du_new_dev[index] = 0.f; dv_new_dev[index] = 0.f; dw_new_dev[index] = 0.f; + pd_dev[index] = 0.f; + puu_dev[index] = 0.f; puv_dev[index] = 0.f; + pvu_dev[index] = 0.f; pvv_dev[index] = 0.f; + pwu_dev[index] = 0.f; pwv_dev[index] = 0.f; + + du_acc_dev[index] = 0.f; dv_acc_dev[index] = 0.f; dw_acc_dev[index] = 0.f; +} + + +// Upsample previous solution +//============================================================================= +__device__ void CSF_cuda::upsampleCopyPrevSolution(unsigned int index) +{ + //Calculate (v,u) + const unsigned int v = index%(rows_i/2); + const unsigned int u = 2*index/(rows_i); + const unsigned int index_big = 2*(v + u*rows_i); + + du_upsamp_dev[index_big] = 2.f*du_l_dev[index]; + dv_upsamp_dev[index_big] = 2.f*dv_l_dev[index]; + dw_upsamp_dev[index_big] = dw_l_dev[index]; + pd_upsamp_dev[index_big] = pd_l_dev[index]; + puu_upsamp_dev[index_big] = puu_l_dev[index]; + puv_upsamp_dev[index_big] = puv_l_dev[index]; + pvu_upsamp_dev[index_big] = pvu_l_dev[index]; + pvv_upsamp_dev[index_big] = pvv_l_dev[index]; + pwu_upsamp_dev[index_big] = pwu_l_dev[index]; + pwv_upsamp_dev[index_big] = pwv_l_dev[index]; +} + +__device__ void CSF_cuda::upsampleFilterPrevSolution(unsigned int index) +{ + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + + //Shared memory for the gaussian mask - Warning!! The number of threads should be higher than 25 + __shared__ float mask_shared[25]; + if (threadIdx.x < 25) + mask_shared[threadIdx.x] = 4.f*g_mask_dev[threadIdx.x]; + __syncthreads(); + + float du = 0.f, dv = 0.f, dw = 0.f, pd = 0.f, puu = 0.f, puv = 0.f, pvu = 0.f, pvv = 0.f, pwu = 0.f, pwv = 0.f; + + //Inner pixels + if ((v>1)&&(v1)&&(u=rows_i)||(indu<0)||(indu>=cols_i)) + { + acu_weight -= 0.25f*mask_shared[12 + k + 5*l]; //[2+k + (2+l)*5] + continue; + } + else + { + const unsigned incr_index = v+k+(u+l)*rows_i; + const float gmask_factor = mask_shared[12 + k + 5*l]; //[2+k + (2+l)*5] + du += gmask_factor*du_upsamp_dev[incr_index]; + dv += gmask_factor*dv_upsamp_dev[incr_index]; + dw += gmask_factor*dw_upsamp_dev[incr_index]; + pd += gmask_factor*pd_upsamp_dev[incr_index]; + puu += gmask_factor*puu_upsamp_dev[incr_index]; + puv += gmask_factor*puv_upsamp_dev[incr_index]; + pvu += gmask_factor*pvu_upsamp_dev[incr_index]; + pvv += gmask_factor*pvv_upsamp_dev[incr_index]; + pwu += gmask_factor*pwu_upsamp_dev[incr_index]; + pwv += gmask_factor*pwv_upsamp_dev[incr_index]; + } + } + + const float inv_acu_weight = fdividef(1.f, acu_weight); + du *= inv_acu_weight; + dv *= inv_acu_weight; + dw *= inv_acu_weight; + pd *= inv_acu_weight; + puu *= inv_acu_weight; + puv *= inv_acu_weight; + pvu *= inv_acu_weight; + pvv *= inv_acu_weight; + pwu *= inv_acu_weight; + pwv *= inv_acu_weight; + } + + //Write results to global memory + du_prev_dev[index] = du; + dv_prev_dev[index] = dv; + dw_new_dev[index] = dw; + pd_dev[index] = pd; + puu_dev[index] = puu; + puv_dev[index] = puv; + pvu_dev[index] = pvu; + pvv_dev[index] = pvv; + pwu_dev[index] = pwu; + pwv_dev[index] = pwv; + + //Last update, for dw_acc + dw_acc_dev[index] = dw; +} + + +// Compute intensity and depth derivatives +//============================================================================= +__device__ void CSF_cuda::computeImGradients(unsigned int index) +{ + //Calculate (v,u) + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + + //Row gradients + if (u == 0) + { + dcu_aux_dev[index] = colour_dev[level_image][index+rows_i] - colour_dev[level_image][index]; + ddu_aux_dev[index] = depth_dev[level_image][index+rows_i] - depth_dev[level_image][index]; + } + else if (u == cols_i-1) + { + dcu_aux_dev[index] = colour_dev[level_image][index] - colour_dev[level_image][index-rows_i]; + ddu_aux_dev[index] = depth_dev[level_image][index] - depth_dev[level_image][index-rows_i]; + } + else + { + dcu_aux_dev[index] = (ri_2_dev[index]*(colour_dev[level_image][index+rows_i]-colour_dev[level_image][index]) + + ri_2_dev[index-rows_i]*(colour_dev[level_image][index]-colour_dev[level_image][index-rows_i])) + /(ri_2_dev[index]+ri_2_dev[index-rows_i]); + if (depth_dev[level_image][index] > 0.f) + ddu_aux_dev[index] = (ri_2_dev[index]*(depth_dev[level_image][index+rows_i]-depth_dev[level_image][index]) + + ri_2_dev[index-rows_i]*(depth_dev[level_image][index]-depth_dev[level_image][index-rows_i])) + /(ri_2_dev[index]+ri_2_dev[index-rows_i]); + else + ddu_aux_dev[index] = 0.f; + } + + //Col gradients + if (v == 0) + { + dcv_aux_dev[index] = colour_dev[level_image][index+1] - colour_dev[level_image][index]; + ddv_aux_dev[index] = depth_dev[level_image][index+1] - depth_dev[level_image][index]; + } + else if (v == rows_i-1) + { + dcv_aux_dev[index] = colour_dev[level_image][index] - colour_dev[level_image][index-1]; + ddv_aux_dev[index] = depth_dev[level_image][index] - depth_dev[level_image][index-1]; + } + else + { + dcv_aux_dev[index] = (rj_2_dev[index]*(colour_dev[level_image][index+1]-colour_dev[level_image][index]) + + rj_2_dev[index-1]*(colour_dev[level_image][index]-colour_dev[level_image][index-1])) + /(rj_2_dev[index]+rj_2_dev[index-1]); + if (depth_dev[level_image][index] > 0.f) + ddv_aux_dev[index] = (rj_2_dev[index]*(depth_dev[level_image][index+1]-depth_dev[level_image][index]) + + rj_2_dev[index-1]*(depth_dev[level_image][index]-depth_dev[level_image][index-1])) + /(rj_2_dev[index]+rj_2_dev[index-1]); + else + ddv_aux_dev[index] = 0.f; + } +} + +__device__ void CSF_cuda::performWarping(unsigned int index) +{ + //Calculate (v,u) + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + float warped_pixel; + + //Intensity images + const float ind_uf = float(u) + du_prev_dev[index]; + const float ind_vf = float(v) + dv_prev_dev[index]; + warped_pixel = interpolatePixel(colour_dev[level_image], ind_uf, ind_vf); + dct_dev[index] = warped_pixel - colour_old_dev[level_image][index]; + dcu_dev[index] = interpolatePixel(dcu_aux_dev, ind_uf, ind_vf); + dcv_dev[index] = interpolatePixel(dcv_aux_dev, ind_uf, ind_vf); + + //Depth images + warped_pixel = interpolatePixelDepth(depth_dev[level_image], ind_uf, ind_vf); + if (warped_pixel > 0.f) + ddt_dev[index] = warped_pixel - depth_old_dev[level_image][index]; + else + ddt_dev[index] = 0.f; + ddu_dev[index] = interpolatePixel(ddu_aux_dev, ind_uf, ind_vf); + ddv_dev[index] = interpolatePixel(ddv_aux_dev, ind_uf, ind_vf); +} + +__device__ float CSF_cuda::interpolatePixel(float *mat, float ind_u, float ind_v) +{ + if (ind_u < 0.f) { ind_u = 0.f;} + else if (ind_u > cols_i - 1.f) { ind_u = cols_i - 1.f;} + if (ind_v < 0.f) { ind_v = 0.f;} + else if (ind_v > rows_i - 1.f) { ind_v = rows_i - 1.f;} + + const unsigned int sup_u = __float2int_ru(ind_u); + const unsigned int inf_u = __float2int_rd(ind_u); + const unsigned int sup_v = __float2int_ru(ind_v); + const unsigned int inf_v = __float2int_rd(ind_v); + + if ((sup_u == inf_u)&&(sup_v == inf_v)) + return mat[lrintf(ind_v + rows_i*ind_u)]; + + else if (sup_u == inf_u) + return (sup_v - ind_v)*mat[inf_v + rows_i*lrintf(ind_u)] + (ind_v - inf_v)*mat[sup_v + rows_i*lrintf(ind_u)]; + + else if (sup_v == inf_v) + return (sup_u - ind_u)*mat[lrintf(ind_v) + rows_i*inf_u] + (ind_u - inf_u)*mat[lrintf(ind_v) + rows_i*sup_u]; + + else + { + //First in u + const float val_sup_v = (sup_u - ind_u)*mat[sup_v + rows_i*inf_u] + (ind_u - inf_u)*mat[sup_v + rows_i*sup_u]; + const float val_inf_v = (sup_u - ind_u)*mat[inf_v + rows_i*inf_u] + (ind_u - inf_u)*mat[inf_v + rows_i*sup_u]; + return (sup_v - ind_v)*val_inf_v + (ind_v - inf_v)*val_sup_v; + } +} + +__device__ float CSF_cuda::interpolatePixelDepth(float *mat, float ind_u, float ind_v) +{ + if (ind_u < 0.f) { ind_u = 0.f;} + else if (ind_u > cols_i - 1.f) { ind_u = cols_i - 1.f;} + if (ind_v < 0.f) { ind_v = 0.f;} + else if (ind_v > rows_i - 1.f) { ind_v = rows_i - 1.f;} + + const unsigned int sup_u = __float2int_ru(ind_u); + const unsigned int inf_u = __float2int_rd(ind_u); + const unsigned int sup_v = __float2int_ru(ind_v); + const unsigned int inf_v = __float2int_rd(ind_v); + + if ((mat[sup_v + rows_i*sup_u] == 0.f)||(mat[sup_v + rows_i*inf_u] == 0.f)||(mat[inf_v + rows_i*sup_u] == 0.f)||(mat[inf_v + rows_i*inf_u]==0.f)) + { + const unsigned int rind_u = __float2int_rn(ind_u); + const unsigned int rind_v = __float2int_rn(ind_v); + return mat[rind_v + rows_i*rind_u]; + } + else + { + if ((sup_u == inf_u)&&(sup_v == inf_v)) + return mat[lrintf(ind_v + rows_i*ind_u)]; + + else if (sup_u == inf_u) + return (sup_v - ind_v)*mat[inf_v + rows_i*lroundf(ind_u)] + (ind_v - inf_v)*mat[sup_v + rows_i*lroundf(ind_u)]; + + else if (sup_v == inf_v) + return (sup_u - ind_u)*mat[lroundf(ind_v) + rows_i*inf_u] + (ind_u - inf_u)*mat[lroundf(ind_v) + rows_i*sup_u]; + + else + { + //First in u + const float val_sup_v = (sup_u - ind_u)*mat[sup_v + rows_i*inf_u] + (ind_u - inf_u)*mat[sup_v + rows_i*sup_u]; + const float val_inf_v = (sup_u - ind_u)*mat[inf_v + rows_i*inf_u] + (ind_u - inf_u)*mat[inf_v + rows_i*sup_u]; + return (sup_v - ind_v)*val_inf_v + (ind_v - inf_v)*val_sup_v; + } + } +} + +// Preliminary computations +//============================================================================= +__device__ void CSF_cuda::computeRij(unsigned int index) +{ + //Calculate (v,u) + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + + float dxu, dzu, dxu_2, dzu_2; + float dyv, dzv, dyv_2, dzv_2; + + if (u == cols_i-1) + { + dxu = 0.f; dzu = 0.f; + dxu_2 = 0.f; dzu_2 = 0.f; + } + else + { + dxu = xx_old_dev[level_image][index + rows_i] - xx_old_dev[level_image][index]; + dzu = depth_old_dev[level_image][index + rows_i] - depth_old_dev[level_image][index]; + dxu_2 = xx_dev[level_image][index + rows_i] - xx_dev[level_image][index]; + dzu_2 = depth_dev[level_image][index + rows_i] - depth_dev[level_image][index]; + } + + if (v == rows_i-1) + { + dyv = 0.f; dzv = 0.f; + dyv_2 = 0.f; dzv_2 = 0.f; + } + else + { + dyv = yy_old_dev[level_image][index+1] - yy_old_dev[level_image][index]; + dzv = depth_old_dev[level_image][index+1] - depth_old_dev[level_image][index]; + dyv_2 = yy_dev[level_image][index+1] - yy_dev[level_image][index]; + dzv_2 = depth_dev[level_image][index+1] - depth_dev[level_image][index]; + } + + if (fabsf(dxu) + fabsf(dzu) > 0.f) + ri_dev[index] = 2.f*rhypotf(dxu,dzu); //2.f/sqrtf(dxu*dxu + dzu*dzu); + else + ri_dev[index] = 1.f; + + if (fabsf(dyv) + fabsf(dzv) > 0.f) + rj_dev[index] = 2.f*rhypotf(dyv,dzv); //2.f/sqrtf(dyv*dyv + dzv*dzv); + else + rj_dev[index] = 1.f; + + if (fabsf(dxu_2) + fabsf(dzu_2) > 0.f) + ri_2_dev[index] = 2.f*rhypotf(dxu_2,dzu_2); //2.f/sqrtf(dxu*dxu + dzu*dzu); + else + ri_2_dev[index] = 1.f; + + if (fabsf(dyv_2) + fabsf(dzv_2) > 0.f) + rj_2_dev[index] = 2.f*rhypotf(dyv_2,dzv_2); //2.f/sqrtf(dyv*dyv + dzv*dzv); + else + rj_2_dev[index] = 1.f; +} + +__device__ void CSF_cuda::computeMu(unsigned int index) +{ + mu_uv_dev[index] = fdividef(mu, 1.f + 1000.f*(ddu_dev[index]*ddu_dev[index] + ddv_dev[index]*ddv_dev[index] + ddt_dev[index]*ddt_dev[index])); +} + +__device__ void CSF_cuda::computeStepSizes(unsigned int index) +{ + //Load lambda from global memory + const float lambdai = lambda_i, lambdad = lambda_d; + + sigma_pd_dev[index] = fdividef(1.f, mu_uv_dev[index]*(1.f + abs(ddt_dev[index]) + abs(ddu_dev[index]) + abs(ddv_dev[index])) + 1e-10f); + sigma_puvx_dev[index] = fdividef(0.5f, lambdai*ri_dev[index] + 1e-10f); + sigma_puvy_dev[index] = fdividef(0.5f, lambdai*rj_dev[index] + 1e-10f); + sigma_pwx_dev[index] = fdividef(0.5f, ri_dev[index]*lambdad + 1e-10f); + sigma_pwy_dev[index] = fdividef(0.5f, rj_dev[index]*lambdad + 1e-10f); + tau_u_dev[index] = fdividef(1.f, mu_uv_dev[index]*abs(ddu_dev[index]) + 2.f*lambdai*(ri_dev[index] + rj_dev[index]) + 1e-10f); + tau_v_dev[index] = fdividef(1.f, mu_uv_dev[index]*abs(ddv_dev[index]) + 2.f*lambdai*(ri_dev[index] + rj_dev[index]) + 1e-10f); + tau_w_dev[index] = fdividef(1.f, mu_uv_dev[index] + 2.f*lambdad*(ri_dev[index] + rj_dev[index]) + 1e-10f); +} + + +// Main iteration +//============================================================================= +__device__ void CSF_cuda::updateDualVariables(unsigned int index) +{ + //Create aux variables + float module_p; + float pd = pd_dev[index], puu = puu_dev[index], puv = puv_dev[index]; + float pvu = pvu_dev[index], pvv = pvv_dev[index], pwu = pwu_dev[index], pwv = pwv_dev[index]; + + //Update dual variables + //Solve pd + pd += sigma_pd_dev[index]*mu_uv_dev[index]*(-dw_acc_dev[index] + ddt_dev[index] + ddu_dev[index]*du_acc_dev[index] + ddv_dev[index]*dv_acc_dev[index]); + + //Solve pu + puu += sigma_puvx_dev[index]*lambda_i*gradu1_dev[index]; + puv += sigma_puvy_dev[index]*lambda_i*gradu2_dev[index]; + + //Solve pv + pvu += sigma_puvx_dev[index]*lambda_i*gradv1_dev[index]; + pvv += sigma_puvy_dev[index]*lambda_i*gradv2_dev[index]; + + //Solve pw + pwu += sigma_pwx_dev[index]*lambda_d*gradw1_dev[index]; + pwv += sigma_pwy_dev[index]*lambda_d*gradw2_dev[index]; + + //Constrain pd + module_p = fabsf(pd); + if (module_p > 1.f) + { + if (pd > 1.f) + pd_dev[index] = 1.f; + else + pd_dev[index] = -1.f; + } + else + pd_dev[index] = pd; + + //Constrain pu + module_p = rhypotf(puu, puv); //1.f/sqrtf(puu*puu + puv*puv); + if (module_p < 1.f) + { + puu_dev[index] = puu*module_p; + puv_dev[index] = puv*module_p; + } + else + { + puu_dev[index] = puu; + puv_dev[index] = puv; + } + + //Constrain pv + module_p = rhypotf(pvu, pvv); //1.f/sqrtf(pvu*pvu + pvv*pvv); + if (module_p < 1.f) + { + pvu_dev[index] = pvu*module_p; + pvv_dev[index] = pvv*module_p; + } + else + { + pvu_dev[index] = pvu; + pvv_dev[index] = pvv; + } + + //Constrain pw + module_p = rhypotf(pwu, pwv); //1.f/sqrt(pwu*pwu + pwv*pwv); + if (module_p < 1.f) + { + pwu_dev[index] = pwu*module_p; + pwv_dev[index] = pwv*module_p; + } + else + { + pwu_dev[index] = pwu; + pwv_dev[index] = pwv; + } + +} + +__device__ void CSF_cuda::updatePrimalVariables(unsigned int index) +{ + float du = du_new_dev[index], dv = dv_new_dev[index], dw = dw_new_dev[index]; + const float du_old = du, dv_old = dv, dw_old = dw; + + //Compute du, dv and dw + //Solve du + du += - tau_u_dev[index]*(mu_uv_dev[index]*ddu_dev[index]*pd_dev[index] - lambda_i*divpu_dev[index]); + + //Solve dv + dv += - tau_v_dev[index]*(mu_uv_dev[index]*ddv_dev[index]*pd_dev[index] - lambda_i*divpv_dev[index]); + + //Solve dw + dw += - tau_w_dev[index]*(-mu_uv_dev[index]*pd_dev[index] - lambda_d*divpw_dev[index]); + + //shrink du, dv and dw + //----------------------------------------------------------- + const float optflow = dct_dev[index] + dcu_dev[index]*du + dcv_dev[index]*dv; + const float of_threshold = tau_u_dev[index]*dcu_dev[index]*dcu_dev[index] + tau_v_dev[index]*dcv_dev[index]*dcv_dev[index]; + if (optflow < -of_threshold) + { + du += tau_u_dev[index]*dcu_dev[index]; + dv += tau_v_dev[index]*dcv_dev[index]; + } + else if (optflow > of_threshold) + { + du -= tau_u_dev[index]*dcu_dev[index]; + dv -= tau_v_dev[index]*dcv_dev[index]; + } + else + { + const float den = tau_u_dev[index]*dcu_dev[index]*dcu_dev[index] + tau_v_dev[index]*dcv_dev[index]*dcv_dev[index] + 1e-10f; + du -= tau_u_dev[index]*dcu_dev[index]*optflow/den; + dv -= tau_v_dev[index]*dcv_dev[index]*optflow/den; + } + + //Update du, dv + du_acc_dev[index] = 2.f*du - du_old; + dv_acc_dev[index] = 2.f*dv - dv_old; + dw_acc_dev[index] = 2.f*dw - dw_old; + + du_new_dev[index] = du; + dv_new_dev[index] = dv; + dw_new_dev[index] = dw; +} + +__device__ void CSF_cuda::computeDivergence(unsigned int index) +{ + //Calculate (v,u) + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + + //First terms + if (u == 0) + { + divpu_dev[index] = ri_dev[index]*puu_dev[index]; + divpv_dev[index] = ri_dev[index]*pvu_dev[index]; + divpw_dev[index] = ri_dev[index]*pwu_dev[index]; + } + else if (u == cols_i-1) + { + divpu_dev[index] = -ri_dev[index]*puu_dev[index-rows_i]; + divpv_dev[index] = -ri_dev[index]*pvu_dev[index-rows_i]; + divpw_dev[index] = -ri_dev[index]*pwu_dev[index-rows_i]; + } + else + { + divpu_dev[index] = ri_dev[index]*(puu_dev[index] - puu_dev[index-rows_i]); + divpv_dev[index] = ri_dev[index]*(pvu_dev[index] - pvu_dev[index-rows_i]); + divpw_dev[index] = ri_dev[index]*(pwu_dev[index] - pwu_dev[index-rows_i]); + } + + //Second term + if (v == 0) + { + divpu_dev[index] += rj_dev[index]*puv_dev[index]; + divpv_dev[index] += rj_dev[index]*pvv_dev[index]; + divpw_dev[index] += rj_dev[index]*pwv_dev[index]; + } + else if (v == rows_i-1) + { + divpu_dev[index] += -rj_dev[index]*puv_dev[index-1]; + divpv_dev[index] += -rj_dev[index]*pvv_dev[index-1]; + divpw_dev[index] += -rj_dev[index]*pwv_dev[index-1]; + } + else + { + divpu_dev[index] += rj_dev[index]*(puv_dev[index] - puv_dev[index-1]); + divpv_dev[index] += rj_dev[index]*(pvv_dev[index] - pvv_dev[index-1]); + divpw_dev[index] += rj_dev[index]*(pwv_dev[index] - pwv_dev[index-1]); + } +} + +__device__ void CSF_cuda::computeGradient(unsigned int index) +{ + //Calculate (v,u) + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + + if (u == cols_i-1) + { + gradu1_dev[index] = 0.f; + gradv1_dev[index] = 0.f; + gradw1_dev[index] = 0.f; + } + else + { + gradu1_dev[index] = ri_dev[index]*((du_acc_dev[index+rows_i] + du_prev_dev[index+rows_i]) - (du_acc_dev[index] + du_prev_dev[index])); + gradv1_dev[index] = ri_dev[index]*((dv_acc_dev[index+rows_i] + dv_prev_dev[index+rows_i]) - (dv_acc_dev[index] + dv_prev_dev[index])); + gradw1_dev[index] = ri_dev[index]*(dw_acc_dev[index+rows_i] - dw_acc_dev[index]); + } + + if (v == rows_i-1) + { + gradu2_dev[index] = 0.f; + gradv2_dev[index] = 0.f; + gradw2_dev[index] = 0.f; + } + else + { + gradu2_dev[index] = rj_dev[index]*((du_acc_dev[index+1] + du_prev_dev[index+1]) - (du_acc_dev[index] + du_prev_dev[index])); + gradv2_dev[index] = rj_dev[index]*((dv_acc_dev[index+1] + dv_prev_dev[index+1]) - (dv_acc_dev[index] + dv_prev_dev[index])); + gradw2_dev[index] = rj_dev[index]*(dw_acc_dev[index+1] - dw_acc_dev[index]); + } +} + + +// Filter +//============================================================================= +__device__ void CSF_cuda::saturateVariables(unsigned int index) +{ + float du = du_new_dev[index], dv = dv_new_dev[index], dw = dw_new_dev[index]; + if (du > 1.f) + du = 1.f; + else if (du < -1.f) + du = -1.f; + + if (dv > 1.f) + dv = 1.f; + else if (dv < -1.f) + dv = -1.f; + + if (depth_old_dev[level_image][index] == 0.f) + dw = 0.f; + + //Add previous solution to filter all together + du_new_dev[index] = du + du_prev_dev[index]; + dv_new_dev[index] = dv + dv_prev_dev[index]; + dw_new_dev[index] = dw; +} + +__device__ void CSF_cuda::filterSolution(unsigned int index) +{ + const float depth_old = depth_old_dev[level_image][index]; + + //Calculate (v,u) + const unsigned int v = index%rows_i; + const unsigned int u = index/rows_i; + + //Median filter + fieldAndPresence up[9], vp[9], wp[9]; + float pres_cum_u[9], pres_cum_v[9], pres_cum_w[9], pres_med; + int indr, indc, ind_loop; + unsigned int point_count, v_index; + const float kd = 5.f; + const float kddt = 10.f; + + if (depth_old > 0.f) + { + point_count = 9; + v_index = 0; + + for (int k=-1; k<2; k++) + for (int l=-1; l<2; l++) + { + indr = v+k; + indc = u+l; + ind_loop = index + l*rows_i + k; + if ((indr < 0)||(indr >= rows_i)||(indc < 0)||(indc >= cols_i)) + { + point_count--; + continue; + } + + //Compute presence of every element + const float pres = 1.f/(1.f + kd*powf(depth_old - depth_old_dev[level_image][ind_loop],2.f) + kddt*powf(ddt_dev[ind_loop],2.f)); + + up[v_index].field = du_new_dev[ind_loop]; up[v_index].pres = pres; + vp[v_index].field = dv_new_dev[ind_loop]; vp[v_index].pres = pres; + wp[v_index].field = dw_new_dev[ind_loop]; wp[v_index].pres = pres; + v_index++; + } + + //Sort vectors (both the solution and the presence) + bubbleSortDev(up, point_count); + bubbleSortDev(vp, point_count); + bubbleSortDev(wp, point_count); + + //Compute cumulative presence + pres_cum_u[0] = up[0].pres; pres_cum_v[0] = vp[0].pres; pres_cum_w[0] = wp[0].pres; + for (unsigned int i=1; i pres_cum_u[cont]) {cont++;} + if (cont == 0) + du_l_dev[index] = up[0].field; + else + { + ind_r = cont; ind_l = cont-1; + du_l_dev[index] = ((pres_cum_u[ind_r] - pres_med)*up[ind_l].field + (pres_med - pres_cum_u[ind_l])*up[ind_r].field)/(pres_cum_u[ind_r] - pres_cum_u[ind_l]); + } + + //For v + cont = 0; + while (pres_med > pres_cum_v[cont]) {cont++;} + if (cont == 0) + dv_l_dev[index] = vp[0].field; + else + { + ind_r = cont; ind_l = cont-1; + dv_l_dev[index] = ((pres_cum_v[ind_r] - pres_med)*vp[ind_l].field + (pres_med - pres_cum_v[ind_l])*vp[ind_r].field)/(pres_cum_v[ind_r] - pres_cum_v[ind_l]); + } + + //For w + cont = 0; + while (pres_med > pres_cum_w[cont]) {cont++;} + if (cont == 0) + dw_l_dev[index] = wp[0].field; + else + { + ind_r = cont; ind_l = cont-1; + dw_l_dev[index] = ((pres_cum_w[ind_r] - pres_med)*wp[ind_l].field + (pres_med - pres_cum_w[ind_l])*wp[ind_r].field)/(pres_cum_w[ind_r] - pres_cum_w[ind_l]); + } + } + else + { + du_l_dev[index] = du_new_dev[index]; + dv_l_dev[index] = dv_new_dev[index]; + dw_l_dev[index] = dw_new_dev[index]; + } + + pd_l_dev[index] = pd_dev[index]; + puu_l_dev[index] = puu_dev[index]; + puv_l_dev[index] = puv_dev[index]; + pvu_l_dev[index] = pvu_dev[index]; + pvv_l_dev[index] = pvv_dev[index]; + pwu_l_dev[index] = pwu_dev[index]; + pwv_l_dev[index] = pwv_dev[index]; +} + +__device__ void CSF_cuda::computeMotionField(unsigned int index) +{ + //Fill the matrices dx,dy,dz with the final solution + const float x_incr = 2.f*f_dist*tanf(0.5f*fovh)/(cols_i-1); //In meters + const float y_incr = 2.f*f_dist*tanf(0.5f*fovv)/(rows_i-1); //In meters + const float fx = f_dist/x_incr; + const float fy = f_dist/y_incr; + + + if (depth_old_dev[level_image][index] > 0) + { + dx_dev[index] = dw_l_dev[index]; + dy_dev[index] = depth_old_dev[level_image][index]*du_l_dev[index]/fx + dw_l_dev[index]*xx_old_dev[level_image][index]/depth_old_dev[level_image][index]; + dz_dev[index] = depth_old_dev[level_image][index]*dv_l_dev[index]/fy + dw_l_dev[index]*yy_old_dev[level_image][index]/depth_old_dev[level_image][index]; + } + else + { + dx_dev[index] = 0.f; + dy_dev[index] = 0.f; + dz_dev[index] = 0.f; + } +} + + +// Bridges +//================================================================================= +void GaussianPyramidBridge(CSF_cuda *csf, unsigned int levels, unsigned int cam_mode) +{ + for (unsigned int i=0; irows_i, &rows_i_aux, sizeof(float), cudaMemcpyHostToDevice); + cudaMemcpy(&csf->cols_i, &cols_i_aux, sizeof(float), cudaMemcpyHostToDevice); + + ComputePyramidLevelKernel <<>>(csf, i); + } +} + +void AssignZerosBridge(CSF_cuda *csf) +{ + AssignZerosKernel <<>>(csf); +} + +void UpsampleBridge(CSF_cuda *csf) +{ + UpsampleCopyKernel <<>>(csf); + UpsampleFilterKernel <<>>(csf); +} + +void ImageGradientsBridge(CSF_cuda *csf) +{ + ComputeImGradients <<>>(csf); +} + +void WarpingBridge(CSF_cuda *csf) +{ + PerformWarping <<>> (csf); +} + +void RijBridge(CSF_cuda *csf) +{ + RijKernel <<>>(csf); +} + +void MuAndStepSizesBridge(CSF_cuda *csf) +{ + MuAndStepSizesKernel <<>>(csf); +} + +void DualVariablesBridge(CSF_cuda *csf) +{ + DualIteration <<>>(csf); +} + +void PrimalVariablesBridge(CSF_cuda *csf) +{ + PrimalIteration <<>>(csf); +} + +void DivergenceBridge(CSF_cuda *csf) +{ + DivergenceComputation <<>>(csf); +} + +void GradientBridge(CSF_cuda *csf) +{ + GradientComputation <<>>(csf); +} + +void FilterBridge(CSF_cuda *csf) +{ + SaturateSolution <<>>(csf); + FilterSolution <<>>(csf); +} + +void MotionFieldBridge(CSF_cuda *csf) +{ + MotionFieldKernel <<>>(csf); +} + +void DebugBridge(CSF_cuda *csf_device) +{ + printf("Entro en el debug bridge"); + DebugKernel <<<1,1>>>(csf_device); +} + +void BridgeBack(CSF_cuda *csf_host, CSF_cuda *csf_device) +{ + cudaMemcpy(csf_host, csf_device, sizeof(CSF_cuda), cudaMemcpyDeviceToHost); + cudaFree(csf_device); +} + + +// Kernels +//============================================================================= +__global__ void DebugKernel(CSF_cuda *csf) +{ + printf("\n dx: "); + for (unsigned int i = 0; i< (csf->rows_i)*(csf->cols_i); i++) //(csf->rows)*(csf->cols) + printf(" %f", csf->dx_dev[i]); + +} + +__global__ void ComputePyramidLevelKernel (CSF_cuda *csf, unsigned int level) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computePyramidLevel(index, level); + index += blockDim.x*gridDim.x; + } +} + +__global__ void AssignZerosKernel (CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->assignZeros(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void UpsampleCopyKernel (CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i/4) + { + csf->upsampleCopyPrevSolution(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void UpsampleFilterKernel (CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->upsampleFilterPrevSolution(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void ComputeImGradients(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computeImGradients(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void PerformWarping(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->performWarping(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void RijKernel(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computeRij(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void MuAndStepSizesKernel(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computeMu(index); + csf->computeStepSizes(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void DualIteration(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->updateDualVariables(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void PrimalIteration(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->updatePrimalVariables(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void DivergenceComputation(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computeDivergence(index); + index += blockDim.x*gridDim.x; + } +} + + +__global__ void GradientComputation(CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computeGradient(index); + index += blockDim.x*gridDim.x; + } +} + + +__global__ void SaturateSolution (CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->saturateVariables(index); + index += blockDim.x*gridDim.x; + } +} + + +__global__ void FilterSolution (CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->filterSolution(index); + index += blockDim.x*gridDim.x; + } +} + +__global__ void MotionFieldKernel (CSF_cuda *csf) +{ + // detect pixel + unsigned int index = threadIdx.x + blockDim.x*blockIdx.x; + + while (index < csf->rows_i*csf->cols_i) + { + csf->computeMotionField(index); + index += blockDim.x*gridDim.x; + } +} + +//Naive implementations of bubbleSort (applied to very small arrays) +__device__ void bubbleSortDev(fieldAndPresence array[], unsigned int num_elem) +{ + bool go_on = true; + while (go_on) + { + go_on = false; + for (unsigned int i=1; i array[i].field) + { + ELEM_SWAP(array[i-1].field,array[i].field); + ELEM_SWAP(array[i-1].pres,array[i].pres); + go_on = true; + } + } + } +} + + + + diff --git a/pdflow_cudalib.h b/pdflow_cudalib.h new file mode 100644 index 0000000..501dfec --- /dev/null +++ b/pdflow_cudalib.h @@ -0,0 +1,195 @@ +// Author: Mariano Jaimez Tarifa +// Organization: MAPIR, University of Malaga +// Date: Juin 2014 +// License: GNU + +#include +#include +#include + +#define N_blocks 256 //128 +#define N_threads 128 //256 + +//Warning!!!!!! Number of threads should be higher than 25 - See definition of "computePyramidLevel()" + +#define ELEM_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } + +//-------------------------------------------------------------- +// Host-Device class for the PD-Flow +//-------------------------------------------------------------- +class CSF_cuda { +public: + + //Parameters + unsigned int rows; + unsigned int cols; + unsigned int ctf_levels; + unsigned int cam_mode; + float lambda_i; + float lambda_d; + float mu; + float lens_disp; + float fovh; + float fovv; + float f_dist; + + //Local values + unsigned int local_level; + unsigned int level_image; + unsigned int rows_i, cols_i; + + //Compute gaussian mask + float *g_mask_dev; + + //Last frames read + float *colour_wf_dev, *depth_wf_dev; + + //Images and coordinates (pointers to pointers...) + float *depth_old_dev[8], *xx_old_dev[8], *yy_old_dev[8]; + float *depth_dev[8], *xx_dev[8], *yy_dev[8]; + float *colour_old_dev[8], *colour_dev[8]; + + //Motion field + float *dx_dev, *dy_dev, *dz_dev; + + //Intensity and depth gradients without warping + float *dcu_aux_dev, *dcv_aux_dev; + float *ddu_aux_dev, *ddv_aux_dev; + + //Warped intensity and depth gradients + float *dct_dev, *dcu_dev, *dcv_dev; + float *ddt_dev, *ddu_dev, *ddv_dev; + + //Motion field gradients + float *gradu1_dev, *gradu2_dev; + float *gradv1_dev, *gradv2_dev; + float *gradw1_dev, *gradw2_dev; + + //Divergence of dual variables + float *divpu_dev, *divpv_dev, *divpw_dev; + + //Primal and dual step sizes + float *sigma_pd_dev, *sigma_puvx_dev, *sigma_puvy_dev; + float *sigma_pwx_dev, *sigma_pwy_dev; + float *tau_u_dev, *tau_v_dev, *tau_w_dev; + + //Weights for data terms and regularization + float *mu_uv_dev; + float *ri_dev, *rj_dev; + float *ri_2_dev, *rj_2_dev; + + //Primal-dual acceleration and previous solution + float *du_acc_dev, *dv_acc_dev, *dw_acc_dev; + float *du_prev_dev, *dv_prev_dev; + + //Aux variables for gaussian upsampling + float *du_upsamp_dev, *dv_upsamp_dev, *dw_upsamp_dev; + float *pd_upsamp_dev; + float *puu_upsamp_dev, *puv_upsamp_dev; + float *pvu_upsamp_dev, *pvv_upsamp_dev; + float *pwu_upsamp_dev, *pwv_upsamp_dev; + + //Solution of the previous level (only store one) + float *du_l_dev, *dv_l_dev, *dw_l_dev; + float *pd_l_dev; + float *puu_l_dev, *puv_l_dev; + float *pvu_l_dev, *pvv_l_dev; + float *pwu_l_dev, *pwv_l_dev; + + //Primal and dual variables + float *du_new_dev; + float *dv_new_dev; + float *dw_new_dev; + float *pd_dev; + float *puu_dev, *puv_dev; + float *pvu_dev, *pvv_dev; + float *pwu_dev, *pwv_dev; + + + __host__ void allocateDevMemory(); + __host__ void allocateMemoryNewLevel(unsigned int rows_loc, unsigned int cols_loc, unsigned int level_i, unsigned int level_image_i); + __host__ void readParameters(unsigned int rows_host, unsigned int cols_host, float lambda_i_host, float lambda_d_host, + float mu_host, float *g_mask, unsigned int levels_host, float lens_displ_host, + unsigned int cam_mode_host, float fovh_host, float fovv_host, float f_dist_host); + + __host__ void copyNewFrames(float *colour_wf, float *depth_wf); + __host__ void freeDeviceMemory(); + __host__ void freeLevelVariables(); + __host__ void copyAllSolutions(float *dx, float *dy, float *dz, float *depth, float *depth_old, float *colour, float *colour_old, float *xx, float *xx_old, float *yy, float *yy_old); + __host__ void copyMotionField(float *dx, float *dy, float *dz); + + __device__ void computePyramidLevel(unsigned int index, unsigned int level); + __device__ void assignZeros(unsigned int index); + __device__ void upsampleCopyPrevSolution(unsigned int index); + __device__ void upsampleFilterPrevSolution(unsigned int index); + __device__ void computeImGradients(unsigned int index); + __device__ void performWarping(unsigned int index); + __device__ void computeRij(unsigned int index); + __device__ void computeMu(unsigned int index); + __device__ void computeStepSizes(unsigned int index); + __device__ void updateDualVariables(unsigned int index); + __device__ void updatePrimalVariables(unsigned int index); + __device__ void computeDivergence(unsigned int index); + __device__ void computeGradient(unsigned int index); + __device__ void saturateVariables(unsigned int index); + __device__ void filterSolution(unsigned int index); + __device__ float interpolatePixel(float *mat, float ind_u, float ind_v); + __device__ float interpolatePixelDepth(float *mat, float ind_u, float ind_v); + __device__ void computeMotionField(unsigned int index); +}; + +//------------------------------------------------------------------------------------------------------- +// Bridges between Cuda-related functions and the code compiled with the standard compiler (without CUDA) +//------------------------------------------------------------------------------------------------------- +CSF_cuda *ObjectToDevice(CSF_cuda *csf_host); +void GaussianPyramidBridge(CSF_cuda *csf, unsigned int levels, unsigned int cam_mode); +void AssignZerosBridge(CSF_cuda *csf); +void UpsampleBridge(CSF_cuda *csf); +void ImageGradientsBridge(CSF_cuda *csf); +void RijBridge(CSF_cuda *csf); +void WarpingBridge(CSF_cuda *csf); +void MuAndStepSizesBridge(CSF_cuda *csf); +void DualVariablesBridge(CSF_cuda *csf); +void PrimalVariablesBridge(CSF_cuda *csf); +void DivergenceBridge(CSF_cuda *csf); +void GradientBridge(CSF_cuda *csf); +void FilterBridge(CSF_cuda *csf); +void MotionFieldBridge(CSF_cuda *csf); +void DebugBridge(CSF_cuda *csf_device); +void BridgeBack(CSF_cuda *csf_host, CSF_cuda *csf_device); + +//------------------------------------------------------------------------------------------------------- +// Kernels corresponding to the main steps of the algorithm (and aux kernels) +//------------------------------------------------------------------------------------------------------- +__global__ void ComputePyramidLevelKernel (CSF_cuda *csf, unsigned int level); +__global__ void AssignZerosKernel (CSF_cuda *csf); +__global__ void UpsampleCopyKernel (CSF_cuda *csf); +__global__ void UpsampleFilterKernel (CSF_cuda *csf); +__global__ void RijKernel(CSF_cuda *csf); +__global__ void ComputeImGradients (CSF_cuda *csf); +__global__ void PerformWarping(CSF_cuda *csf); +__global__ void MuAndStepSizesKernel(CSF_cuda *csf); +__global__ void DualIteration(CSF_cuda *csf); +__global__ void PrimalIteration(CSF_cuda *csf); +__global__ void DivergenceComputation(CSF_cuda *csf); +__global__ void GradientComputation(CSF_cuda *csf); +__global__ void SaturateSolution(CSF_cuda *csf); +__global__ void FilterSolution(CSF_cuda *csf); +__global__ void MotionFieldKernel (CSF_cuda *csf); +__global__ void DebugKernel(CSF_cuda *csf); + +//----------------------------------------------------------------------------- +// Aux functions for the weighted median filter +//----------------------------------------------------------------------------- + +//Sorting - Structure field and presence +struct fieldAndPresence { + float field; + float pres; +}; + +//Naive implementation of bubbleSort (applied to very small arrays) +__device__ void bubbleSortDev(fieldAndPresence array[], unsigned int num_elem); + + + diff --git a/scene_flow_impair.cpp b/scene_flow_impair.cpp new file mode 100644 index 0000000..6bbe74b --- /dev/null +++ b/scene_flow_impair.cpp @@ -0,0 +1,460 @@ + +#include "scene_flow_impair.h" + +PD_flow_opencv::PD_flow_opencv(unsigned int rows_config) +{ + rows = rows_config; //Maximum size of the coarse-to-fine scheme + cols = rows*320/240; + cam_mode = 1; + ctf_levels = round(log2(rows/15)) + 1; + fovh = M_PI*62.5f/180.f; + fovv = M_PI*45.f/180.f; + len_disp = 0.022f; + num_max_iter[0] = 40; + num_max_iter[1] = 50; + num_max_iter[2] = 60; + num_max_iter[3] = 80; + num_max_iter[4] = 100; + num_max_iter[5] = 0; + + //Compute gaussian mask + int v_mask[5] = {1,4,6,4,1}; + for (unsigned int i=0; i<5; i++) + for (unsigned int j=0; j<5; j++) + g_mask[i+5*j] = float(v_mask[i]*v_mask[j])/256.f; + + //Matrices that store the original and filtered images with the image resolution + colour_wf.setSize(480/cam_mode,640/cam_mode); + depth_wf.setSize(480/cam_mode,640/cam_mode); + + //Resize vectors according to levels + dx.resize(ctf_levels); dy.resize(ctf_levels); dz.resize(ctf_levels); + dxp = (float *) malloc(sizeof(float)*rows*cols); + dyp = (float *) malloc(sizeof(float)*rows*cols); + dzp = (float *) malloc(sizeof(float)*rows*cols); + + const unsigned int width = colour_wf.getColCount(); + const unsigned int height = colour_wf.getRowCount(); + unsigned int s, cols_i, rows_i; + + for (unsigned int i = 0; i0) + UpsampleBridge(csf_device); + + //Compute connectivity (Rij) + RijBridge(csf_device); + + //Compute colour and depth derivatives + ImageGradientsBridge(csf_device); + WarpingBridge(csf_device); + + //Compute mu_uv and step sizes for the primal-dual algorithm + MuAndStepSizesBridge(csf_device); + + for (num_iter = 0; num_iter < num_max_iter[i]; num_iter++) + { + GradientBridge(csf_device); + DualVariablesBridge(csf_device); + DivergenceBridge(csf_device); + PrimalVariablesBridge(csf_device); + } + + //Filter solution + FilterBridge(csf_device); + + //Compute the motion field + MotionFieldBridge(csf_device); + + //BridgeBack + BridgeBack(&csf_host, csf_device); + + //Free variables of this level + csf_host.freeLevelVariables(); + + //Copy motion field to CPU + csf_host.copyMotionField(dxp, dyp, dzp); + + //For debugging + //DebugBridge(csf_device); + + //========================================================================= + // Cuda - end + //========================================================================= + } +} + +void PD_flow_opencv::freeGPUMemory() +{ + csf_host.freeDeviceMemory(); +} + +void PD_flow_opencv::initializeCUDA() +{ + //Read parameters + csf_host.readParameters(rows, cols, lambda_i, lambda_d, mu, g_mask, ctf_levels, len_disp, cam_mode, fovh, fovv, f_dist); + + //Allocate memory + csf_host.allocateDevMemory(); +} + +void PD_flow_opencv::initializeScene() +{ + global_settings::OCTREE_RENDER_MAX_POINTS_PER_NODE = 10000000; + window.resize(1000,900); + window.setPos(900,0); + window.setCameraZoom(4); + window.setCameraAzimuthDeg(190); + window.setCameraElevationDeg(30); + window.setCameraPointingToPoint(1,0,0); + + scene = window.get3DSceneAndLock(); + + //Point cloud (final) + opengl::CPointCloudPtr fpoints_gl = opengl::CPointCloud::Create(); + fpoints_gl->setColor(0, 1, 1); + fpoints_gl->enablePointSmooth(); + fpoints_gl->setPointSize(3.0); + fpoints_gl->setPose(CPose3D(0,0,0,0,0,0)); + scene->insert( fpoints_gl ); + + //Scene Flow + opengl::CVectorField3DPtr sf = opengl::CVectorField3D::Create(); + sf->setPointSize(3.0f); + sf->setLineWidth(2.0f); + sf->setPointColor(1,0,0); + sf->setVectorFieldColor(0,0,1); + sf->enableAntiAliasing(); + sf->setPose(CPose3D(0,0,0,0,0,0)); + scene->insert( sf ); + + //Reference frame + opengl::CSetOfObjectsPtr reference = opengl::stock_objects::CornerXYZ(); + reference->setPose(CPose3D(0,len_disp,0,0,0,0)); + reference->setScale(0.15f); + scene->insert( reference ); + + window.unlockAccess3DScene(); + window.repaint(); +} + +void PD_flow_opencv::updateScene() +{ + scene = window.get3DSceneAndLock(); + + const unsigned int repr_level = round(log2(colour_wf.getColCount()/cols)); + + //Point cloud (final) + opengl::CPointCloudPtr fpoints_gl = scene->getByClass(0); + fpoints_gl->clear(); + for (unsigned int v=0; v 0.1f) + fpoints_gl->insertPoint(depth[repr_level](v,u), xx[repr_level](v,u), yy[repr_level](v,u)); + + + opengl::CVectorField3DPtr sf = scene->getByClass(0); + sf->setPointCoordinates(depth_old[repr_level], xx_old[repr_level], yy_old[repr_level]); + sf->setVectorField(dx[0], dy[0], dz[0]); + + window.unlockAccess3DScene(); + window.repaint(); +} + +void PD_flow_opencv::showImages() +{ + //Show images + const unsigned int dispx = intensity1.cols + 20; + const unsigned int dispy = intensity1.rows + 20; + + cv::namedWindow("I1", cv::WINDOW_AUTOSIZE); + cv::moveWindow("I1",10,10); + cv::imshow("I1", intensity1); + + cv::namedWindow("Z1", cv::WINDOW_AUTOSIZE); + cv::moveWindow("Z1",dispx,10); + cv::imshow("Z1", depth1); + + cv::namedWindow("I2", cv::WINDOW_AUTOSIZE); + cv::moveWindow("I2",10,dispy); + cv::imshow("I2", intensity2); + + cv::namedWindow("Z2", cv::WINDOW_AUTOSIZE); + cv::moveWindow("Z2",dispx,dispy); + cv::imshow("Z2", depth2); + + cv::waitKey(30); + + initializeScene(); +} + +bool PD_flow_opencv::loadRGBDFrames() +{ + char name[100]; + cv::Mat depth_float; + + //First intensity image + sprintf(name, "i1.png"); + intensity1 = cv::imread(name, CV_LOAD_IMAGE_GRAYSCALE); + if (intensity1.empty()) + { + cout << endl << "The first intensity image (i1) cannot be found, please check that it is in the correct folder \n"; + return 0; + } + + width = intensity1.cols; + height = intensity1.rows; + I = (float *) malloc(sizeof(float)*width*height); + Z = (float *) malloc(sizeof(float)*width*height); + + for (unsigned int u=0; u(v,u); + I[v + u*height] = float(intensity1.at(v,u)); + } + + //First depth image + sprintf(name, "z1.png"); + depth1 = cv::imread(name, -1); + if (depth1.empty()) + { + cout << endl << "The first depth image (z1) cannot be found, please check that it is in the correct folder \n"; + return 0; + } + + depth1.convertTo(depth_float, CV_32FC1, 1.0 / 5000.0); + for (unsigned int v=0; v(v,u); + Z[v + u*height] = depth_float.at(v,u); + } + + createImagePyramidGPU(); + + + //Second intensity image + sprintf(name, "i2.png"); + intensity2 = cv::imread(name, CV_LOAD_IMAGE_GRAYSCALE); + if (intensity2.empty()) + { + cout << endl << "The second intensity image (i2) cannot be found, please check that it is in the correct folder \n"; + return 0; + } + + for (unsigned int v=0; v(v,u); + I[v + u*height] = float(intensity2.at(v,u)); + } + + //Second depth image + sprintf(name, "z2.png"); + depth2 = cv::imread(name, -1); + if (depth2.empty()) + { + cout << endl << "The second depth image (z2) cannot be found, please check that they are in the correct folder \n"; + return 0; + } + depth2.convertTo(depth_float, CV_32FC1, 1.0 / 5000.0); + for (unsigned int v=0; v(v,u); + Z[v + u*height] = depth_float.at(v,u); + } + + createImagePyramidGPU(); + + return 1; +} + +void PD_flow_opencv::showAndSaveResults() +{ + //Save scene flow as an RGB image (one colour per direction) + cv::Mat sf_image(rows, cols, CV_8UC3); + + //The max-min values are used by default but it can be set manually if the user wants to + const float mindx = dx[0].minimum(); + const float maxdx = dx[0].maximum(); + const float mindy = dy[0].minimum(); + const float maxdy = dy[0].maximum(); + const float mindz = dz[0].minimum(); + const float maxdz = dz[0].maximum(); + + //const float maxmodx = 0.8*max(abs(mindx), abs(maxdx)); + //const float maxmody = 0.8*max(abs(mindy), abs(maxdy)); + //const float maxmodz = 0.8*max(abs(mindz), abs(maxdz)); + + //Compute the max-min values of the flow + float maxmodx = 0.f, maxmody = 0.f, maxmodz = 0.f; + for (unsigned int v=0; v maxmodx) + maxmodx = abs(dxp[v + u*rows]); + if (abs(dyp[v + u*rows]) > maxmody) + maxmody = abs(dyp[v + u*rows]); + if (abs(dzp[v + u*rows]) > maxmodz) + maxmodz = abs(dzp[v + u*rows]); + } + + for (unsigned int v=0; v(v,u)[0] = 255*abs(dx[0](v,u))/maxmodx; //Blue + //sf_image.at(v,u)[1] = 255*abs(dy[0](v,u))/maxmody; //Green + //sf_image.at(v,u)[2] = 255*abs(dz[0](v,u))/maxmodz; //Red + + sf_image.at(v,u)[0] = 255*abs(dxp[v + u*rows])/maxmodx; //Blue + sf_image.at(v,u)[1] = 255*abs(dyp[v + u*rows])/maxmody; //Green + sf_image.at(v,u)[2] = 255*abs(dzp[v + u*rows])/maxmodz; //Red + } + + //Show the scene flow as an RGB image + cv::namedWindow("SceneFlow", cv::WINDOW_NORMAL); + cv::moveWindow("SceneFlow",10,10); + cv::imshow("SceneFlow", sf_image); + cv::waitKey(100000); + + + //Save the scene flow as a text file, as well as the RGB generated image. + //char name[100]; + //int nFichero = 0; + //bool free_name = false; + + //while (!free_name) + //{ + // nFichero++; + // sprintf(name, "pdflow_results%02u.txt", nFichero ); + // free_name = !system::fileExists(name); + //} + // + //std::ofstream f_res; + //f_res.open(name); + //printf("Saving the estimated scene flow to file: %s \n", name); + + ////Format: (pixel(row), pixel(col), vx, vy, vz) + //for (unsigned int v=0; v +#include +#include +#include +#include +#include +#include +#include "pdflow_cudalib.h" +#include "legend_pdflow.xpm" +#include +#include + +#define M_LOG2E 1.44269504088896340736 //log2(e) + +inline float log2(const float x){ + return log(x) * M_LOG2E; +} + + +using namespace mrpt; +using namespace mrpt::math; +using namespace mrpt::utils; +using namespace std; +using mrpt::poses::CPose3D; +using Eigen::MatrixXf; + + +class PD_flow_opencv { +public: + + float len_disp; //In meters + unsigned int cam_mode; // (1 - 640 x 480, 2 - 320 x 240, 4 - 160 x 120) + unsigned int ctf_levels;//Number of levels used in the coarse-to-fine scheme (always dividing by two) + unsigned int num_max_iter[6]; //Max number of iterations distributed homogeneously between all levels + float g_mask[25]; + + //Matrices that store the original images with the image resolution + cv::Mat intensity1; + cv::Mat depth1; + cv::Mat intensity2; + cv::Mat depth2; + float *I, *Z; + MatrixXf colour_wf; + MatrixXf depth_wf; + + //Matrices that store the images downsampled + vector colour; + vector colour_old; + vector depth; + vector depth_old; + vector xx; + vector xx_old; + vector yy; + vector yy_old; + + //Motion field + vector dx; + vector dy; + vector dz; + float *dxp, *dyp, *dzp; + + //Camera properties + float f_dist; //In meters + float fovh; //Here it is expressed in radians + float fovv; //Here it is expressed in radians + + //Max resolution of the coarse-to-fine scheme. + unsigned int rows; + unsigned int cols; + + //Resolution of the original images + unsigned int width; + unsigned int height; + + //Optimization Parameters + float mu, lambda_i, lambda_d; + + //Visual + gui::CDisplayWindow3D window; + opengl::COpenGLScenePtr scene; + utils::CImage image; + + //Cuda + CSF_cuda csf_host, *csf_device; + + //Methods + bool loadRGBDFrames(); + void createImagePyramidGPU(); + void solveSceneFlowGPU(); + void freeGPUMemory(); + void initializeCUDA(); + void initializeScene(); + void updateScene(); + void showImages(); + void showAndSaveResults(); + + PD_flow_opencv(unsigned int rows_config); +}; + + + diff --git a/scene_flow_visualization.cpp b/scene_flow_visualization.cpp new file mode 100644 index 0000000..9a59188 --- /dev/null +++ b/scene_flow_visualization.cpp @@ -0,0 +1,415 @@ + +#include "scene_flow_visualization.h" + +PD_flow_mrpt::PD_flow_mrpt(unsigned int cam_mode_config, unsigned int fps_config, unsigned int rows_config) +{ + rows = rows_config; //Maximum size of the coarse-to-fine scheme + cols = rows*320/240; + cam_mode = cam_mode_config; // (1 - 640 x 480, 2 - 320 x 240) + ctf_levels = round(log2(rows/15)) + 1; + fovh = M_PI*62.5f/180.f; + fovv = M_PI*45.f/180.f; + len_disp = 0.022f; + num_max_iter[0] = 40; + num_max_iter[1] = 50; + num_max_iter[2] = 60; + num_max_iter[3] = 80; + num_max_iter[4] = 0; + num_max_iter[5] = 0; + + fps = fps_config; //In Hz + + //Compute gaussian mask + int v_mask[5] = {1,4,6,4,1}; + g_mask.setSize(5,5); + for (unsigned int i=0; i<5; i++) + for (unsigned int j=0; j<5; j++) + g_mask(i,j) = v_mask[i]*v_mask[j]; + + g_mask = g_mask/256.f; + + //Matrices that store the original and filtered images with the image resolution + colour_wf.setSize(480/cam_mode,640/cam_mode); + depth_wf.setSize(480/cam_mode,640/cam_mode); + + //Resize vectors according to levels + dx.resize(ctf_levels); dy.resize(ctf_levels); dz.resize(ctf_levels); + + const unsigned int width = colour_wf.getColCount(); + const unsigned int height = colour_wf.getRowCount(); + unsigned int s, cols_i, rows_i; + + for (unsigned int i = 0; i0) + UpsampleBridge(csf_device); + + //Compute connectivity (Rij) + RijBridge(csf_device); + + //Compute colour and depth derivatives + ImageGradientsBridge(csf_device); + WarpingBridge(csf_device); + + //Compute mu_uv and step sizes for the primal-dual algorithm + MuAndStepSizesBridge(csf_device); + + for (num_iter = 0; num_iter < num_max_iter[i]; num_iter++) + { + GradientBridge(csf_device); + DualVariablesBridge(csf_device); + DivergenceBridge(csf_device); + PrimalVariablesBridge(csf_device); + } + + //Filter solution + FilterBridge(csf_device); + + //Compute the motion field + MotionFieldBridge(csf_device); + + //BridgeBack + BridgeBack(&csf_host, csf_device); + + //Free variables of this level + csf_host.freeLevelVariables(); + + //Copy motion field to CPU + csf_host.copyAllSolutions(dx[ctf_levels-i-1].data(), dy[ctf_levels-i-1].data(), dz[ctf_levels-i-1].data(), + depth[level_image].data(), depth_old[level_image].data(), colour[level_image].data(), colour_old[level_image].data(), + xx[level_image].data(), xx_old[level_image].data(), yy[level_image].data(), yy_old[level_image].data()); + + //For debugging + //DebugBridge(csf_device); + + //========================================================================= + // Cuda - end + //========================================================================= + } +} + +bool PD_flow_mrpt::OpenCamera() +{ + rc = openni::STATUS_OK; + + const char* deviceURI = openni::ANY_DEVICE; + + rc = openni::OpenNI::initialize(); + + printf("After initialization:\n %s\n", openni::OpenNI::getExtendedError()); + rc = device.open(deviceURI); + if (rc != openni::STATUS_OK) + { + printf("Device open failed:\n%s\n", openni::OpenNI::getExtendedError()); + openni::OpenNI::shutdown(); + return 1; + } + + // Create RGB and Depth channels + //======================================================================================== + + rc = dimage.create(device, openni::SENSOR_DEPTH); + rc = rgb.create(device, openni::SENSOR_COLOR); + + // Configure some properties (resolution) + //======================================================================================== + rc = device.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR); + + options = rgb.getVideoMode(); //In rgb the resolution can't be set to (160,120) + if (cam_mode == 1) + options.setResolution(640,480); + else + options.setResolution(320,240); + rc = rgb.setVideoMode(options); + rc = rgb.setMirroringEnabled(false); + + options = dimage.getVideoMode(); + if (cam_mode == 1) + options.setResolution(640,480); + else + options.setResolution(320,240); + rc = dimage.setVideoMode(options); + rc = dimage.setMirroringEnabled(false); + + //Turn off autoExposure + rgb.getCameraSettings()->setAutoExposureEnabled(false); + printf("Auto Exposure: %s \n", rgb.getCameraSettings()->getAutoExposureEnabled() ? "ON" : "OFF"); + + //Check final resolution + options = rgb.getVideoMode(); + printf("Resolution (%d, %d) \n", options.getResolutionX(), options.getResolutionY()); + + // Start channels + //=================================================================================== + rc = dimage.start(); + if (rc != openni::STATUS_OK) + { + printf("SimpleViewer: Couldn't start depth stream:\n%s\n", openni::OpenNI::getExtendedError()); + dimage.destroy(); + } + + rc = rgb.start(); + if (rc != openni::STATUS_OK) + { + printf("Couldn't start rgb stream:\n%s\n", openni::OpenNI::getExtendedError()); + rgb.destroy(); + } + + if (!dimage.isValid() || !rgb.isValid()) + { + printf("Camera: No valid streams. Exiting\n"); + openni::OpenNI::shutdown(); + return 1; + } + + return 0; +} + +void PD_flow_mrpt::CloseCamera() +{ + rgb.destroy(); + openni::OpenNI::shutdown(); +} + +void PD_flow_mrpt::CaptureFrame() +{ + openni::VideoFrameRef framergb, framed; + rgb.readFrame(&framergb); + dimage.readFrame(&framed); + + const int height = framergb.getHeight(); + const int width = framergb.getWidth(); + + if ((framed.getWidth() != framergb.getWidth()) || (framed.getHeight() != framergb.getHeight())) + cout << endl << "Both frames don't have the same size."; + + else + { + //Read one frame + const openni::DepthPixel* pDepthRow = (const openni::DepthPixel*)framed.getData(); + const openni::RGB888Pixel* pRgbRow = (const openni::RGB888Pixel*)framergb.getData(); + int rowSize = framergb.getStrideInBytes() / sizeof(openni::RGB888Pixel); + + for (int yc = height-1; yc >= 0; --yc) + { + const openni::RGB888Pixel* pRgb = pRgbRow; + const openni::DepthPixel* pDepth = pDepthRow; + for (int xc = width-1; xc >= 0; --xc, ++pRgb, ++pDepth) + { + colour_wf(yc,xc) = 0.299*pRgb->r + 0.587*pRgb->g + 0.114*pRgb->b; + depth_wf(yc,xc) = 0.001f*(*pDepth); + } + pRgbRow += rowSize; + pDepthRow += rowSize; + } + } +} + +void PD_flow_mrpt::freeGPUMemory() +{ + csf_host.freeDeviceMemory(); +} + +void PD_flow_mrpt::initializeCUDA() +{ + //Read parameters + csf_host.readParameters(rows, cols, lambda_i, lambda_d, mu, g_mask.data(), ctf_levels, len_disp, cam_mode, fovh, fovv, f_dist); + + //Allocate memory + csf_host.allocateDevMemory(); +} + +void PD_flow_mrpt::initializeScene() +{ + global_settings::OCTREE_RENDER_MAX_POINTS_PER_NODE = 10000000; + window.resize(1000,900); + window.setPos(900,0); + window.setCameraZoom(4); + window.setCameraAzimuthDeg(190); + window.setCameraElevationDeg(30); + window.setCameraPointingToPoint(1,0,0); + + scene = window.get3DSceneAndLock(); + + //Point cloud (final) + opengl::CPointCloudPtr fpoints_gl = opengl::CPointCloud::Create(); + fpoints_gl->setColor(0, 1, 1); + fpoints_gl->enablePointSmooth(); + fpoints_gl->setPointSize(3.0); + fpoints_gl->setPose(CPose3D(0,0,0,0,0,0)); + scene->insert( fpoints_gl ); + + //Scene Flow + opengl::CVectorField3DPtr sf = opengl::CVectorField3D::Create(); + sf->setPointSize(3.0f); + sf->setLineWidth(2.0f); + sf->setPointColor(1,0,0); + sf->setVectorFieldColor(0,0,1); + sf->enableAntiAliasing(); + sf->setPose(CPose3D(0,0,0,0,0,0)); + scene->insert( sf ); + + //Reference frame + opengl::CSetOfObjectsPtr reference = opengl::stock_objects::CornerXYZ(); + reference->setPose(CPose3D(0,len_disp,0,0,0,0)); + reference->setScale(0.15f); + scene->insert( reference ); + + //Legend + utils::CImage img_legend; + img_legend.loadFromXPM(legend_pdflow_xpm); + opengl::COpenGLViewportPtr legend = scene->createViewport("legend"); + legend->setViewportPosition(20, 20, 201, 252); + legend->setImageView(img_legend); + + window.unlockAccess3DScene(); + window.repaint(); +} + +void PD_flow_mrpt::updateScene() +{ + scene = window.get3DSceneAndLock(); + + const unsigned int repr_level = round(log2(colour_wf.getColCount()/cols)); + + //Point cloud (final) + opengl::CPointCloudPtr fpoints_gl = scene->getByClass(0); + fpoints_gl->clear(); + for (unsigned int v=0; v 0.1f) + fpoints_gl->insertPoint(depth[repr_level](v,u), xx[repr_level](v,u), yy[repr_level](v,u)); + + + opengl::CVectorField3DPtr sf = scene->getByClass(0); + sf->setPointCoordinates(depth_old[repr_level], xx_old[repr_level], yy_old[repr_level]); + sf->setVectorField(dx[0], dy[0], dz[0]); + + window.unlockAccess3DScene(); + window.repaint(); +} + +void PD_flow_mrpt::initializePDFlow() +{ + //Initialize Visualization + initializeScene(); + + //Initialize CUDA + mrpt::system::sleep(1000); + initializeCUDA(); + + //Start video streaming + OpenCamera(); + + //Fill empty matrices + CaptureFrame(); + createImagePyramidGPU(); + CaptureFrame(); + createImagePyramidGPU(); + solveSceneFlowGPU(); +} \ No newline at end of file diff --git a/scene_flow_visualization.h b/scene_flow_visualization.h new file mode 100644 index 0000000..94548a9 --- /dev/null +++ b/scene_flow_visualization.h @@ -0,0 +1,98 @@ + +#include +#include +#include +#include +#include // +#include +#include "pdflow_cudalib.h" +#include "legend_pdflow.xpm" + +#define M_LOG2E 1.44269504088896340736 //log2(e) + +inline float log2(const float x){ + return log(x) * M_LOG2E; +} + + +using namespace mrpt; +using namespace mrpt::math; +using namespace mrpt::utils; +using namespace std; +using mrpt::poses::CPose3D; +using Eigen::MatrixXf; + + +class PD_flow_mrpt { +public: + + float len_disp; //In meters + float fps; //In Hz + unsigned int cam_mode; // (1 - 640 x 480, 2 - 320 x 240, 4 - 160 x 120) + unsigned int ctf_levels;//Number of levels used in the coarse-to-fine scheme (always dividing by two) + unsigned int num_max_iter[6]; //Max number of iterations distributed homogeneously between all levels + MatrixXf g_mask; + + //Matrices that store the original images with the image resolution + MatrixXf colour_wf; + MatrixXf depth_wf; + + //Matrices that store the images downsampled + vector colour; + vector colour_old; + vector depth; + vector depth_old; + vector xx; + vector xx_old; + vector yy; + vector yy_old; + + //Motion field + vector dx; + vector dy; + vector dz; + + //Camera properties + float f_dist; //In meters + float fovh; //Here it is expressed in radians + float fovv; //Here it is expressed in radians + + //Max resolution of the coarse-to-fine scheme. + unsigned int rows; + unsigned int cols; + + //Optimization Parameters + float mu, lambda_i, lambda_d; + + //Visual + gui::CDisplayWindow3D window; + opengl::COpenGLScenePtr scene; + utils::CImage image; + + //Camera + openni::Status rc; + openni::Device device; + openni::VideoMode options; + openni::VideoStream rgb,dimage; + + //Cuda + CSF_cuda csf_host, *csf_device; + + + //Methods + void createImagePyramidGPU(); + void solveSceneFlowGPU(); + bool OpenCamera(); + void CloseCamera(); + void CaptureFrame(); + void freeGPUMemory(); + void initializeCUDA(); + void initializeScene(); + void updateScene(); + void initializePDFlow(); + + PD_flow_mrpt(unsigned int cam_mode_config, unsigned int fps_config, unsigned int rows_config); +}; + + +