diff --git a/CMakeLists.txt b/CMakeLists.txt index 1905c17..5dfbe54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ find_package(Qt6 REQUIRED COMPONENTS ) # 查找PCL -find_package(PCL REQUIRED COMPONENTS common io visualization) +find_package(PCL REQUIRED COMPONENTS common io visualization filters) if(PCL_FOUND) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) @@ -101,6 +101,52 @@ add_executable(${PROJECT_NAME} WIN32 ${RESOURCES} ) +# ==================== 标定文件(cmos0)检查 ==================== +set(VIEWER_CALIBRATION_DIR "${CMAKE_SOURCE_DIR}/cmos0") +set(VIEWER_REQUIRED_CALIB_FILES + "coe.txt" + "kc.txt" + "KK.txt" +) + +set(VIEWER_MISSING_CALIB_FILES "") +foreach(_calib_file IN LISTS VIEWER_REQUIRED_CALIB_FILES) + if(NOT EXISTS "${VIEWER_CALIBRATION_DIR}/${_calib_file}") + list(APPEND VIEWER_MISSING_CALIB_FILES "${_calib_file}") + endif() +endforeach() + +option(VIEWER_REQUIRE_CALIB_FILES "Fail configure when required cmos0 calibration files are missing" ON) + +if(VIEWER_MISSING_CALIB_FILES) + if(VIEWER_REQUIRE_CALIB_FILES) + message(FATAL_ERROR + "Missing calibration file(s) in ${VIEWER_CALIBRATION_DIR}: ${VIEWER_MISSING_CALIB_FILES}\n" + "Please ensure cmos0 contains: ${VIEWER_REQUIRED_CALIB_FILES}" + ) + else() + message(WARNING + "Missing calibration file(s) in ${VIEWER_CALIBRATION_DIR}: ${VIEWER_MISSING_CALIB_FILES}\n" + "Build continues, but runtime or MSI may be incomplete." + ) + endif() +else() + message(STATUS "Calibration files found: ${VIEWER_REQUIRED_CALIB_FILES}") +endif() + +# 复制标定文件到运行目录(bin/cmos0) +if(EXISTS "${VIEWER_CALIBRATION_DIR}" AND NOT VIEWER_MISSING_CALIB_FILES) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "$/cmos0" + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${VIEWER_CALIBRATION_DIR}" + "$/cmos0" + COMMENT "Copy cmos0 calibration files to runtime directory" + ) +else() + message(WARNING "Skip copying cmos0 because required calibration files are missing.") +endif() + # 链接库 target_link_libraries(${PROJECT_NAME} Qt6::Core @@ -141,6 +187,15 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/platforms/ FILES_MATCHING PATTERN "*.dll" ) +# 安装标定文件目录(用于MSI) +if(EXISTS "${VIEWER_CALIBRATION_DIR}" AND NOT VIEWER_MISSING_CALIB_FILES) + install(DIRECTORY ${VIEWER_CALIBRATION_DIR}/ + DESTINATION cmos0 + FILES_MATCHING + PATTERN "*.txt" + ) +endif() + # ==================== CPack配置 - MSI安装程序 ==================== set(CPACK_PACKAGE_NAME "Viewer") set(CPACK_PACKAGE_VENDOR "Lorenzo Zhao") diff --git a/README.md b/README.md index 24e1076..53bef39 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,51 @@ C:\Program Files\D330Viewer\ - 性能监控(CPU/GPU使用率、内存使用) - 其他相机参数调节(增益、白平衡等) +## 点云去噪原理与参数说明 + +### 去噪处理流程(当前版本) + +当前点云去噪不是单一滤波器,而是多阶段组合策略,目标是在保留主体结构的同时抑制放射状无效点和外围杂点。 + +1. 有效点预筛:去掉非有限值和 `z<=0` 的点,得到基础有效掩码。 +2. 中心ROI深度门控:基于中心区域中位深度自适应裁剪深度窗口,先去掉明显离群深度。 +3. 邻域一致性筛选:统计每个点在局部窗口内“深度相近邻居”的数量,邻域支持不足的点剔除。 +4. 形态学轻清理:移除局部孤立残点,减少毛刺。 +5. 近距离尾部裁剪:对低深度尾部进行比例裁剪,抑制中心放射状噪点。 +6. 连通簇筛选:按面积、深度一致性和中心重叠等条件保留主簇及相关簇,抑制周边散簇。 +7. 最终细枝清理:对近距离且邻居不足的细枝点做额外抑制。 +8. 时序稳定:对关键阈值做帧间平滑和限跳,减少块状点云“时有时无”的闪烁。 + +### 三个参数的作用与范围 + +参数都在“曝光与拍照 -> 拍照参数 -> 点云去噪参数”中,实时生效。 + +1. 邻域支持阈值 +- 范围:`3 ~ 12` +- 含义:一个点要保留,局部邻域内至少需要多少个深度相近邻居。 +- 调大:噪点更少,但边缘和细小结构更容易被吃掉。 +- 调小:细节更多,但散点噪声会增加。 + +2. 射线裁剪强度 (‰) +- 范围:`5 ~ 50` +- 含义:近距离低深度尾部的裁剪比例(千分比)。 +- 调大:中心放射状噪点减少更明显,但近距离真实细节可能减少。 +- 调小:近距离细节保留更多,但放射状点可能增多。 + +3. 周边抑制带宽 (‰) +- 范围:`40 ~ 180` +- 含义:控制连通簇保留深度带宽、回补范围和近距离毛刺门限。 +- 调小:抑制更激进,周边杂点更少,但主体可能偏“硬”、易丢块。 +- 调大:主体与细节更完整,但外围杂点回升概率更高。 + +### 推荐起始参数 + +用于室内桌椅等常见场景,可先从以下值起步,再按效果微调: + +- 邻域支持阈值:`8 ~ 10` +- 射线裁剪强度:`12 ~ 18` +- 周边抑制带宽:`90 ~ 130` + ## 项目结构 ``` diff --git a/cmos0/KK.txt b/cmos0/KK.txt new file mode 100644 index 0000000..6634f15 --- /dev/null +++ b/cmos0/KK.txt @@ -0,0 +1,3 @@ + 1.4328957e+03 0.0000000e+00 6.3751170e+02 + 0.0000000e+00 1.4326590e+03 5.2187200e+02 + 0.0000000e+00 0.0000000e+00 1.0000000e+00 diff --git a/cmos0/coe.txt b/cmos0/coe.txt new file mode 100644 index 0000000..6ee3a5a --- /dev/null +++ b/cmos0/coe.txt @@ -0,0 +1,1224 @@ +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.160994809 140.383029141 -0.377661373 -0.634334779 -0.000454812 -0.673279513 -0.000000071 -0.000008439 0.003155883 0.731182568 +0.144298959 140.237681142 -0.363384600 -0.631800004 -0.000127652 -0.659816478 -0.000000542 -0.000007002 0.002368805 0.713998905 +0.184455503 140.074455555 -0.328342976 -0.629241730 0.000449732 -0.656613970 -0.000001434 -0.000012132 0.005606978 0.718407365 +0.208625280 140.076966547 -0.347506971 -0.626945283 0.000443229 -0.668060270 -0.000001336 -0.000010956 0.004989093 0.737121149 +0.207847819 140.063234920 -0.311966831 -0.624629718 0.000557981 -0.644479507 -0.000001476 -0.000009000 0.003680894 0.786634105 +0.204122152 140.015758449 -0.308207929 -0.622255190 0.000221855 -0.658973257 -0.000000894 -0.000008656 0.003562649 0.850700461 +0.222646379 139.890456617 -0.250364887 -0.619786812 0.000663819 -0.632992123 -0.000001614 -0.000009765 0.004292523 0.892658606 +0.241154928 139.925497446 -0.239883454 -0.617559557 0.000095329 -0.637210591 -0.000000712 -0.000006398 0.002190585 0.857247002 +0.273443280 139.865771446 -0.226821730 -0.615203199 0.000114621 -0.667147771 -0.000000691 -0.000007617 0.003237685 0.884828942 +0.275504689 139.812026061 -0.194567906 -0.612827292 0.000392002 -0.658611512 -0.000001101 -0.000007275 0.002842212 0.933772604 +0.324350945 139.821726721 -0.184469274 -0.610575380 0.000416803 -0.660813827 -0.000001132 -0.000006751 0.002673407 0.931781894 +0.300746532 139.932446136 -0.186318358 -0.608490413 -0.000130620 -0.637193980 -0.000000218 -0.000002781 0.000213080 0.998199167 +0.316001391 139.831524166 -0.205563894 -0.606071670 0.000415261 -0.657765166 -0.000001077 -0.000001362 -0.000643675 1.008689888 +0.369424003 139.785992030 -0.183987576 -0.603740335 0.000319948 -0.633871250 -0.000000876 -0.000001497 -0.000604361 1.078523798 +0.362362284 139.791439396 -0.139682781 -0.601496985 0.000027835 -0.604865610 -0.000000414 0.000002050 -0.002649893 1.053469427 +0.392252248 139.644761678 -0.094201157 -0.599015665 0.000403329 -0.616588942 -0.000001010 -0.000002582 0.000203035 1.134081720 +0.366925147 139.592547250 -0.085195920 -0.596701594 0.000092678 -0.603854964 -0.000000478 -0.000003434 0.000899197 1.102783552 +0.405115655 139.527855455 -0.062765850 -0.594361104 -0.000021789 -0.619289472 -0.000000295 -0.000002867 0.000498687 1.116725006 +0.396183296 139.506103020 -0.043905794 -0.592107849 0.000540512 -0.626416889 -0.000001165 -0.000002943 0.000609673 1.245995016 +0.451722708 139.388559595 -0.067664907 -0.589662607 -0.000014495 -0.628349034 -0.000000303 -0.000005659 0.002329587 1.227279949 +0.470710109 139.328278823 -0.054806621 -0.587366718 0.000420065 -0.586139049 -0.000000976 -0.000007124 0.003553146 1.236005159 +0.501363371 139.085371542 -0.007683473 -0.584737178 0.000833107 -0.593086926 -0.000001609 -0.000011866 0.006478119 1.223905913 +0.500404794 139.137708779 -0.029451886 -0.582612777 0.000641144 -0.580082325 -0.000001262 -0.000008733 0.004579826 1.305493052 +0.518706995 139.038492940 0.036643480 -0.580245023 0.000440833 -0.590736668 -0.000000976 -0.000009213 0.005006239 1.276610071 +0.545914907 139.082407284 0.051015525 -0.578090579 0.000545452 -0.611697269 -0.000001094 -0.000009170 0.004818405 1.318502807 +0.536493448 139.149063704 0.029681966 -0.575989171 0.000018667 -0.603207902 -0.000000272 -0.000005396 0.002618972 1.332631765 +0.552165245 139.014324303 0.044594159 -0.573588057 0.000093169 -0.611489609 -0.000000340 -0.000005865 0.002884083 1.382630000 +0.591640279 138.952754076 0.084078775 -0.571287834 0.000140194 -0.608896689 -0.000000414 -0.000009047 0.005003360 1.411205263 +0.609184482 139.052186029 0.101973591 -0.569250674 0.000069443 -0.593822058 -0.000000283 -0.000002816 0.001030434 1.510294586 +0.583195740 139.112977171 0.123856233 -0.567176190 -0.000251943 -0.595976519 0.000000242 -0.000000033 -0.000638673 1.531539582 +0.588511547 139.246999783 0.126378032 -0.565195354 -0.000815973 -0.567344972 0.000001142 0.000003881 -0.003215138 1.545555561 +0.606887664 139.182690417 0.109578334 -0.562886958 -0.000712637 -0.552779104 0.000001008 0.000003892 -0.003293069 1.482408792 +0.628929039 139.211083032 0.156700611 -0.560758564 -0.000505878 -0.577000634 0.000000703 0.000003469 -0.002985342 1.551874661 +0.647127916 139.154367219 0.138572664 -0.558508208 -0.000638164 -0.586292074 0.000000931 0.000006920 -0.004871131 1.575290545 +0.693722985 138.982104959 0.202508781 -0.556059858 -0.000705343 -0.548349888 0.000001096 0.000001326 -0.001373879 1.603616330 +0.670267681 138.877981144 0.212276502 -0.553737951 -0.000034474 -0.561278379 0.000000046 -0.000000551 -0.000201183 1.700044268 +0.716088818 138.995895461 0.224563955 -0.551744632 -0.000548357 -0.547032940 0.000000853 0.000003223 -0.002728692 1.634336895 +0.746129518 138.829999328 0.216032983 -0.549320338 -0.000247165 -0.543946074 0.000000385 -0.000000055 -0.000775828 1.644472049 +0.724852598 138.655621609 0.264780957 -0.546902427 -0.000212235 -0.553728206 0.000000349 -0.000005658 0.003022492 1.757203638 +0.749237595 138.396127284 0.281800161 -0.544356927 0.000056962 -0.538532874 0.000000003 -0.000011911 0.007141273 1.689101572 +0.769072040 138.324573009 0.272747865 -0.542093129 0.000269670 -0.536528644 -0.000000363 -0.000012224 0.007210370 1.829794539 +0.777617086 138.350514323 0.268283388 -0.539972967 -0.000129205 -0.538642700 0.000000257 -0.000008208 0.004839902 1.836305533 +0.803980408 138.331712610 0.338641057 -0.537795569 0.000083596 -0.552035928 -0.000000058 -0.000007809 0.004425376 1.882474487 +0.852107340 138.270251075 0.350053341 -0.535581431 0.000112176 -0.532704700 -0.000000073 -0.000008953 0.005303663 1.884418584 +0.834975580 138.275141345 0.348976442 -0.533434877 0.000155672 -0.517583487 -0.000000162 -0.000006551 0.003809832 1.891029009 +0.883008382 138.237073364 0.378430885 -0.531265916 0.000228716 -0.530708654 -0.000000245 -0.000007749 0.004536046 1.964930199 +0.884451389 138.160398325 0.400344927 -0.529005041 0.000275749 -0.511526029 -0.000000313 -0.000008379 0.004883170 1.937919512 +0.900879448 138.207596298 0.385944601 -0.526953647 0.000142230 -0.510776613 -0.000000050 -0.000004989 0.002864159 1.955886007 +0.928909819 138.365764918 0.441111676 -0.525076290 0.000752406 -0.494013699 -0.000000969 -0.000001274 0.000382142 1.951830161 +0.948074988 138.356767300 0.434946998 -0.522949553 0.000582601 -0.523104677 -0.000000715 0.000000929 -0.000924777 1.970995151 +0.972856474 138.493061006 0.431993952 -0.521053097 0.000086807 -0.518084957 0.000000066 0.000004037 -0.002963893 2.034391816 +0.938311144 138.419958724 0.446890991 -0.518842894 -0.000165579 -0.512548321 0.000000482 0.000003999 -0.002836310 2.087960535 +0.998338454 138.367999436 0.504745212 -0.516643282 0.000451003 -0.527291205 -0.000000475 0.000004625 -0.003099715 2.148852336 +0.974327558 138.407725862 0.486106746 -0.514612623 0.000016850 -0.493622680 0.000000240 0.000008626 -0.005806196 2.093527457 +0.979931626 138.257257888 0.488001026 -0.512261106 0.000075068 -0.493737447 0.000000133 0.000002730 -0.002101214 2.105520653 +1.002792479 138.372275899 0.557388505 -0.510339039 0.000286601 -0.500424429 -0.000000179 0.000010079 -0.006965513 2.147460047 +1.019515712 138.324012899 0.553989021 -0.508178451 0.000131092 -0.494327065 0.000000034 0.000008784 -0.005908208 2.142050783 +1.035454064 138.050461455 0.592380971 -0.505624238 0.000200534 -0.488989986 -0.000000036 0.000003200 -0.002536101 2.235850133 +1.105550653 137.790346629 0.556122246 -0.503133736 -0.000440397 -0.493078061 0.000000966 -0.000003425 0.001717020 2.230473526 +1.077715337 137.668264431 0.614749506 -0.500858695 0.000481098 -0.494216915 -0.000000486 -0.000005669 0.003169000 2.320420367 +1.138645284 137.611603518 0.608720139 -0.498699400 0.000892254 -0.496403156 -0.000001130 -0.000004481 0.002274933 2.289115931 +1.134643367 137.542982372 0.631485236 -0.496492724 0.000953028 -0.492201695 -0.000001217 -0.000005992 0.003267526 2.373446751 +1.166568721 137.522752064 0.611392705 -0.494405756 0.000699274 -0.448273828 -0.000000796 -0.000006325 0.003684943 2.316428696 +1.149171549 137.448602732 0.662330543 -0.492204695 0.000249065 -0.467678351 -0.000000037 -0.000006166 0.003537207 2.414316195 +1.156746794 137.536005904 0.683236287 -0.490303405 0.000486044 -0.451589319 -0.000000408 -0.000003637 0.001984317 2.448285156 +1.169787883 137.474908459 0.690506651 -0.488151175 0.000418755 -0.470153242 -0.000000267 -0.000003638 0.002097057 2.420687032 +1.209976618 137.511279577 0.677574909 -0.486167401 0.000552937 -0.482014736 -0.000000450 -0.000003081 0.001884353 2.467207460 +1.206907764 137.687306309 0.724244212 -0.484385204 0.000819824 -0.448318916 -0.000000796 0.000000294 -0.000138435 2.431362436 +1.226588241 137.813434052 0.709746329 -0.482557013 0.001525685 -0.457921333 -0.000001868 0.000002754 -0.001611085 2.477522862 +1.223536575 137.970734191 0.778742128 -0.480739094 0.001355953 -0.440058546 -0.000001604 0.000009102 -0.005748535 2.546721426 +1.277965873 138.090264883 0.778444852 -0.478870783 0.000985384 -0.426901139 -0.000000961 0.000015544 -0.009830140 2.563872421 +1.319270554 138.035919984 0.801167922 -0.476721607 0.000894477 -0.460832339 -0.000000804 0.000014079 -0.008904324 2.639356754 +1.328056512 137.973564447 0.814548451 -0.474585746 0.001194916 -0.433184908 -0.000001273 0.000009388 -0.006105793 2.634311593 +1.288229353 137.811289970 0.829262656 -0.472277117 0.001192458 -0.430180891 -0.000001326 0.000004844 -0.003398266 2.640156569 +1.346268369 137.880544230 0.867590555 -0.470324120 0.001336357 -0.429909812 -0.000001556 0.000005523 -0.004017376 2.683350331 +1.344252742 137.822669991 0.832096266 -0.468171681 -0.000048722 -0.429970009 0.000000554 0.000014725 -0.010059835 2.641095061 +1.344203974 137.907088531 0.868260346 -0.466286791 -0.000353795 -0.401064900 0.000001035 0.000018830 -0.012770983 2.661700899 +1.388954528 137.771340678 0.909060241 -0.464019035 -0.000768225 -0.436984652 0.000001722 0.000018075 -0.012131269 2.776845472 +1.396961426 137.515194005 0.902330897 -0.461587494 -0.001698887 -0.414830394 0.000003178 0.000015826 -0.010807725 2.749669590 +1.419973233 137.206212263 0.936326982 -0.459078800 -0.001586059 -0.408176276 0.000002967 0.000005722 -0.004344720 2.743811331 +1.460874858 137.019798928 0.913791817 -0.456826940 -0.001136911 -0.434693500 0.000002319 0.000002715 -0.001964466 2.877207113 +1.428059727 137.106603058 0.964208137 -0.454977209 -0.000956959 -0.400786347 0.000002095 0.000005766 -0.003654053 2.794895069 +1.463378435 137.239778590 0.995361657 -0.453160087 -0.001147825 -0.387691943 0.000002407 0.000010173 -0.006277569 2.822892823 +1.454635921 137.164656320 0.961543828 -0.451028682 -0.001482815 -0.406543199 0.000002962 0.000010681 -0.006619943 2.912391799 +1.492402004 137.209487052 0.995539741 -0.449120741 -0.001479471 -0.401132890 0.000002960 0.000011465 -0.007086976 2.921899822 +1.531457965 137.171994617 0.986090124 -0.447043893 -0.001332479 -0.415455861 0.000002723 0.000011374 -0.006837616 2.896721093 +1.505941282 137.159793905 1.014649750 -0.445027482 -0.001462386 -0.387331126 0.000002918 0.000012249 -0.007361421 2.925812413 +1.560379360 137.181402680 1.060310024 -0.443072345 -0.001034942 -0.369515901 0.000002228 0.000009987 -0.005833376 2.975719107 +1.551960037 137.265269000 1.090289659 -0.441183971 -0.000429370 -0.399454646 0.000001325 0.000009754 -0.005962936 2.988112663 +1.588404184 137.346625437 1.071481890 -0.439241405 -0.000662865 -0.401769498 0.000001669 0.000013984 -0.009316681 3.077291102 +1.574923466 137.451566280 1.066616771 -0.437390243 -0.000580890 -0.393802390 0.000001495 0.000015435 -0.010227189 3.084351771 +1.610191807 137.471076767 1.141452178 -0.435442152 -0.001238357 -0.366508171 0.000002504 0.000018847 -0.012438322 3.064849649 +1.598245487 137.405609567 1.128804150 -0.433356168 -0.001176355 -0.359978955 0.000002427 0.000017900 -0.011879779 3.131828963 +1.628968196 137.352278965 1.174397601 -0.431281186 -0.001185886 -0.361749478 0.000002476 0.000016267 -0.010889438 3.216434813 +1.647578644 137.315434983 1.151865318 -0.429235989 -0.000952833 -0.366589692 0.000002119 0.000015154 -0.010208617 3.200729252 +1.680392349 137.481655575 1.192373570 -0.427513760 -0.001065176 -0.370981883 0.000002300 0.000023078 -0.015061482 3.247630452 +1.676938993 137.511659655 1.163763199 -0.425640413 -0.001481815 -0.351326667 0.000002932 0.000026475 -0.016858073 3.305220008 +1.701973986 137.421562992 1.213056457 -0.423523468 -0.001533553 -0.351998655 0.000003001 0.000026789 -0.016839866 3.282426108 +1.745054473 137.139559773 1.217320912 -0.421141298 -0.002268758 -0.343613667 0.000004207 0.000021431 -0.013165609 3.298095180 +1.739074630 136.936671291 1.233907496 -0.418862527 -0.002126708 -0.367256148 0.000004026 0.000016055 -0.009634630 3.327949212 +1.731516837 136.654446232 1.291356374 -0.416478518 -0.001252048 -0.336498641 0.000002659 0.000008578 -0.004533886 3.363585902 +1.770101876 136.584445187 1.294133694 -0.414379654 -0.000823482 -0.332884436 0.000002025 0.000004896 -0.002328447 3.409639636 +1.792032263 136.657742364 1.282661615 -0.412561814 -0.000677848 -0.317093993 0.000001841 0.000009906 -0.005365018 3.415477997 +1.831721381 136.618364637 1.318888850 -0.410501102 -0.000685630 -0.318859015 0.000001860 0.000005195 -0.002672355 3.457023228 +1.813242905 136.460975547 1.320703047 -0.408294103 -0.000230332 -0.348094982 0.000001157 0.000001951 -0.000666242 3.447401868 +1.864086009 136.407905277 1.347733320 -0.406237136 -0.000133937 -0.306237969 0.000001026 0.000000617 -0.000058517 3.500115579 +1.863311984 136.448937512 1.389566702 -0.404332136 -0.000120908 -0.340418858 0.000001034 0.000003371 -0.001980970 3.467686931 +1.845525441 136.683228167 1.382956549 -0.402743361 -0.000111465 -0.336215967 0.000001004 0.000011607 -0.007237240 3.581459513 +1.875534279 136.612119213 1.368238526 -0.400691560 0.000277433 -0.343373903 0.000000469 0.000005220 -0.003177897 3.529661264 +1.913773570 136.808823089 1.430384713 -0.399054030 0.001362975 -0.325468671 -0.000001175 0.000006311 -0.003621495 3.569060520 +1.922782241 137.041857565 1.439211028 -0.397486777 0.001294211 -0.323476459 -0.000001097 0.000014075 -0.008777645 3.588718222 +1.920343374 137.249849859 1.414356413 -0.395851806 0.000436059 -0.304577577 0.000000286 0.000022700 -0.014067984 3.698069955 +1.939334177 137.268022228 1.434156769 -0.393962037 0.000327665 -0.310772358 0.000000463 0.000020955 -0.012844018 3.627436445 +1.991712899 137.262161166 1.459500686 -0.392037250 0.000913399 -0.317979861 -0.000000462 0.000020932 -0.012566329 3.641933053 +1.997153995 137.180296216 1.484238829 -0.389955102 0.001445881 -0.304359180 -0.000001269 0.000016269 -0.009757870 3.742723741 +1.981908587 137.197802450 1.507527628 -0.388073393 -0.000032580 -0.312970308 0.000000982 0.000027321 -0.016985396 3.694303060 +2.036342135 137.125812186 1.506939825 -0.386033076 -0.000875556 -0.275784777 0.000002306 0.000035662 -0.022223890 3.733523297 +2.031667095 137.045952321 1.560097072 -0.383989080 -0.000900600 -0.306612396 0.000002335 0.000037355 -0.023333648 3.810781871 +2.052025691 136.989830544 1.574052316 -0.381962358 -0.001311160 -0.276822702 0.000003059 0.000038642 -0.024069691 3.849913870 +2.084652134 136.721602492 1.555749866 -0.379594682 -0.001366438 -0.269995501 0.000003134 0.000031420 -0.019852980 3.898815939 +2.080547370 136.576056827 1.594846293 -0.377458227 -0.001091604 -0.303455500 0.000002668 0.000027781 -0.017474879 3.889130190 +2.071059027 136.289718170 1.576870048 -0.375100628 -0.001707558 -0.293787675 0.000003690 0.000027794 -0.017289245 3.947906674 +2.091376029 136.185970132 1.631064214 -0.372997305 -0.000566743 -0.296067220 0.000001937 0.000024269 -0.015386672 3.950894650 +2.142104545 136.270747365 1.625859773 -0.371204673 -0.000478810 -0.253865224 0.000001801 0.000026442 -0.016674952 3.990824813 +2.148733435 136.314302149 1.663633040 -0.369392113 0.000034467 -0.288642702 0.000000988 0.000025026 -0.015636389 3.986081022 +2.197074707 136.347381240 1.654986816 -0.367499597 0.000403000 -0.254390926 0.000000415 0.000025513 -0.016085617 3.945855930 +2.157926224 136.506486079 1.696961864 -0.365861099 0.000202226 -0.261598378 0.000000693 0.000029587 -0.018658334 3.996426392 +2.192927919 136.673499094 1.694151538 -0.364237700 -0.000033607 -0.240950181 0.000001068 0.000036778 -0.023155520 4.052740586 +2.220599924 136.619217922 1.710321222 -0.362193127 -0.000431742 -0.259878055 0.000001675 0.000035384 -0.022514457 4.093986407 +2.207945225 136.553966983 1.714297553 -0.360195124 0.000270794 -0.273233298 0.000000593 0.000028643 -0.017961981 4.098641187 +2.277097549 136.574502790 1.765101354 -0.358321518 0.000746915 -0.260270592 -0.000000183 0.000027628 -0.017515673 4.157657328 +2.275318467 136.740855271 1.787720357 -0.356710335 0.001135560 -0.232354255 -0.000000802 0.000031691 -0.020070228 4.176309264 +2.309760776 136.828228867 1.811164776 -0.354945284 0.000396042 -0.237153961 0.000000336 0.000036786 -0.023234421 4.225191378 +2.307736863 136.849084682 1.799974666 -0.353048258 -0.000311108 -0.217815348 0.000001401 0.000039091 -0.025008507 4.177529339 +2.282948552 136.739283844 1.794876219 -0.350997257 -0.000078025 -0.221058217 0.000001010 0.000034107 -0.021867294 4.244889334 +2.319398519 136.718544404 1.838493394 -0.349038225 -0.000120877 -0.249538493 0.000001051 0.000035694 -0.023020753 4.256134367 +2.322058049 136.623908436 1.827812013 -0.347041494 -0.000584935 -0.202828339 0.000001770 0.000037003 -0.023703359 4.356749783 +2.372864209 136.529046142 1.858259505 -0.345015150 -0.000620707 -0.211164370 0.000001875 0.000035752 -0.022800609 4.377910452 +2.351247297 136.406173519 1.904071654 -0.342914196 0.000284974 -0.244107121 0.000000477 0.000030247 -0.019286067 4.398792119 +2.408432995 136.433233761 1.892105453 -0.341079036 0.000096011 -0.207543917 0.000000819 0.000033761 -0.021287822 4.368941206 +2.411629272 136.403494528 1.941510572 -0.339159561 -0.000560319 -0.213924863 0.000001881 0.000037568 -0.023767234 4.433740824 +2.416469720 136.221919233 1.920971848 -0.337014201 -0.000840898 -0.233164082 0.000002279 0.000034821 -0.022127369 4.479775394 +2.446822199 136.083122302 1.958949758 -0.334933316 -0.000944403 -0.225878019 0.000002456 0.000034048 -0.021297895 4.439064729 +2.475835217 136.193087789 1.967941695 -0.333235871 0.000006927 -0.224468744 0.000001034 0.000034900 -0.021604141 4.433236328 +2.499240732 135.948747268 1.951724410 -0.330976301 0.000407734 -0.194608766 0.000000481 0.000028974 -0.017958374 4.510640127 +2.482353889 135.948300841 1.988793000 -0.329060725 0.000542366 -0.210026707 0.000000288 0.000029385 -0.018418954 4.513940642 +2.498353479 135.892011835 2.039247215 -0.327101163 0.000635087 -0.211299428 0.000000097 0.000022669 -0.014305443 4.603775353 +2.516898458 135.921299515 1.997603365 -0.325253714 0.000443216 -0.188591340 0.000000369 0.000024153 -0.015206007 4.547178943 +2.554620326 135.873349656 2.035803170 -0.323315529 0.000170483 -0.165284933 0.000000767 0.000023037 -0.014638125 4.576293123 +2.583904775 135.875854204 2.042542674 -0.321465632 -0.000488886 -0.177654861 0.000001880 0.000021245 -0.013262765 4.642803865 +2.593585284 135.770371985 2.057987240 -0.319432362 -0.000187787 -0.170705404 0.000001446 0.000020576 -0.012942953 4.613335652 +2.617489172 135.752145998 2.082908026 -0.317525329 0.000214777 -0.190178707 0.000000829 0.000012984 -0.008264085 4.659196197 +2.633482366 135.862098931 2.137006837 -0.315847235 0.000851579 -0.188257807 -0.000000175 0.000014876 -0.009331438 4.734719079 +2.603219360 135.912499375 2.125199890 -0.314073130 0.000250409 -0.193431687 0.000000771 0.000015989 -0.010020851 4.695584486 +2.664681599 136.127551240 2.161549176 -0.312553662 -0.000454863 -0.158831752 0.000001775 0.000023766 -0.015109113 4.783918085 +2.688272558 136.268617048 2.147651469 -0.310976798 -0.000727280 -0.163337271 0.000002251 0.000029995 -0.018612866 4.845519699 +2.691947133 136.150340074 2.171178834 -0.308922427 -0.000450153 -0.161109978 0.000001888 0.000025661 -0.015975603 4.821935709 +2.715234357 136.057556418 2.220306444 -0.306904207 0.000176392 -0.139015250 0.000000854 0.000021297 -0.013385045 4.826088466 +2.677694232 136.034294288 2.182065558 -0.305047491 0.000138045 -0.130524255 0.000000988 0.000023474 -0.014727684 4.908467548 +2.732619481 136.126122458 2.194187149 -0.303324531 -0.000285681 -0.137515603 0.000001662 0.000027885 -0.017483229 4.958815796 +2.727406439 136.008821833 2.252872096 -0.301307263 -0.000130695 -0.159866028 0.000001450 0.000028539 -0.017985428 4.946535472 +2.764789794 135.836767945 2.284213518 -0.299173083 -0.000093588 -0.135086627 0.000001403 0.000024421 -0.015585983 4.952764945 +2.797050069 135.764183762 2.245660061 -0.297226130 0.000255491 -0.127634728 0.000000806 0.000023755 -0.015194638 4.973172734 +2.779609178 135.677957087 2.298146456 -0.295246492 -0.000135279 -0.132990509 0.000001460 0.000020691 -0.013324360 4.967997757 +2.822115837 135.465204179 2.280737476 -0.293062238 0.000708988 -0.117878037 0.000000068 0.000015433 -0.010038443 5.026391787 +2.798505777 135.289578092 2.333564195 -0.290937808 0.000857288 -0.109358243 -0.000000087 0.000011242 -0.007540791 5.058314975 +2.838248312 135.315806083 2.345307575 -0.289152439 0.000935579 -0.120521656 -0.000000274 0.000013801 -0.009045130 5.131241433 +2.861730374 135.324441447 2.322814893 -0.287295873 0.000893343 -0.148153107 -0.000000176 0.000013354 -0.009122163 5.139456984 +2.883794246 135.245624067 2.389394922 -0.285334890 0.000839667 -0.136582968 -0.000000087 0.000009996 -0.007006738 5.153741584 +2.872926407 135.410298218 2.418247380 -0.283769624 0.000988624 -0.141162965 -0.000000321 0.000016494 -0.010875446 5.113721704 +2.886379141 135.403354295 2.397916321 -0.281952195 0.000702909 -0.092450066 0.000000097 0.000015170 -0.010275428 5.142770184 +2.946166900 135.447717400 2.408083257 -0.280183632 0.001000277 -0.111676632 -0.000000370 0.000016445 -0.010949743 5.227048661 +2.942402284 135.511601501 2.404653741 -0.278485829 0.000686050 -0.092860722 0.000000113 0.000018486 -0.012150329 5.239107183 +2.923911671 135.491076552 2.432713527 -0.276630471 0.000660817 -0.106458233 0.000000183 0.000018827 -0.012114806 5.275881167 +2.975846480 135.620483677 2.472734195 -0.275030844 0.000952414 -0.101289537 -0.000000232 0.000020507 -0.013200773 5.238751532 +2.963101868 135.671156178 2.490391689 -0.273256734 0.001246413 -0.101414302 -0.000000724 0.000022428 -0.014409437 5.332710773 +3.018397646 135.736474398 2.483434560 -0.271543804 0.000867727 -0.074811392 -0.000000115 0.000026217 -0.016837997 5.365222234 +3.040533367 135.597951740 2.526522777 -0.269509730 0.000825150 -0.072385744 -0.000000073 0.000020858 -0.013402895 5.373140922 +3.021438774 135.502338256 2.503206373 -0.267532860 0.001108459 -0.081142482 -0.000000515 0.000019755 -0.012812491 5.359265873 +3.024527600 135.390727966 2.578200406 -0.265530826 0.001163110 -0.094886034 -0.000000584 0.000019660 -0.013005382 5.459797360 +3.082831144 135.449936731 2.537968705 -0.263817015 0.001556486 -0.091616083 -0.000001200 0.000023780 -0.015642509 5.490986994 +3.069340916 135.279483658 2.570365195 -0.261717987 0.001093370 -0.090624998 -0.000000407 0.000026682 -0.017608110 5.454521157 +3.081225301 135.134716881 2.607803310 -0.259671099 0.001840894 -0.064382604 -0.000001633 0.000020798 -0.013842685 5.507851038 +3.094038307 135.161380760 2.614294052 -0.257899598 0.001541633 -0.057569406 -0.000001173 0.000025228 -0.016722165 5.500449055 +3.101600657 135.155492321 2.632395009 -0.256070088 0.001985591 -0.051867322 -0.000001871 0.000029715 -0.019650586 5.521085578 +3.150094049 135.252260395 2.638574915 -0.254413052 0.002032656 -0.049390518 -0.000001854 0.000035007 -0.023012871 5.624387136 +3.156520775 135.070375087 2.680860494 -0.252313169 0.001428338 -0.073711452 -0.000000965 0.000034065 -0.022476721 5.557934161 +3.195907720 134.964767904 2.664734084 -0.250396234 0.001759605 -0.043075007 -0.000001450 0.000032667 -0.021281147 5.600382808 +3.194678900 134.787675785 2.705484849 -0.248282244 0.002389726 -0.048314564 -0.000002447 0.000026800 -0.017693001 5.724047734 +3.204152408 134.886825760 2.739978921 -0.246636870 0.001954466 -0.064924922 -0.000001726 0.000034885 -0.022666252 5.700386305 +3.198893901 135.055655340 2.716844792 -0.245147400 0.002038060 -0.054146162 -0.000001881 0.000034141 -0.021861213 5.727701700 +3.225346099 135.123447848 2.765329275 -0.243437927 0.001911824 -0.047239918 -0.000001645 0.000035976 -0.022884967 5.799852706 +3.263658224 135.021066448 2.779909040 -0.241474739 0.001335219 -0.041572022 -0.000000711 0.000032053 -0.020684823 5.719904901 +3.271076307 135.032352728 2.751988165 -0.239665118 0.000921086 -0.036271423 -0.000000166 0.000033929 -0.021923218 5.843541727 +3.320064214 134.922042719 2.770492503 -0.237688924 0.000272685 -0.042742742 0.000000832 0.000030584 -0.019985138 5.871431327 +3.280052636 134.807328670 2.803966551 -0.235734267 0.000450166 -0.042128499 0.000000540 0.000028091 -0.018130367 5.813054597 +3.322167283 134.784008904 2.838422187 -0.233861803 0.000788078 -0.018223570 0.000000115 0.000025038 -0.016444966 5.833469062 +3.344754168 134.857662783 2.852746927 -0.232183687 0.001156370 -0.003396079 -0.000000511 0.000030358 -0.019793506 5.919665686 +3.334137373 134.872802839 2.870531833 -0.230408433 0.000366781 -0.017091262 0.000000766 0.000032412 -0.021332876 5.887742944 +3.377563148 134.874266257 2.842125778 -0.228607296 0.000387196 -0.013845461 0.000000689 0.000031035 -0.020589146 5.906068750 +3.414957879 134.802031597 2.866373972 -0.226678900 0.000683153 -0.003263448 0.000000196 0.000028608 -0.019012930 5.963466756 +3.387301158 134.814862868 2.925027092 -0.224915652 0.000656412 -0.018267841 0.000000221 0.000031956 -0.021112439 5.994396885 +3.400773940 134.787301421 2.946527700 -0.223103199 0.000861943 -0.010936481 -0.000000007 0.000031469 -0.020750955 5.981626236 +3.410791851 134.841543661 2.956496573 -0.221426326 0.001042498 -0.004831222 -0.000000261 0.000031643 -0.020631496 6.082171009 +3.467071599 134.845844706 2.985968231 -0.219634723 0.001175645 0.019435542 -0.000000450 0.000032961 -0.021692250 6.091361781 +3.440540176 134.937250555 3.000614282 -0.217995954 0.001378337 -0.001160610 -0.000000783 0.000038219 -0.025100799 6.172544846 +3.475006862 135.036282724 2.970471619 -0.216414060 0.001330191 0.011471743 -0.000000717 0.000039130 -0.025572201 6.102193697 +3.536821588 135.128647119 3.005884479 -0.214789664 0.001586575 0.005868193 -0.000001101 0.000042720 -0.027723918 6.216773817 +3.539176030 134.887585408 3.040716013 -0.212640083 0.000695040 0.013888723 0.000000360 0.000038712 -0.024926358 6.211345207 +3.520745595 134.710591225 3.039330128 -0.210551564 0.000196319 -0.008438367 0.000001079 0.000034553 -0.022533034 6.247434785 +3.566274404 134.626727019 3.061959463 -0.208636087 0.000684494 0.032910109 0.000000374 0.000035563 -0.023224014 6.228107177 +3.546290301 134.493072503 3.074316047 -0.206600374 0.000968919 0.029675582 -0.000000140 0.000032957 -0.021940543 6.266446041 +3.595387444 134.523869732 3.102132802 -0.204901266 0.001619242 0.009416380 -0.000001154 0.000030828 -0.020489058 6.246682715 +3.626834313 134.411748228 3.073926808 -0.202939927 0.000886686 0.003429319 -0.000000065 0.000027582 -0.018387517 6.370173016 +3.645986556 134.397015409 3.118852435 -0.201128560 0.000633964 0.044158301 0.000000332 0.000024848 -0.016593653 6.341637904 +3.625524560 134.263539349 3.117628269 -0.199148744 0.000602759 0.037675588 0.000000356 0.000021887 -0.014791028 6.395828542 +3.651020680 134.124597023 3.141092739 -0.197142824 0.000518857 0.045310690 0.000000459 0.000017475 -0.012043625 6.429626975 +3.680201166 134.181703883 3.171675874 -0.195474562 0.000593474 0.047637019 0.000000400 0.000020549 -0.014081092 6.400605412 +3.698141459 134.128222398 3.200779045 -0.193609062 0.000097131 0.055916510 0.000001177 0.000019067 -0.013173062 6.465410843 +3.698225604 134.168990159 3.194987036 -0.191928484 0.000719790 0.066866329 0.000000177 0.000016571 -0.011339947 6.463816281 +3.708084820 134.312364691 3.217641222 -0.190386103 0.000854689 0.059095451 0.000000008 0.000022177 -0.014813540 6.543254703 +3.718784348 134.514885366 3.208698158 -0.188958382 -0.000022823 0.035133730 0.000001423 0.000027596 -0.018290036 6.479291811 +3.721480296 134.519358841 3.230722377 -0.187177676 -0.000218938 0.068086780 0.000001709 0.000025540 -0.016949835 6.620492204 +3.762341665 134.574873842 3.252221976 -0.185529977 0.000537549 0.058061359 0.000000519 0.000028423 -0.018710259 6.619703672 +3.760047086 134.666679755 3.278997722 -0.183929169 0.000258344 0.071049118 0.000001039 0.000029416 -0.019314456 6.549921307 +3.791883265 134.572176480 3.281318808 -0.181972636 0.000398001 0.074744806 0.000000811 0.000029592 -0.019662149 6.686418552 +3.842972311 134.394542795 3.299150899 -0.179929743 0.000479451 0.079518770 0.000000660 0.000025360 -0.016956999 6.709615622 +3.831988959 134.540390029 3.357338838 -0.178408014 0.000716398 0.051841382 0.000000328 0.000032125 -0.021195082 6.715099218 +3.875142822 134.417004277 3.353275989 -0.176404326 0.000946824 0.063397663 -0.000000021 0.000029184 -0.019616180 6.764824010 +3.836628929 134.358805758 3.393078308 -0.174547673 0.000901416 0.063899079 0.000000005 0.000027696 -0.018815352 6.738705568 +3.913002478 134.299915806 3.388005325 -0.172696486 0.001216241 0.105226470 -0.000000521 0.000028622 -0.019392066 6.753244806 +3.869528908 134.097817865 3.379814603 -0.170607718 0.000730563 0.087861550 0.000000237 0.000024623 -0.017026772 6.743477700 +3.900276500 133.823628848 3.386235830 -0.168415089 0.001218750 0.099068176 -0.000000568 0.000018342 -0.013093770 6.884052320 +3.948058341 133.590589177 3.432124260 -0.166259424 0.001856532 0.102090011 -0.000001541 0.000012453 -0.009367101 6.894428732 +3.952160017 133.575997691 3.441509708 -0.164500796 0.001450891 0.076073071 -0.000000924 0.000014695 -0.010613457 6.812008783 +3.959360557 133.532017632 3.474400409 -0.162671700 0.001405183 0.086553673 -0.000000845 0.000012912 -0.009524479 6.923297090 +3.964475423 133.609986936 3.495229297 -0.161064331 0.001258068 0.092809460 -0.000000612 0.000014969 -0.010631515 6.946460008 +3.969778186 133.571625253 3.487528079 -0.159245612 0.001487831 0.127588186 -0.000000934 0.000015863 -0.011272420 6.942376630 +3.996867264 133.654568556 3.515027560 -0.157642517 0.001099397 0.096655078 -0.000000360 0.000016793 -0.011617067 6.976746046 +4.004608472 133.775431582 3.507205595 -0.156106068 0.001000616 0.100931020 -0.000000158 0.000023334 -0.015583396 6.992033876 +4.030940263 133.843562664 3.572701907 -0.154480474 0.000899862 0.125614538 0.000000040 0.000025041 -0.016493509 7.026307131 +4.033422645 133.788421869 3.560287110 -0.152641827 0.000830821 0.127524533 0.000000127 0.000022177 -0.014673275 6.999444980 +4.097872531 133.834647826 3.560816440 -0.150968834 0.001116900 0.133583843 -0.000000313 0.000023831 -0.015735526 7.075560798 +4.123472850 133.973948439 3.573975970 -0.149432832 0.001669298 0.143555164 -0.000001188 0.000026109 -0.017162536 7.061925661 +4.089551418 134.015909699 3.638528561 -0.147726363 0.001326473 0.141364785 -0.000000607 0.000027379 -0.018137499 7.080388908 +4.138371842 134.056663625 3.637261389 -0.146024520 0.001349992 0.109271719 -0.000000658 0.000030190 -0.020138878 7.170815276 +4.110200913 133.956929578 3.654791517 -0.144092302 0.000911355 0.140787324 0.000000026 0.000026031 -0.017676862 7.204010881 +4.164986342 133.903475158 3.667694794 -0.142237227 0.001258906 0.160943841 -0.000000565 0.000025763 -0.017622353 7.246254032 +4.184824278 133.707730861 3.692131163 -0.140159873 0.001011956 0.122783900 -0.000000157 0.000023431 -0.016384206 7.212314909 +4.158980102 133.694076500 3.695197970 -0.138376943 0.001784560 0.149228031 -0.000001375 0.000023762 -0.016757664 7.297282367 +4.173022304 133.695371705 3.706348676 -0.136632677 0.001759329 0.171340140 -0.000001328 0.000025341 -0.017639762 7.321956617 +4.198597624 133.707575985 3.747682087 -0.134898853 0.001936944 0.138072647 -0.000001597 0.000029852 -0.020628560 7.322070565 +4.262893697 133.641932155 3.731596618 -0.133039369 0.001904240 0.157665979 -0.000001528 0.000026522 -0.018574904 7.396996198 +4.240102494 133.674070035 3.737875701 -0.131345068 0.001715616 0.141036955 -0.000001241 0.000031706 -0.021894158 7.409123151 +4.273446102 133.544064359 3.756775109 -0.129400460 0.001641647 0.175436364 -0.000001180 0.000030810 -0.021254988 7.399857521 +4.289114753 133.289599598 3.814618067 -0.127274494 0.001834176 0.157033435 -0.000001455 0.000025925 -0.017925057 7.459488395 +4.308441181 133.256294172 3.817445015 -0.125519229 0.003115252 0.153958707 -0.000003373 0.000031216 -0.021088815 7.473980588 +4.309102170 133.410930999 3.843770382 -0.124078108 0.003223651 0.196919756 -0.000003402 0.000040253 -0.026795775 7.539164026 +4.330761103 133.421105629 3.828445580 -0.122348008 0.002888738 0.186841357 -0.000002903 0.000036543 -0.024340642 7.457833855 +4.347123210 133.269732062 3.861701442 -0.120364424 0.002522348 0.195782499 -0.000002326 0.000032511 -0.021612739 7.578165407 +4.401394786 133.274135717 3.837903790 -0.118602639 0.002509561 0.191960991 -0.000002338 0.000032659 -0.021947668 7.566781902 +4.355949287 133.264943131 3.913435569 -0.116853424 0.002270447 0.195570090 -0.000001986 0.000029099 -0.019560118 7.537118908 +4.394836192 133.215946296 3.899716459 -0.115028894 0.001806621 0.190943794 -0.000001306 0.000029093 -0.019522635 7.669691177 +4.437454705 133.224199165 3.919360212 -0.113289720 0.001932016 0.177142685 -0.000001477 0.000027154 -0.018242642 7.679695830 +4.440612364 133.105550823 3.952087474 -0.111367477 0.001455119 0.195650785 -0.000000683 0.000024451 -0.016844721 7.608789581 +4.437937540 133.086604964 3.939714440 -0.109545653 0.001740871 0.202276993 -0.000001200 0.000021461 -0.015334131 7.662059070 +4.493720194 133.269928090 3.975332341 -0.108077846 0.001687526 0.219014014 -0.000001186 0.000028349 -0.019767370 7.704803748 +4.456108466 133.385774546 3.971693467 -0.106503421 0.000657261 0.191043430 0.000000423 0.000028709 -0.020112712 7.758251096 +4.487468476 133.400552574 3.986940457 -0.104772729 0.000610184 0.210587311 0.000000492 0.000028446 -0.020016366 7.821087887 +4.541630774 133.314305665 4.025571893 -0.102901068 0.000426343 0.227890560 0.000000701 0.000026458 -0.018686671 7.784393961 +4.542628778 133.443909682 4.027712775 -0.101356249 0.000432250 0.208555223 0.000000802 0.000032561 -0.022614594 7.847737520 +4.560734459 133.324601474 4.021959103 -0.099475207 0.000455380 0.221487752 0.000000711 0.000028860 -0.020017984 7.906459344 +4.562996575 133.367454756 4.047143398 -0.097780999 0.000440689 0.233271892 0.000000687 0.000032723 -0.022793446 7.865834003 +4.557116277 133.335543079 4.112485520 -0.096016023 0.000750228 0.210825618 0.000000230 0.000031991 -0.021984449 7.917122743 +4.627394992 133.444207800 4.110593161 -0.094466221 0.000429102 0.236187845 0.000000744 0.000034272 -0.023329241 7.976694381 +4.639141742 133.335659305 4.124263350 -0.092560764 0.000475015 0.207304451 0.000000700 0.000033005 -0.022485024 7.999247961 +4.625762570 133.176931145 4.118339823 -0.090596744 0.000922151 0.236258849 0.000000060 0.000029139 -0.019782216 7.934439491 +4.668563787 132.818516844 4.114221461 -0.088309305 0.000973797 0.242391451 -0.000000021 0.000025778 -0.017627096 7.967974694 +4.650876227 132.567342238 4.167231506 -0.086204574 0.001625859 0.217551835 -0.000001006 0.000021478 -0.014989193 8.046816000 +4.670009287 132.492070715 4.147922327 -0.084363824 0.002546608 0.265123623 -0.000002392 0.000021185 -0.014711212 8.092378648 +4.714789298 132.474897151 4.179449516 -0.082579181 0.002322244 0.265459680 -0.000002047 0.000020507 -0.014416071 8.052651377 +4.684720581 132.350377303 4.190810562 -0.080632559 0.002143203 0.265858273 -0.000001764 0.000018359 -0.013267483 8.094281526 +4.757852104 132.351450765 4.224353308 -0.078883163 0.002604081 0.269806782 -0.000002526 0.000019812 -0.014232639 8.117037182 +4.710798262 132.418358617 4.261943679 -0.077231017 0.002385797 0.252381479 -0.000002149 0.000022659 -0.016310599 8.157748688 +4.746693057 132.422603485 4.268862413 -0.075508461 0.002683521 0.244615599 -0.000002666 0.000025857 -0.018343664 8.148352964 +4.746530303 132.482494276 4.264280020 -0.073856546 0.002347181 0.257913015 -0.000002075 0.000026441 -0.018731939 8.246500746 +4.789116026 132.581104162 4.279069542 -0.072276851 0.001853091 0.275854896 -0.000001334 0.000027202 -0.019260950 8.191847240 +4.828556425 132.589279748 4.281115866 -0.070539275 0.000978788 0.293496837 -0.000000023 0.000023321 -0.016741533 8.317183677 +4.853101374 132.548754838 4.303662922 -0.068726376 0.001081019 0.254866052 -0.000000222 0.000020562 -0.015002038 8.242461771 +4.844050291 132.991108092 4.356585356 -0.067717542 0.000827749 0.290438889 0.000000182 0.000032690 -0.022392185 8.356190331 +4.878405096 133.175212419 4.330763239 -0.066265792 0.000061621 0.259563368 0.000001377 0.000033863 -0.023292185 8.390884729 +4.878610690 133.094301399 4.402287480 -0.064388595 -0.000087180 0.297957923 0.000001558 0.000029631 -0.020620701 8.367459673 +4.907458430 132.972349311 4.386045130 -0.062472413 0.000170154 0.286574468 0.000001148 0.000029781 -0.020651568 8.413065658 +4.874315357 132.961900293 4.379014858 -0.060728502 0.000117217 0.268950222 0.000001232 0.000030398 -0.020930651 8.408008755 +4.921785657 132.915676479 4.428142941 -0.058917909 0.000509667 0.312101475 0.000000659 0.000029841 -0.020785682 8.484886932 +4.922988635 132.795371460 4.461751488 -0.057008148 0.000244555 0.281535578 0.000001029 0.000028079 -0.019457947 8.489980107 +4.943127884 132.642833488 4.445757854 -0.055055445 0.000956620 0.282353697 -0.000000030 0.000026755 -0.018542377 8.519046245 +5.003363274 132.485795335 4.490892600 -0.053070900 0.001107897 0.293478044 -0.000000284 0.000024329 -0.017096069 8.574296332 +4.969120291 132.391422769 4.502422615 -0.051193933 0.001895844 0.298919314 -0.000001476 0.000024280 -0.017145486 8.552323488 +5.006198417 132.173023409 4.510896157 -0.049123720 0.002072630 0.316804481 -0.000001718 0.000017919 -0.013061115 8.631848714 +5.002836409 131.910179671 4.512932913 -0.047008820 0.002072991 0.323673335 -0.000001657 0.000012768 -0.009533905 8.609496581 +5.041913192 131.734366397 4.530355002 -0.044993556 0.002883666 0.342482113 -0.000002898 0.000013041 -0.009860383 8.651956331 +5.086944235 131.712821675 4.548953923 -0.043182658 0.003262006 0.346063038 -0.000003481 0.000012362 -0.009649546 8.670670638 +5.045491022 131.640468897 4.564901707 -0.041361087 0.003240153 0.337576817 -0.000003444 0.000011573 -0.008989940 8.716907610 +5.116645106 131.682473799 4.567594952 -0.039693562 0.003186659 0.316752980 -0.000003361 0.000011356 -0.008855975 8.721346238 +5.077558501 131.868281896 4.602417643 -0.038282316 0.003000712 0.354000687 -0.000003054 0.000019118 -0.013605756 8.777355177 +5.098015880 132.081424110 4.588257981 -0.036874397 0.002731720 0.330154119 -0.000002670 0.000022383 -0.015935879 8.761394077 +5.145000181 132.170069094 4.639554433 -0.035250326 0.002125085 0.323731164 -0.000001726 0.000024929 -0.017492776 8.845888496 +5.126744605 132.080978199 4.621476197 -0.033378659 0.002142666 0.347656504 -0.000001803 0.000022382 -0.015983747 8.769023381 +5.139921367 132.137656497 4.692652083 -0.031713271 0.001975649 0.320243452 -0.000001547 0.000025397 -0.018167448 8.909367169 +5.194748470 132.185581126 4.708134984 -0.030027873 0.001972161 0.324964989 -0.000001599 0.000025657 -0.018418193 8.901747637 +5.168926590 132.242267849 4.689650530 -0.028404678 0.002483146 0.335113107 -0.000002340 0.000029215 -0.020553824 8.906900834 +5.249078653 132.467996218 4.748335364 -0.027024319 0.002419578 0.339423255 -0.000002244 0.000034948 -0.024428775 8.881253017 +5.235655396 132.555340550 4.763351667 -0.025398362 0.001727721 0.368667878 -0.000001179 0.000036919 -0.025739968 8.994404616 +5.240922328 132.445647334 4.781908067 -0.023480259 0.001947581 0.358143378 -0.000001531 0.000032260 -0.023081277 9.006655918 +5.279415659 132.373169108 4.742814512 -0.021624560 0.002167360 0.381574631 -0.000001910 0.000032960 -0.023411279 8.994472461 +5.311760758 132.226805593 4.748794557 -0.019705193 0.002172064 0.362089505 -0.000001845 0.000028615 -0.020376178 9.002746336 +5.290385157 132.120812916 4.781445331 -0.017812167 0.003173694 0.387777610 -0.000003339 0.000030684 -0.021558369 9.034238447 +5.327393904 132.122459992 4.804286008 -0.016096157 0.002981184 0.386620933 -0.000003038 0.000033796 -0.023654984 9.093912005 +5.337638087 131.969133569 4.813055914 -0.014117379 0.003177390 0.381693052 -0.000003313 0.000028611 -0.020047172 9.133669783 +5.365483847 131.988278102 4.864192746 -0.012422612 0.003397366 0.363828680 -0.000003681 0.000030546 -0.021472904 9.181783454 +5.369555614 131.742158129 4.845161845 -0.010291308 0.003467357 0.385542009 -0.000003817 0.000025409 -0.018239525 9.126457341 +5.371478654 131.829506077 4.876296216 -0.008721207 0.003399269 0.385533545 -0.000003701 0.000025967 -0.018119009 9.189743952 +5.419409947 131.480878419 4.879996304 -0.006489893 0.003730419 0.384677192 -0.000004150 0.000021027 -0.014790764 9.205831217 +5.394049013 131.265221046 4.902052968 -0.004401429 0.004097847 0.373661499 -0.000004727 0.000018187 -0.013018786 9.208962510 +5.448430552 131.267973693 4.955496997 -0.002642933 0.003952661 0.385257272 -0.000004455 0.000020599 -0.014807678 9.299990406 +5.478058734 131.344512338 4.912446725 -0.000984664 0.003784434 0.392391832 -0.000004290 0.000021385 -0.015768780 9.330588988 +5.446654055 131.345053590 4.936714854 0.000771880 0.002996006 0.397655611 -0.000003085 0.000019262 -0.014321412 9.306134987 +5.491558732 131.485410227 4.970070844 0.002294408 0.003260670 0.389512983 -0.000003549 0.000018739 -0.014076906 9.323956797 +5.504809471 131.413988837 5.016541401 0.004094463 0.002444842 0.401338494 -0.000002244 0.000019745 -0.014525288 9.370615644 +5.504455702 131.378397684 4.991017754 0.005905912 0.002335363 0.402861270 -0.000002107 0.000019235 -0.014387498 9.371613240 +5.526317993 131.360646876 5.055448960 0.007683099 0.002877963 0.433106181 -0.000002916 0.000018126 -0.013708755 9.382854522 +5.572674868 131.454959058 5.074053359 0.009264737 0.002375015 0.412504483 -0.000002162 0.000020224 -0.014886030 9.438826002 +5.589245445 131.536233347 5.050717237 0.010877212 0.002199560 0.442300107 -0.000001932 0.000022496 -0.016415896 9.451382006 +5.590861554 131.726529167 5.107657523 0.012317927 0.002492226 0.415401474 -0.000002364 0.000028565 -0.020336437 9.472381330 +5.583945334 131.845903463 5.066439046 0.013911831 0.001735020 0.444071588 -0.000001138 0.000030983 -0.021904935 9.548614957 +5.577272182 131.801081513 5.125330498 0.015682751 0.001401675 0.439060450 -0.000000710 0.000030234 -0.021090379 9.614215467 +5.629762239 131.545544719 5.129524112 0.017824916 0.001326834 0.412798442 -0.000000564 0.000024524 -0.017483954 9.544191941 +5.644847509 131.478002827 5.148610436 0.019653439 0.001504395 0.450275572 -0.000000848 0.000023032 -0.016447522 9.660889614 +5.647178841 131.583977142 5.156160283 0.021244456 0.001557735 0.419287615 -0.000000940 0.000026647 -0.018656697 9.644592555 +5.698480055 131.345249072 5.154496690 0.023343986 0.001357488 0.455994656 -0.000000615 0.000018713 -0.013519979 9.623989559 +5.697735342 131.197041216 5.165708950 0.025303377 0.001931554 0.468995082 -0.000001477 0.000015994 -0.011800463 9.714129805 +5.714001036 131.071748313 5.214745047 0.027275420 0.001885495 0.449990303 -0.000001436 0.000015306 -0.011563559 9.733847432 +5.708416094 130.835095234 5.242194380 0.029355948 0.001632335 0.463267146 -0.000001013 0.000008019 -0.006675512 9.720187116 +5.709978662 130.757716014 5.249642884 0.031237706 0.001428113 0.464302037 -0.000000736 0.000006740 -0.005861741 9.770196084 +5.740880400 130.657858435 5.252740197 0.033124776 0.001547678 0.449670562 -0.000000839 0.000005838 -0.005269004 9.734395430 +5.753249321 130.546718338 5.300565208 0.035047488 0.001405608 0.480832734 -0.000000633 0.000000626 -0.001800466 9.760384115 +5.776959825 130.290910775 5.293332058 0.037209488 0.001559032 0.459281815 -0.000000889 -0.000004718 0.001528674 9.883715542 +5.826766024 130.372288435 5.285316517 0.038800451 0.001984444 0.494418780 -0.000001517 -0.000004610 0.001496997 9.823676532 +5.797190959 130.474464788 5.332089579 0.040399855 0.001681853 0.466423757 -0.000001113 0.000001304 -0.002288445 9.922600881 +5.813324292 130.642879570 5.324176190 0.041896291 0.001438687 0.481615159 -0.000000768 0.000005341 -0.005007393 9.959678211 +5.853010618 130.528552980 5.369027903 0.043812863 0.001586002 0.474782374 -0.000000905 0.000003617 -0.003656291 9.988036743 +5.875620067 130.697963856 5.401942880 0.045298913 0.001478796 0.473264698 -0.000000777 0.000007663 -0.006301980 10.004083630 +5.862459798 130.850106415 5.369682223 0.046813322 0.001560040 0.491961961 -0.000000937 0.000012853 -0.009653741 10.060017237 +5.910363622 130.875570927 5.430124642 0.048537340 0.001210322 0.473384281 -0.000000417 0.000015696 -0.011627210 10.005252476 +5.940562705 130.900086411 5.430725804 0.050247826 0.001565067 0.478157766 -0.000000914 0.000016311 -0.012104713 10.118777639 +5.952751281 130.756512037 5.406950619 0.052228649 0.001759601 0.479321374 -0.000001213 0.000011539 -0.008959677 10.089905908 +5.934537757 131.053964763 5.433291478 0.053498943 0.001810453 0.493444181 -0.000001324 0.000019153 -0.013836093 10.128911061 +5.954179931 131.043752820 5.495510503 0.055263857 0.001436009 0.521831819 -0.000000770 0.000020910 -0.015007833 10.191368598 +5.961713038 130.842443657 5.481485615 0.057323010 0.001597486 0.510177884 -0.000000965 0.000014192 -0.010676087 10.127579654 +5.995631552 130.750321936 5.524635183 0.059237821 0.001451249 0.531123821 -0.000000734 0.000012695 -0.009708516 10.248489762 +6.003878574 130.663822745 5.534053154 0.061121223 0.001465230 0.540124360 -0.000000794 0.000010962 -0.008640392 10.173427698 +6.017054419 130.684286288 5.499618926 0.062854561 0.001302541 0.510732632 -0.000000493 0.000012981 -0.009856854 10.296032523 +6.076817594 130.338890256 5.566084116 0.065123147 0.001518992 0.508680844 -0.000000868 0.000000687 -0.001786471 10.324320002 +6.057646161 130.450944188 5.576719894 0.066701303 0.001592058 0.526911187 -0.000000972 0.000005369 -0.004638940 10.252876841 +6.072594877 130.388509602 5.605144471 0.068533624 0.001460571 0.521950293 -0.000000807 0.000003592 -0.003553480 10.264088727 +6.103123097 130.484160899 5.602300645 0.070156029 0.001744760 0.550573857 -0.000001189 0.000008173 -0.006533124 10.317126056 +6.084467112 130.359873803 5.621640319 0.072113217 0.001291045 0.523901033 -0.000000548 0.000005127 -0.004589461 10.378151214 +6.109882511 130.258195373 5.603609813 0.074035885 0.001772787 0.556386052 -0.000001244 0.000002053 -0.002548283 10.433098310 +6.160741219 130.151388246 5.626746282 0.075957575 0.001342641 0.546640078 -0.000000581 -0.000000160 -0.000970201 10.437969928 +6.167143174 130.254763454 5.631224651 0.077559338 0.001538084 0.556770277 -0.000000839 0.000004078 -0.003734533 10.428312025 +6.158448834 130.157921342 5.674736329 0.079458547 0.001682079 0.541276189 -0.000001137 0.000002146 -0.002467469 10.469269070 +6.217632023 130.300780555 5.683172060 0.081010038 0.001450777 0.527863696 -0.000000736 0.000005298 -0.004642456 10.546747386 +6.205948667 130.325312629 5.696852949 0.082736192 0.001720126 0.540322324 -0.000001132 0.000009090 -0.007194926 10.545966590 +6.230316731 130.277716886 5.727096799 0.084576358 0.001644513 0.559369389 -0.000001061 0.000007116 -0.006091370 10.528068506 +6.245497826 130.319852430 5.722413680 0.086255374 0.001685962 0.538512092 -0.000001085 0.000009915 -0.007647195 10.584616803 +6.238940521 130.318352661 5.788852791 0.088054925 0.001835012 0.568102072 -0.000001296 0.000011679 -0.009045350 10.657650063 +6.248345981 130.341849708 5.805578752 0.089756519 0.001710911 0.557709205 -0.000001112 0.000013014 -0.009686426 10.594686992 +6.290139575 130.303774818 5.798630872 0.091612481 0.001608670 0.582012060 -0.000000982 0.000009992 -0.007846391 10.701708541 +6.277536985 130.356867717 5.775553908 0.093314444 0.001753990 0.594567641 -0.000001144 0.000012265 -0.009340499 10.648148985 +6.320798944 130.412441549 5.852000430 0.094965498 0.001586624 0.555034070 -0.000000892 0.000015037 -0.011056809 10.663957959 +6.345290997 130.285054523 5.853626196 0.096939542 0.001595586 0.574160323 -0.000000868 0.000013835 -0.010276761 10.682014351 +6.366985475 130.320936073 5.829323401 0.098653436 0.001632282 0.581470284 -0.000000987 0.000015373 -0.011306319 10.705671982 +6.342981161 130.353703027 5.907125611 0.100371495 0.001468929 0.567700558 -0.000000759 0.000017361 -0.012342483 10.851630857 +6.404326696 130.290187049 5.877963798 0.102234296 0.001675489 0.570967690 -0.000001089 0.000014434 -0.010491946 10.868004693 +6.384588263 130.187791739 5.927247989 0.104147946 0.001408527 0.573918812 -0.000000655 0.000013270 -0.009585743 10.789510671 +6.429158832 130.228275746 5.920363374 0.105873798 0.001673549 0.618617050 -0.000001097 0.000016973 -0.012203509 10.893375866 +6.446437661 130.133200040 5.945042764 0.107778073 0.001314781 0.625365415 -0.000000532 0.000013234 -0.009589495 10.957977666 +6.473690639 130.067353357 5.954039701 0.109679261 0.001323745 0.599765348 -0.000000575 0.000011932 -0.008810478 10.889733265 +6.442251574 130.050769294 5.975330242 0.111467420 0.001180435 0.599179255 -0.000000327 0.000013689 -0.009994024 10.899007325 +6.511781676 130.002439543 5.966487769 0.113341084 0.000774882 0.614465679 0.000000348 0.000014681 -0.010621868 10.959658117 +6.496718955 129.922519232 6.010249658 0.115208368 0.000913405 0.629702403 0.000000037 0.000014139 -0.010092864 11.032747898 +6.514041264 129.886887214 5.997720102 0.117073464 0.000868655 0.633315704 0.000000160 0.000009650 -0.007354974 11.042668028 +6.525394499 129.935411672 6.033396837 0.118785656 0.000756941 0.639862927 0.000000332 0.000015154 -0.010948751 11.050121351 +6.557026007 129.891672914 6.055841428 0.120603699 0.000816138 0.639898110 0.000000226 0.000014631 -0.010407327 11.134100456 +6.555994674 129.865991917 6.067093341 0.122416694 0.000921127 0.603618821 0.000000037 0.000014900 -0.010559347 11.046697158 +6.577008000 129.794453784 6.108207314 0.124324037 0.001079622 0.652595068 -0.000000214 0.000013369 -0.009665995 11.136359966 +6.592169889 129.867446861 6.135311487 0.126015867 0.000695238 0.610798112 0.000000436 0.000015615 -0.011051654 11.116957615 +6.627214937 129.804484276 6.150016285 0.127892408 0.000896358 0.614670824 0.000000095 0.000014934 -0.010659621 11.188281237 +6.645796139 129.792650699 6.151228625 0.129680746 0.000740226 0.652072596 0.000000349 0.000016180 -0.011393055 11.222526839 +6.683939756 129.822997987 6.131130464 0.131446354 0.000936966 0.646720709 0.000000027 0.000017543 -0.012343693 11.258071278 +6.697057417 129.763044459 6.136521949 0.133304023 0.000878844 0.649329429 0.000000095 0.000018104 -0.012593071 11.229966728 +6.673756524 129.908259960 6.162973604 0.134889403 0.000824584 0.651511997 0.000000237 0.000021581 -0.014913273 11.272923395 +6.679566530 129.894864394 6.205203157 0.136717058 0.001212202 0.632983625 -0.000000390 0.000022293 -0.015468836 11.297634282 +6.744305076 129.857345833 6.224884823 0.138532436 0.000998028 0.644502031 -0.000000094 0.000023054 -0.015870411 11.359870607 +6.718546137 129.794692296 6.223618317 0.140424090 0.000892391 0.642152016 0.000000134 0.000021613 -0.014962270 11.383198717 +6.752323962 129.714112135 6.258037201 0.142345570 0.001147177 0.689088553 -0.000000275 0.000017797 -0.012423704 11.421590513 +6.793188277 129.768173469 6.291319564 0.144077600 0.001248782 0.646425825 -0.000000442 0.000022174 -0.015220380 11.382704726 +6.754203235 129.704729283 6.265101214 0.145966666 0.001143303 0.649201183 -0.000000230 0.000021828 -0.014996468 11.469728434 +6.781679753 129.668107005 6.283590623 0.147803069 0.000957595 0.682578855 -0.000000011 0.000018715 -0.013048632 11.510579708 +6.809269864 129.706162661 6.289161278 0.149571832 0.001400687 0.670002888 -0.000000655 0.000020207 -0.013942046 11.490270796 +6.835614886 129.694055788 6.332338252 0.151356580 0.001248878 0.662525667 -0.000000442 0.000024073 -0.016298380 11.516633020 +6.873368093 129.615230427 6.368117757 0.153285894 0.000813523 0.691256783 0.000000238 0.000021828 -0.014742850 11.579915028 +6.844248374 129.545331702 6.349685031 0.155208145 0.001079518 0.700024408 -0.000000162 0.000019859 -0.013575556 11.549409124 +6.910468792 129.587040953 6.398511928 0.156950164 0.001385793 0.706263365 -0.000000621 0.000021644 -0.014681932 11.664610339 +6.891232092 129.479035065 6.391434172 0.158908340 0.001350027 0.682751357 -0.000000606 0.000020072 -0.013650673 11.589269044 +6.930921495 129.447070277 6.415302648 0.160762973 0.001060621 0.694298989 -0.000000161 0.000020756 -0.013984478 11.662539436 +6.929915590 129.537989825 6.460640965 0.162451964 0.001179410 0.695990324 -0.000000346 0.000023473 -0.015710266 11.630078845 +6.933285124 129.465177647 6.457185399 0.164359447 0.001245690 0.709607117 -0.000000372 0.000020901 -0.014071450 11.690251199 +6.956272910 129.468105342 6.492175785 0.166185403 0.001246616 0.721004373 -0.000000398 0.000023456 -0.015698267 11.717721258 +6.991660107 129.422897316 6.450197723 0.168041113 0.001486044 0.732856198 -0.000000780 0.000021535 -0.014550409 11.822340287 +7.021180805 129.204474565 6.519972816 0.170190902 0.001218346 0.695673239 -0.000000359 0.000014350 -0.009779347 11.756017654 +7.035735199 126.689056881 6.480296206 0.175800833 -0.003296433 0.705186136 0.000006444 -0.000038410 0.025441185 11.817567819 +7.001680404 125.578618507 6.500921210 0.179289702 -0.005613482 0.714615540 0.000009931 -0.000036371 0.024064555 11.838284409 +7.016994184 125.558741642 6.551048383 0.181175525 0.001828381 0.748686785 -0.000001192 0.000007347 -0.005326924 11.911606046 +7.084863495 125.611613552 6.549973623 0.182904477 0.002088146 0.719347562 -0.000001555 0.000006498 -0.004822991 11.837485027 +7.085139036 125.511108981 6.562904818 0.184882680 0.001538186 0.750577605 -0.000000707 0.000007278 -0.005099834 11.960164422 +7.060585205 125.428402614 6.610946289 0.186811041 0.001596798 0.720774081 -0.000000809 0.000006231 -0.004507176 11.955498773 +7.107847731 125.453483941 6.594313654 0.188608764 0.001362867 0.723200054 -0.000000481 0.000004172 -0.003093446 11.919884554 +7.150130231 125.483654130 6.630997446 0.190384206 0.001748643 0.765053820 -0.000001060 0.000008021 -0.005561832 12.004731306 +7.132515231 125.482713795 6.637598150 0.192198746 0.001662321 0.766355253 -0.000000906 0.000010381 -0.007052790 12.022502991 +7.142570125 125.402467353 6.642606179 0.194143965 0.001686804 0.754010838 -0.000000958 0.000008321 -0.005756835 12.054520616 +7.155002438 125.283956007 6.694894597 0.196177572 0.001920876 0.750606542 -0.000001256 0.000004256 -0.002975521 12.101886186 +7.169096557 125.118692963 6.693735064 0.198219695 0.001662539 0.746605917 -0.000000935 0.000002368 -0.001513038 12.108871280 +7.197353738 123.134755232 6.676700541 0.202989162 -0.002818182 0.770422606 0.000005669 -0.000030837 0.021057470 12.164732463 +7.227952676 122.317684690 6.706054113 0.206022514 -0.002905867 0.774518144 0.000005849 -0.000033288 0.022787553 12.216281205 +7.222492398 122.530288349 6.715991655 0.207557896 0.001339009 0.740045905 -0.000000327 0.000006334 -0.004444095 12.224515638 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 +0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 diff --git a/cmos0/kc.txt b/cmos0/kc.txt new file mode 100644 index 0000000..add16c9 --- /dev/null +++ b/cmos0/kc.txt @@ -0,0 +1,5 @@ + -1.2009005e-01 + 1.1928703e-01 + 9.6197371e-05 + -1.4896083e-04 + 0.0000000e+00 diff --git a/include/core/PointCloudProcessor.h b/include/core/PointCloudProcessor.h index 22d715e..77ec24c 100644 --- a/include/core/PointCloudProcessor.h +++ b/include/core/PointCloudProcessor.h @@ -1,8 +1,10 @@ -#ifndef POINTCLOUDPROCESSOR_H +#ifndef POINTCLOUDPROCESSOR_H #define POINTCLOUDPROCESSOR_H #include #include +#include +#include #include #include #include @@ -15,44 +17,38 @@ public: explicit PointCloudProcessor(QObject *parent = nullptr); ~PointCloudProcessor(); - // 初始化OpenCL bool initializeOpenCL(); - - // 设置相机内参 void setCameraIntrinsics(float fx, float fy, float cx, float cy); - - // 设置Z缩放因子 void setZScaleFactor(float scale); - // 将深度数据转换为点云(使用OpenCL GPU加速) void processDepthData(const QByteArray &depthData, uint32_t blockId); - - // 处理已经计算好的点云数据(x,y,z格式) void processPointCloudData(const QByteArray &cloudData, uint32_t blockId); + void setDenoiseEnabled(bool enabled); + void setDenoiseNeighborSupport(int minNeighbors); + void setDenoiseLowTailPermille(int permille); + void setDenoiseDepthBandPermille(int permille); + signals: void pointCloudReady(pcl::PointCloud::Ptr cloud, uint32_t blockId); void errorOccurred(const QString &error); private: - // 清理OpenCL资源 + pcl::PointCloud::Ptr applyDenoise(const pcl::PointCloud::Ptr &input); + void loadLowerCalibration(); void cleanupOpenCL(); - // 相机内参 float m_fx; float m_fy; float m_cx; float m_cy; - // Z缩放因子 float m_zScale; - // 图像尺寸 int m_imageWidth; int m_imageHeight; int m_totalPoints; - // OpenCL资源 cl_platform_id m_platform; cl_device_id m_device; cl_context m_context; @@ -62,6 +58,30 @@ private: cl_mem m_depthBuffer; cl_mem m_xyzBuffer; bool m_clInitialized; + + std::atomic_bool m_denoiseEnabled; + float m_voxelLeafSize; + std::atomic_int m_denoiseNeighborSupport; + std::atomic_int m_denoiseLowTailPermille; + std::atomic_int m_denoiseDepthBandPermille; + + // Calibration params aligned with lower-machine model + float m_k1; + float m_k2; + float m_p1; + float m_p2; + float m_p5; + float m_p6; + float m_p7; + float m_p8; + bool m_hasLowerCalibration; + + // Temporal stabilizers for denoise to reduce frame-to-frame flicker. + std::mutex m_denoiseStateMutex; + bool m_hasAnchorMeanZ; + float m_anchorMeanZFiltered; + bool m_hasLowCutZ; + float m_lowCutZFiltered; }; #endif // POINTCLOUDPROCESSOR_H diff --git a/src/core/PointCloudProcessor.cpp b/src/core/PointCloudProcessor.cpp index 54ce3cd..3da968d 100644 --- a/src/core/PointCloudProcessor.cpp +++ b/src/core/PointCloudProcessor.cpp @@ -1,12 +1,93 @@ #include "core/PointCloudProcessor.h" #include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif +namespace { +struct VoxelKey { + int x; + int y; + int z; + + bool operator==(const VoxelKey &other) const noexcept + { + return x == other.x && y == other.y && z == other.z; + } +}; + +struct VoxelKeyHash { + size_t operator()(const VoxelKey &k) const noexcept + { + // FNV-1a hash for 3D integer voxel index. + uint64_t h = 1469598103934665603ull; + auto mix = [&h](uint64_t v) { + h ^= v; + h *= 1099511628211ull; + }; + mix(static_cast(k.x)); + mix(static_cast(k.y)); + mix(static_cast(k.z)); + return static_cast(h); + } +}; + +struct VoxelAccum { + float sumX = 0.0f; + float sumY = 0.0f; + float sumZ = 0.0f; + uint32_t count = 0; +}; + +constexpr int kNeighborOffsets[26][3] = { + {-1, -1, -1}, {0, -1, -1}, {1, -1, -1}, + {-1, 0, -1}, {0, 0, -1}, {1, 0, -1}, + {-1, 1, -1}, {0, 1, -1}, {1, 1, -1}, + {-1, -1, 0}, {0, -1, 0}, {1, -1, 0}, + {-1, 0, 0}, {1, 0, 0}, + {-1, 1, 0}, {0, 1, 0}, {1, 1, 0}, + {-1, -1, 1}, {0, -1, 1}, {1, -1, 1}, + {-1, 0, 1}, {0, 0, 1}, {1, 0, 1}, + {-1, 1, 1}, {0, 1, 1}, {1, 1, 1} +}; + +bool readFloatFile(const QString &path, std::vector &out) +{ + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + return false; + } + + const QByteArray raw = file.readAll(); + const QString text = QString::fromUtf8(raw); + const QStringList tokens = text.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); + out.clear(); + out.reserve(tokens.size()); + + for (const QString &token : tokens) { + bool ok = false; + float value = token.toFloat(&ok); + if (ok) { + out.push_back(value); + } + } + + return !out.empty(); +} +} // namespace + PointCloudProcessor::PointCloudProcessor(QObject *parent) : QObject(parent) , m_fx(1432.8957f) @@ -26,7 +107,26 @@ PointCloudProcessor::PointCloudProcessor(QObject *parent) , m_depthBuffer(nullptr) , m_xyzBuffer(nullptr) , m_clInitialized(false) + , m_denoiseEnabled(false) + , m_voxelLeafSize(2.5f) + , m_denoiseNeighborSupport(6) + , m_denoiseLowTailPermille(15) + , m_denoiseDepthBandPermille(80) + , m_k1(0.0f) + , m_k2(0.0f) + , m_p1(0.0f) + , m_p2(0.0f) + , m_p5(1.0f / 1432.8957f) + , m_p6(-637.5117f / 1432.8957f) + , m_p7(1.0f / 1432.6590f) + , m_p8(-521.8720f / 1432.6590f) + , m_hasLowerCalibration(false) + , m_hasAnchorMeanZ(false) + , m_anchorMeanZFiltered(0.0f) + , m_hasLowCutZ(false) + , m_lowCutZFiltered(0.0f) { + loadLowerCalibration(); } PointCloudProcessor::~PointCloudProcessor() @@ -40,6 +140,14 @@ void PointCloudProcessor::setCameraIntrinsics(float fx, float fy, float cx, floa m_fy = fy; m_cx = cx; m_cy = cy; + + // Keep lower-machine style projection terms in sync when intrinsics are changed at runtime. + if (m_fx != 0.0f && m_fy != 0.0f) { + m_p5 = 1.0f / m_fx; + m_p6 = -m_cx / m_fx; + m_p7 = 1.0f / m_fy; + m_p8 = -m_cy / m_fy; + } } void PointCloudProcessor::setZScaleFactor(float scale) @@ -47,6 +155,557 @@ void PointCloudProcessor::setZScaleFactor(float scale) m_zScale = scale; } +void PointCloudProcessor::loadLowerCalibration() +{ + const QString appDir = QCoreApplication::applicationDirPath(); + QStringList candidates; + candidates + << QDir::current().filePath("cmos0") + << QDir(appDir).filePath("cmos0") + << QDir(appDir).filePath("../cmos0") + << QDir(appDir).filePath("../../cmos0"); + + for (const QString &dirPath : candidates) { + const QString kcPath = QDir(dirPath).filePath("kc.txt"); + const QString kkPath = QDir(dirPath).filePath("KK.txt"); + if (!QFile::exists(kcPath) || !QFile::exists(kkPath)) { + continue; + } + + std::vector kcVals; + std::vector kkVals; + if (!readFloatFile(kcPath, kcVals) || !readFloatFile(kkPath, kkVals)) { + continue; + } + if (kcVals.size() < 4 || kkVals.size() < 6) { + continue; + } + + const float fx = kkVals[0]; + const float cx = kkVals[2]; + const float fy = kkVals[4]; + const float cy = kkVals[5]; + if (fx == 0.0f || fy == 0.0f) { + continue; + } + + m_k1 = kcVals[0]; + m_k2 = kcVals[1]; + m_p1 = kcVals[2]; + m_p2 = kcVals[3]; + + m_fx = fx; + m_fy = fy; + m_cx = cx; + m_cy = cy; + m_p5 = 1.0f / fx; + m_p6 = -cx / fx; + m_p7 = 1.0f / fy; + m_p8 = -cy / fy; + m_hasLowerCalibration = true; + + qDebug() << "[PointCloud] Loaded lower calibration from" << dirPath + << "kc size:" << static_cast(kcVals.size()) + << "KK size:" << static_cast(kkVals.size()); + return; + } + + m_hasLowerCalibration = false; + qDebug() << "[PointCloud] lower calibration txt not found, using fallback intrinsics"; +} + +void PointCloudProcessor::setDenoiseEnabled(bool enabled) +{ + m_denoiseEnabled.store(enabled, std::memory_order_relaxed); +} + +void PointCloudProcessor::setDenoiseNeighborSupport(int minNeighbors) +{ + m_denoiseNeighborSupport.store(std::clamp(minNeighbors, 3, 12), std::memory_order_relaxed); +} + +void PointCloudProcessor::setDenoiseLowTailPermille(int permille) +{ + m_denoiseLowTailPermille.store(std::clamp(permille, 5, 50), std::memory_order_relaxed); +} + +void PointCloudProcessor::setDenoiseDepthBandPermille(int permille) +{ + m_denoiseDepthBandPermille.store(std::clamp(permille, 40, 180), std::memory_order_relaxed); +} + +pcl::PointCloud::Ptr PointCloudProcessor::applyDenoise( + const pcl::PointCloud::Ptr &input) +{ + if (!input || input->empty()) { + return input; + } + + const size_t total = input->points.size(); + const int width = static_cast(input->width); + const int height = static_cast(input->height); + const int supportMinNeighbors = m_denoiseNeighborSupport.load(std::memory_order_relaxed); + const int lowTailPermille = m_denoiseLowTailPermille.load(std::memory_order_relaxed); + const int depthBandPermille = m_denoiseDepthBandPermille.load(std::memory_order_relaxed); + + bool hasPrevAnchor = false; + float prevAnchorMeanZ = 0.0f; + bool hasPrevLowCut = false; + float prevLowCutZ = 0.0f; + { + std::lock_guard lock(m_denoiseStateMutex); + hasPrevAnchor = m_hasAnchorMeanZ; + prevAnchorMeanZ = m_anchorMeanZFiltered; + hasPrevLowCut = m_hasLowCutZ; + prevLowCutZ = m_lowCutZFiltered; + } + bool anchorUpdated = false; + float anchorToStore = 0.0f; + bool lowCutUpdated = false; + float lowCutToStore = 0.0f; + + // Fallback for unorganized clouds: only remove invalid points. + if (width <= 1 || height <= 1 || static_cast(width) * static_cast(height) != total) { + pcl::PointCloud::Ptr validOnly(new pcl::PointCloud()); + validOnly->points.reserve(total); + for (const auto &p : input->points) { + if (pcl::isFinite(p) && p.z > 0.0f) { + validOnly->points.push_back(p); + } + } + if (validOnly->points.empty()) { + return input; + } + validOnly->width = static_cast(validOnly->points.size()); + validOnly->height = 1; + validOnly->is_dense = true; + return validOnly; + } + + const auto idx = [width](int r, int c) -> int { return r * width + c; }; + std::vector validMask(total, 0); + + float minZ = std::numeric_limits::max(); + float maxZ = std::numeric_limits::lowest(); + int validCount = 0; + for (size_t i = 0; i < total; ++i) { + const auto &p = input->points[i]; + if (pcl::isFinite(p) && p.z > 0.0f) { + validMask[i] = 1; + ++validCount; + if (p.z < minZ) minZ = p.z; + if (p.z > maxZ) maxZ = p.z; + } + } + + if (validCount < 1200) { + return input; + } + + // Pass 0: adaptive conditional depth gate (inspired by ConditionalRemoval/CropBox idea). + // Use center ROI median depth as reference, then keep a dynamic depth band. + const float spanZ = std::max(0.0f, maxZ - minZ); + int gatedCount = validCount; + if (spanZ > 1e-3f) { + const int r0 = static_cast(height * 0.35f); + const int r1 = static_cast(height * 0.75f); + const int c0 = static_cast(width * 0.35f); + const int c1 = static_cast(width * 0.65f); + + std::vector centerZ; + centerZ.reserve(static_cast((r1 - r0) * (c1 - c0))); + for (int r = r0; r < r1; ++r) { + for (int c = c0; c < c1; ++c) { + const int i = idx(r, c); + if (validMask[i]) { + centerZ.push_back(input->points[i].z); + } + } + } + + if (centerZ.size() > 800) { + const size_t mid = centerZ.size() / 2; + std::nth_element(centerZ.begin(), centerZ.begin() + mid, centerZ.end()); + const float zRef = centerZ[mid]; + + const float zNear = std::max(minZ, zRef - std::max(80.0f, spanZ * 0.08f)); + const float zFar = std::min(maxZ, zRef + std::max(250.0f, spanZ * 0.22f)); + + gatedCount = 0; + for (size_t i = 0; i < total; ++i) { + if (!validMask[i]) { + continue; + } + const float z = input->points[i].z; + if (z < zNear || z > zFar) { + validMask[i] = 0; + } else { + ++gatedCount; + } + } + + // If gate is too aggressive, rollback. + if (gatedCount < 2000) { + std::fill(validMask.begin(), validMask.end(), 0); + gatedCount = 0; + for (size_t i = 0; i < total; ++i) { + const auto &p = input->points[i]; + if (pcl::isFinite(p) && p.z > 0.0f) { + validMask[i] = 1; + ++gatedCount; + } + } + } + } + } + + // Pass 1: local depth-consistency support in 3x3 neighborhood. + // This suppresses thin ray artifacts while preserving contiguous surfaces. + std::vector supportMask(total, 0); + int supportCount = 0; + + for (int r = 2; r < height - 2; ++r) { + for (int c = 2; c < width - 2; ++c) { + const int center = idx(r, c); + if (!validMask[center]) { + continue; + } + + const float z = input->points[center].z; + const float dzThreshold = std::max(12.0f, z * 0.015f); + + int neighbors = 0; + for (int rr = -2; rr <= 2; ++rr) { + for (int cc = -2; cc <= 2; ++cc) { + if (rr == 0 && cc == 0) { + continue; + } + const int ni = idx(r + rr, c + cc); + if (!validMask[ni]) { + continue; + } + if (std::fabs(input->points[ni].z - z) <= dzThreshold) { + ++neighbors; + } + } + } + + if (neighbors >= supportMinNeighbors) { + supportMask[center] = 1; + ++supportCount; + } + } + } + + if (supportCount < 1500) { + return input; + } + + // Pass 1.5: one morphology-like cleanup to remove sparse remnants. + std::vector cleanMask = supportMask; + int cleanCount = 0; + for (int r = 1; r < height - 1; ++r) { + for (int c = 1; c < width - 1; ++c) { + const int center = idx(r, c); + if (!supportMask[center]) { + continue; + } + int kept = 0; + for (int rr = -1; rr <= 1; ++rr) { + for (int cc = -1; cc <= 1; ++cc) { + if (rr == 0 && cc == 0) { + continue; + } + if (supportMask[idx(r + rr, c + cc)]) { + ++kept; + } + } + } + if (kept < 2) { + cleanMask[center] = 0; + } + if (cleanMask[center]) { + ++cleanCount; + } + } + } + if (cleanCount >= 1500) { + supportMask.swap(cleanMask); + supportCount = cleanCount; + } + + // Pass 2: clip the near-camera low-depth tail to suppress center-radiating streaks. + std::vector finalMask = supportMask; + if (spanZ > 1e-3f) { + constexpr int kBins = 256; + std::vector hist(kBins, 0); + for (size_t i = 0; i < total; ++i) { + if (!supportMask[i]) { + continue; + } + const float z = input->points[i].z; + int b = static_cast((z - minZ) / spanZ * static_cast(kBins - 1)); + b = std::clamp(b, 0, kBins - 1); + ++hist[b]; + } + + const int lowTailTarget = std::max(120, static_cast(supportCount * (static_cast(lowTailPermille) / 1000.0f))); + int accum = 0; + int lowBin = 0; + for (int b = 0; b < kBins; ++b) { + accum += hist[b]; + if (accum >= lowTailTarget) { + lowBin = b; + break; + } + } + const float rawLowCut = minZ + spanZ * (static_cast(lowBin) / static_cast(kBins - 1)); + float zLowCut = rawLowCut; + if (hasPrevLowCut) { + const float maxJump = std::max(120.0f, spanZ * 0.10f); + const float clamped = std::clamp(rawLowCut, prevLowCutZ - maxJump, prevLowCutZ + maxJump); + zLowCut = prevLowCutZ * 0.65f + clamped * 0.35f; + } + lowCutUpdated = true; + lowCutToStore = zLowCut; + + int finalCount = 0; + for (size_t i = 0; i < total; ++i) { + if (finalMask[i] && input->points[i].z < zLowCut) { + finalMask[i] = 0; + } + if (finalMask[i]) { + ++finalCount; + } + } + + if (finalCount < 1200) { + finalMask = supportMask; + } + } + + // Pass 2.5: 2D connected components + foreground-priority keep. + // This suppresses surrounding residual blobs while preserving the near main object. + struct ComponentStat { + std::vector pixels; + int area = 0; + float zSum = 0.0f; + int centerOverlap = 0; + }; + + const int centerR0 = static_cast(height * 0.35f); + const int centerR1 = static_cast(height * 0.75f); + const int centerC0 = static_cast(width * 0.35f); + const int centerC1 = static_cast(width * 0.65f); + + std::vector visited(total, 0); + std::vector comps; + comps.reserve(32); + + std::vector queue; + queue.reserve(4096); + constexpr int cdr[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; + constexpr int cdc[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; + + for (int r = 0; r < height; ++r) { + for (int c = 0; c < width; ++c) { + const int seed = idx(r, c); + if (!finalMask[seed] || visited[seed]) { + continue; + } + + ComponentStat comp; + queue.clear(); + queue.push_back(seed); + visited[seed] = 1; + + for (size_t head = 0; head < queue.size(); ++head) { + const int cur = queue[head]; + const int rr = cur / width; + const int cc = cur % width; + + comp.pixels.push_back(cur); + comp.area += 1; + comp.zSum += input->points[cur].z; + if (rr >= centerR0 && rr < centerR1 && cc >= centerC0 && cc < centerC1) { + comp.centerOverlap += 1; + } + + for (int k = 0; k < 8; ++k) { + const int nr = rr + cdr[k]; + const int nc = cc + cdc[k]; + if (nr < 0 || nr >= height || nc < 0 || nc >= width) { + continue; + } + const int ni = idx(nr, nc); + if (!finalMask[ni] || visited[ni]) { + continue; + } + visited[ni] = 1; + queue.push_back(ni); + } + } + + comps.push_back(std::move(comp)); + } + } + + if (!comps.empty()) { + int anchor = -1; + float anchorMeanZ = std::numeric_limits::max(); + int anchorArea = 0; + float bestScore = -std::numeric_limits::max(); + const float temporalBand = std::max(120.0f, spanZ * 0.10f); + + // Stable anchor selection with temporal bias to reduce frame-to-frame jumping. + for (int i = 0; i < static_cast(comps.size()); ++i) { + const auto &cp = comps[i]; + if (cp.area < 300) { + continue; + } + const float meanZ = cp.zSum / static_cast(cp.area); + float score = static_cast(cp.centerOverlap) * 6.0f + + static_cast(std::min(cp.area, 12000)) * 0.25f; + if (hasPrevAnchor) { + const float dz = std::fabs(meanZ - prevAnchorMeanZ); + score -= dz * 0.35f; + if (dz <= temporalBand) { + score += 1200.0f; + } + } + if (score > bestScore) { + bestScore = score; + anchor = i; + anchorMeanZ = meanZ; + anchorArea = cp.area; + } + } + + if (anchor >= 0) { + float stableAnchorMeanZ = anchorMeanZ; + if (hasPrevAnchor) { + const float maxJump = std::max(180.0f, spanZ * 0.15f); + const float clamped = std::clamp(anchorMeanZ, prevAnchorMeanZ - maxJump, prevAnchorMeanZ + maxJump); + stableAnchorMeanZ = prevAnchorMeanZ * 0.60f + clamped * 0.40f; + } + anchorUpdated = true; + anchorToStore = stableAnchorMeanZ; + + std::vector ccMask(total, 0); + int kept = 0; + // Make depth-band slider more perceptible: 40 -> tight (strong suppression), 180 -> loose. + const float bandT = std::clamp((static_cast(depthBandPermille) - 40.0f) / 140.0f, 0.0f, 1.0f); + const float zKeepBandFloor = 90.0f + 260.0f * bandT; + const float zKeepBandSpanFactor = 0.03f + 0.19f * bandT; + const float zKeepBandBase = std::max(zKeepBandFloor, spanZ * zKeepBandSpanFactor); + const float zKeepBand = hasPrevAnchor + ? (zKeepBandBase * (1.15f + 0.35f * bandT)) + : (zKeepBandBase * (1.00f + 0.25f * bandT)); + const float minKeepAreaRatio = 0.035f - 0.020f * bandT; + const int minKeepArea = std::max(60, static_cast(anchorArea * minKeepAreaRatio)); + + for (const auto &cp : comps) { + if (cp.area < minKeepArea) { + continue; + } + const float meanZ = cp.zSum / static_cast(cp.area); + const float overlapBonus = (cp.centerOverlap > 0) ? (zKeepBand * 0.45f) : 0.0f; + if (meanZ > stableAnchorMeanZ + zKeepBand + overlapBonus) { + continue; + } + for (int p : cp.pixels) { + ccMask[p] = 1; + ++kept; + } + } + + // Apply when preserving a reasonable part of support mask to avoid frame jumps. + const float minStableRatio = 0.18f - 0.10f * bandT; + const int minStableKeep = std::max(1000, static_cast(supportCount * minStableRatio)); + if (kept >= minStableKeep) { + // Soft fallback: keep previously accepted support points that are depth-consistent. + const float softKeepFar = stableAnchorMeanZ + zKeepBand * (1.20f + 1.60f * bandT); + for (size_t i = 0; i < total; ++i) { + if (finalMask[i] && !ccMask[i] && input->points[i].z <= softKeepFar) { + ccMask[i] = 1; + } + } + finalMask.swap(ccMask); + } + } + } + + // Pass 2.8: final spur cleanup to reduce radiating thin points. + { + std::vector pruned = finalMask; + int keptAfterPrune = 0; + const float bandT = std::clamp((static_cast(depthBandPermille) - 40.0f) / 140.0f, 0.0f, 1.0f); + const float nearRaySpanFactor = 0.10f - 0.06f * bandT; + const float nearRayOffset = std::max(70.0f, spanZ * nearRaySpanFactor); + const float nearRayGate = lowCutUpdated + ? (lowCutToStore + nearRayOffset) + : (minZ + spanZ * (0.22f - 0.10f * bandT)); + for (int r = 1; r < height - 1; ++r) { + for (int c = 1; c < width - 1; ++c) { + const int center = idx(r, c); + if (!finalMask[center]) { + continue; + } + int n = 0; + for (int rr = -1; rr <= 1; ++rr) { + for (int cc = -1; cc <= 1; ++cc) { + if (rr == 0 && cc == 0) { + continue; + } + if (finalMask[idx(r + rr, c + cc)]) { + ++n; + } + } + } + if (n < 2 && input->points[center].z < nearRayGate) { + pruned[center] = 0; + } + if (pruned[center]) { + ++keptAfterPrune; + } + } + } + if (keptAfterPrune >= 1200) { + finalMask.swap(pruned); + } + } + + pcl::PointCloud::Ptr denoised(new pcl::PointCloud()); + denoised->points.reserve(static_cast(supportCount)); + for (size_t i = 0; i < total; ++i) { + if (finalMask[i]) { + denoised->points.push_back(input->points[i]); + } + } + + if (denoised->points.empty()) { + return input; + } + + denoised->width = static_cast(denoised->points.size()); + denoised->height = 1; + denoised->is_dense = true; + + { + std::lock_guard lock(m_denoiseStateMutex); + if (anchorUpdated) { + m_anchorMeanZFiltered = anchorToStore; + m_hasAnchorMeanZ = true; + } + if (lowCutUpdated) { + m_lowCutZFiltered = lowCutToStore; + m_hasLowCutZ = true; + } + } + + return denoised; +} + bool PointCloudProcessor::initializeOpenCL() { if (m_clInitialized) { @@ -247,6 +906,9 @@ void PointCloudProcessor::processDepthData(const QByteArray &depthData, uint32_t // 注释掉频繁的日志输出 // qDebug() << "[PointCloud] Block" << blockId << "processed successfully"; + if (m_denoiseEnabled.load(std::memory_order_relaxed)) { + cloud = applyDenoise(cloud); + } emit pointCloudReady(cloud, blockId); } @@ -282,8 +944,9 @@ void PointCloudProcessor::processPointCloudData(const QByteArray &cloudData, uin // 从int16_t数组读取点云数据 const int16_t* cloudShort = reinterpret_cast(cloudData.constData()); - float inv_fx = 1.0f / m_fx; - float inv_fy = 1.0f / m_fy; + // 与下位机 gpu_calculate_pointcloud.cl 对齐的参数: + // u = p5 * (j - 0.5) + p6, v = p7 * (i + 1) + p8 + // (k1,k2,p1,p2,p5,p6,p7,p8) 由 cmos0/kc.txt 与 cmos0/KK.txt 加载。 if (isZOnly) { // Z-only格式:标准针孔模型反投影 @@ -292,8 +955,21 @@ void PointCloudProcessor::processPointCloudData(const QByteArray &cloudData, uin int col = i % m_imageWidth; float z = static_cast(cloudShort[i]) * m_zScale; - cloud->points[i].x = (col - m_cx) * z * inv_fx; - cloud->points[i].y = (row - m_cy) * z * inv_fy; + + // 旧公式保留,便于快速回退: + // cloud->points[i].x = (col - m_cx) * z * inv_fx; + // cloud->points[i].y = (row - m_cy) * z * inv_fy; + + // 下位机同款:先求(u,v)并做畸变修正得到(unc,vnc),再乘z得到(x,y) + float u = m_p5 * (static_cast(col) - 0.5f) + m_p6; + float v = m_p7 * (static_cast(row) + 1.0f) + m_p8; + float r = u * u + v * v; + float temp3 = 1.0f / (1.0f + m_k1 * r + m_k2 * r * r); + float unc = temp3 * (u - 2.0f * m_p1 * u * v - m_p2 * (r + 2.0f * u * u)); + float vnc = temp3 * (v - m_p1 * (r + 2.0f * v * v) - 2.0f * m_p2 * u * v); + + cloud->points[i].x = unc * z; + cloud->points[i].y = vnc * z; cloud->points[i].z = z; } } else { @@ -303,14 +979,30 @@ void PointCloudProcessor::processPointCloudData(const QByteArray &cloudData, uin int col = i % m_imageWidth; float z = static_cast(cloudShort[i * 3 + 2]) * m_zScale; - cloud->points[i].x = (col - m_cx) * z * inv_fx; - cloud->points[i].y = (row - m_cy) * z * inv_fy; + + // 旧公式保留,便于快速回退: + // cloud->points[i].x = (col - m_cx) * z * inv_fx; + // cloud->points[i].y = (row - m_cy) * z * inv_fy; + + // 下位机同款:先求(u,v)并做畸变修正得到(unc,vnc),再乘z得到(x,y) + float u = m_p5 * (static_cast(col) - 0.5f) + m_p6; + float v = m_p7 * (static_cast(row) + 1.0f) + m_p8; + float r = u * u + v * v; + float temp3 = 1.0f / (1.0f + m_k1 * r + m_k2 * r * r); + float unc = temp3 * (u - 2.0f * m_p1 * u * v - m_p2 * (r + 2.0f * u * u)); + float vnc = temp3 * (v - m_p1 * (r + 2.0f * v * v) - 2.0f * m_p2 * u * v); + + cloud->points[i].x = unc * z; + cloud->points[i].y = vnc * z; cloud->points[i].z = z; } } // qDebug() << "[PointCloud] Block" << blockId << "processed successfully," // << m_totalPoints << "points"; + if (m_denoiseEnabled.load(std::memory_order_relaxed)) { + cloud = applyDenoise(cloud); + } emit pointCloudReady(cloud, blockId); } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index a8b0ffe..4fbc5e5 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -63,11 +63,19 @@ MainWindow::MainWindow(QWidget *parent) , m_rgbFrameCount(0) , m_totalRgbFrameCount(0) , m_currentRgbFps(0.0) + , m_leftIrDisplayRangeInited(false) + , m_leftIrDisplayMin(0.0f) + , m_leftIrDisplayMax(0.0f) + , m_rightIrDisplayRangeInited(false) + , m_rightIrDisplayMin(0.0f) + , m_rightIrDisplayMax(0.0f) , m_rgbSkipCounter(0) { m_rgbProcessing.storeRelaxed(0); // 初始化RGB处理标志 m_leftIRProcessing.storeRelaxed(0); // 初始化左红外处理标志 m_rightIRProcessing.storeRelaxed(0); // 初始化右红外处理标志 + m_pointCloudProcessing.storeRelaxed(0); // 初始化点云处理标志 + m_pointCloudDropCounter.storeRelaxed(0); // 初始化点云丢帧计数 m_leftIREnabled.storeRelaxed(0); // 初始化左红外启用标志(默认禁用) m_rightIREnabled.storeRelaxed(0); // 初始化右红外启用标志(默认禁用) m_rgbEnabled.storeRelaxed(0); // 初始化RGB启用标志(默认禁用) @@ -232,6 +240,14 @@ void MainWindow::setupUI() m_pointCloudColorToggle->setStyleSheet(toggleStyle); toolBarLayout->addWidget(m_pointCloudColorToggle); + m_pointCloudDenoiseToggle = new QPushButton("点云去噪", topToolBar); + m_pointCloudDenoiseToggle->setCheckable(true); + m_pointCloudDenoiseToggle->setChecked(false); + m_pointCloudDenoiseToggle->setFixedHeight(32); + m_pointCloudDenoiseToggle->setToolTip("开启/关闭点云去噪"); + m_pointCloudDenoiseToggle->setStyleSheet(toggleStyle); + toolBarLayout->addWidget(m_pointCloudDenoiseToggle); + toolBarLayout->addSpacing(20); // 单目/双目模式切换按钮 @@ -433,6 +449,53 @@ void MainWindow::setupUI() m_pointCloudFormatCombo->setCurrentIndex(2); captureLayout->addWidget(m_pointCloudFormatCombo); + QGroupBox *denoiseParamGroup = new QGroupBox("点云去噪参数", captureGroup); + QVBoxLayout *denoiseParamLayout = new QVBoxLayout(denoiseParamGroup); + + QLabel *supportLabel = new QLabel("邻域支持阈值:", denoiseParamGroup); + denoiseParamLayout->addWidget(supportLabel); + QHBoxLayout *supportLayout = new QHBoxLayout(); + m_denoiseSupportSlider = new QSlider(Qt::Horizontal, denoiseParamGroup); + m_denoiseSupportSlider->setRange(3, 12); + m_denoiseSupportSlider->setValue(6); + m_denoiseSupportSpinBox = new QSpinBox(denoiseParamGroup); + m_denoiseSupportSpinBox->setRange(3, 12); + m_denoiseSupportSpinBox->setValue(6); + m_denoiseSupportSpinBox->setMinimumWidth(72); + supportLayout->addWidget(m_denoiseSupportSlider, 3); + supportLayout->addWidget(m_denoiseSupportSpinBox, 1); + denoiseParamLayout->addLayout(supportLayout); + + QLabel *tailLabel = new QLabel("射线裁剪强度 (‰):", denoiseParamGroup); + denoiseParamLayout->addWidget(tailLabel); + QHBoxLayout *tailLayout = new QHBoxLayout(); + m_denoiseTailSlider = new QSlider(Qt::Horizontal, denoiseParamGroup); + m_denoiseTailSlider->setRange(5, 50); + m_denoiseTailSlider->setValue(15); + m_denoiseTailSpinBox = new QSpinBox(denoiseParamGroup); + m_denoiseTailSpinBox->setRange(5, 50); + m_denoiseTailSpinBox->setValue(15); + m_denoiseTailSpinBox->setMinimumWidth(72); + tailLayout->addWidget(m_denoiseTailSlider, 3); + tailLayout->addWidget(m_denoiseTailSpinBox, 1); + denoiseParamLayout->addLayout(tailLayout); + + QLabel *bandLabel = new QLabel("周边抑制带宽 (‰):", denoiseParamGroup); + denoiseParamLayout->addWidget(bandLabel); + QHBoxLayout *bandLayout = new QHBoxLayout(); + m_denoiseBandSlider = new QSlider(Qt::Horizontal, denoiseParamGroup); + m_denoiseBandSlider->setRange(40, 180); + m_denoiseBandSlider->setValue(80); + m_denoiseBandSpinBox = new QSpinBox(denoiseParamGroup); + m_denoiseBandSpinBox->setRange(40, 180); + m_denoiseBandSpinBox->setValue(80); + m_denoiseBandSpinBox->setMinimumWidth(72); + bandLayout->addWidget(m_denoiseBandSlider, 3); + bandLayout->addWidget(m_denoiseBandSpinBox, 1); + denoiseParamLayout->addLayout(bandLayout); + + captureLayout->addWidget(denoiseParamGroup); + exposureCaptureLayout->addWidget(captureGroup); exposureCaptureLayout->addStretch(); @@ -692,6 +755,7 @@ void MainWindow::setupConnections() connect(m_leftIRToggle, &QPushButton::toggled, this, [this](bool checked) { if(checked) { m_leftIREnabled.storeRelaxed(1); // 标记启用 + m_leftIrDisplayRangeInited = false; // 重新开启时重置显示动态范围 m_networkManager->sendEnableLeftIR(); qDebug() << "启用左红外传输"; } else { @@ -709,6 +773,7 @@ void MainWindow::setupConnections() connect(m_rightIRToggle, &QPushButton::toggled, this, [this](bool checked) { if(checked) { m_rightIREnabled.storeRelaxed(1); // 标记启用 + m_rightIrDisplayRangeInited = false; // 重新开启时重置显示动态范围 m_networkManager->sendEnableRightIR(); qDebug() << "启用右红外传输"; } else { @@ -748,6 +813,71 @@ void MainWindow::setupConnections() } }); + connect(m_pointCloudDenoiseToggle, &QPushButton::toggled, this, [this](bool checked) { + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseEnabled(checked); + addLog(QString("点云去噪: %1").arg(checked ? "开启" : "关闭"), "INFO"); + qDebug() << "[MainWindow] Point cloud denoise:" << (checked ? "ON" : "OFF"); + } + }); + + connect(m_denoiseSupportSlider, &QSlider::valueChanged, this, [this](int value) { + m_denoiseSupportSpinBox->blockSignals(true); + m_denoiseSupportSpinBox->setValue(value); + m_denoiseSupportSpinBox->blockSignals(false); + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseNeighborSupport(value); + } + }); + connect(m_denoiseSupportSpinBox, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { + m_denoiseSupportSlider->blockSignals(true); + m_denoiseSupportSlider->setValue(value); + m_denoiseSupportSlider->blockSignals(false); + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseNeighborSupport(value); + } + }); + + connect(m_denoiseTailSlider, &QSlider::valueChanged, this, [this](int value) { + m_denoiseTailSpinBox->blockSignals(true); + m_denoiseTailSpinBox->setValue(value); + m_denoiseTailSpinBox->blockSignals(false); + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseLowTailPermille(value); + } + }); + connect(m_denoiseTailSpinBox, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { + m_denoiseTailSlider->blockSignals(true); + m_denoiseTailSlider->setValue(value); + m_denoiseTailSlider->blockSignals(false); + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseLowTailPermille(value); + } + }); + + connect(m_denoiseBandSlider, &QSlider::valueChanged, this, [this](int value) { + m_denoiseBandSpinBox->blockSignals(true); + m_denoiseBandSpinBox->setValue(value); + m_denoiseBandSpinBox->blockSignals(false); + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseDepthBandPermille(value); + } + }); + connect(m_denoiseBandSpinBox, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { + m_denoiseBandSlider->blockSignals(true); + m_denoiseBandSlider->setValue(value); + m_denoiseBandSlider->blockSignals(false); + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseDepthBandPermille(value); + } + }); + + if(m_pointCloudProcessor) { + m_pointCloudProcessor->setDenoiseNeighborSupport(m_denoiseSupportSlider->value()); + m_pointCloudProcessor->setDenoiseLowTailPermille(m_denoiseTailSlider->value()); + m_pointCloudProcessor->setDenoiseDepthBandPermille(m_denoiseBandSlider->value()); + } + // 单目/双目模式切换按钮连接 connect(m_monocularBtn, &QPushButton::clicked, this, [this]() { m_monocularBtn->setChecked(true); @@ -1048,122 +1178,148 @@ void MainWindow::onLeftImageReceived(const QByteArray &jpegData, uint32_t blockI // 使用后台线程处理红外数据,避免阻塞UI if(m_leftImageDisplay && jpegData.size() > 0) { - // 检查数据大小:8位下采样(612x512)或16位原始(1224x1024) - size_t size8bit = 612 * 512; - size_t size16bit = 1224 * 1024 * sizeof(uint16_t); - - if(jpegData.size() == size8bit) { - // 8位下采样格式:直接显示 - QByteArray dataCopy = jpegData; - QtConcurrent::run([this, dataCopy]() { - try { - QImage image(reinterpret_cast(dataCopy.constData()), - 612, 512, 612, QImage::Format_Grayscale8); - QImage imageCopy = image.copy(); - - QMetaObject::invokeMethod(this, [this, imageCopy]() { - if(m_leftImageDisplay) { - QPixmap pixmap = QPixmap::fromImage(imageCopy); - m_leftImageDisplay->setPixmap(pixmap.scaled( - m_leftImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); - } - }, Qt::QueuedConnection); - } catch (const std::exception &e) { - qDebug() << "[MainWindow] ERROR: Left IR 8bit processing exception:" << e.what(); - } - }); - } else if(jpegData.size() == size16bit) { - // 16位原始格式:需要归一化处理 - QByteArray dataCopy = jpegData; - - // 在后台线程处理 - QtConcurrent::run([this, dataCopy]() { - try { - const uint16_t* src = reinterpret_cast(dataCopy.constData()); - - // 方案2:快速百分位数估算(无需排序,采样估算) - // 优点:适应不同环境,画面对比度好,速度快10倍以上 - uint16_t minVal = 65535, maxVal = 0; - - // 第一遍:快速扫描找到粗略范围(每隔8个像素采样) - for (int i = 0; i < 1224 * 1024; i += 8) { - uint16_t val = src[i]; - if(val > 0) { - if(val < minVal) minVal = val; - if(val > maxVal) maxVal = val; - } - } - - // 第二遍:使用直方图统计精确百分位数(避免排序) - if(maxVal > minVal) { - const int histSize = 256; - int histogram[histSize] = {0}; - float binWidth = (maxVal - minVal) / (float)histSize; - - // 构建直方图 - for (int i = 0; i < 1224 * 1024; i++) { - if(src[i] > 0) { - int bin = (src[i] - minVal) / binWidth; - if(bin >= histSize) bin = histSize - 1; - histogram[bin]++; - } - } - - // 计算1%和99%百分位数 - int totalPixels = 0; - for (int i = 0; i < histSize; i++) totalPixels += histogram[i]; - - int thresh_1 = totalPixels * 0.01; - int thresh_99 = totalPixels * 0.99; - - int cumsum = 0; - for (int i = 0; i < histSize; i++) { - cumsum += histogram[i]; - if(cumsum >= thresh_1 && minVal == 65535) { - minVal = minVal + i * binWidth; - } - if(cumsum >= thresh_99) { - maxVal = minVal + i * binWidth; - break; - } - } - } - - // 创建8位图像并归一化 - QImage image(1224, 1024, QImage::Format_Grayscale8); - uint8_t* dst = image.bits(); - float scale = (maxVal > minVal) ? (255.0f / (maxVal - minVal)) : 0.0f; - - for (int i = 0; i < 1224 * 1024; i++) { - if(src[i] == 0) { - dst[i] = 0; - } else if(src[i] <= minVal) { - dst[i] = 0; - } else if(src[i] >= maxVal) { - dst[i] = 255; - } else { - dst[i] = static_cast((src[i] - minVal) * scale); - } - } - - QImage imageCopy = image.copy(); - - // 在主线程更新UI - QMetaObject::invokeMethod(this, [this, imageCopy]() { - if(m_leftImageDisplay) { - QPixmap pixmap = QPixmap::fromImage(imageCopy); - m_leftImageDisplay->setPixmap(pixmap.scaled( - m_leftImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); - } - }, Qt::QueuedConnection); - } catch (const std::exception &e) { - qDebug() << "[MainWindow] ERROR: Left IR processing exception:" << e.what(); - } - }); - } else { + const size_t size8bit = 612 * 512; + const size_t size16bit = 1224 * 1024 * sizeof(uint16_t); + const bool is8bit = (jpegData.size() == size8bit); + const bool is16bit = (jpegData.size() == size16bit); + if(!is8bit && !is16bit) { qDebug() << "[MainWindow] ERROR: Left IR data size mismatch:" << jpegData.size() << "(expected 8bit:" << size8bit << "or 16bit:" << size16bit << ")"; + return; } + + // 忙时丢帧,避免线程池任务积压导致显示乱序和偶发闪烁。 + if(m_leftIRProcessing.loadAcquire() > 0) { + return; + } + m_leftIRProcessing.ref(); + + QByteArray dataCopy = jpegData; + QtConcurrent::run([this, dataCopy, is16bit]() { + try { + QImage imageCopy; + if(!is16bit) { + QImage image(reinterpret_cast(dataCopy.constData()), + 612, 512, 612, QImage::Format_Grayscale8); + imageCopy = image.copy(); + } else { + const uint16_t* src = reinterpret_cast(dataCopy.constData()); + constexpr int kWidth = 1224; + constexpr int kHeight = 1024; + constexpr int kPixels = kWidth * kHeight; + constexpr int kHistSize = 256; + + uint16_t sampleMin = 65535; + uint16_t sampleMax = 0; + for(int i = 0; i < kPixels; i += 8) { + const uint16_t val = src[i]; + if(val > 0) { + if(val < sampleMin) sampleMin = val; + if(val > sampleMax) sampleMax = val; + } + } + + float rangeMin = 0.0f; + float rangeMax = 65535.0f; + if(sampleMax > sampleMin) { + int histogram[kHistSize] = {0}; + const float binWidth = qMax(1.0f, (sampleMax - sampleMin) / static_cast(kHistSize)); + + int totalPixels = 0; + for(int i = 0; i < kPixels; ++i) { + const uint16_t val = src[i]; + if(val > 0) { + int bin = static_cast((val - sampleMin) / binWidth); + if(bin < 0) bin = 0; + if(bin >= kHistSize) bin = kHistSize - 1; + histogram[bin]++; + totalPixels++; + } + } + + if(totalPixels > 0) { + const int thresh1 = qMax(1, static_cast(totalPixels * 0.01f)); + const int thresh99 = qMax(thresh1 + 1, static_cast(totalPixels * 0.99f)); + + int p1Bin = 0; + int p99Bin = kHistSize - 1; + int cumsum = 0; + bool p1Found = false; + for(int i = 0; i < kHistSize; ++i) { + cumsum += histogram[i]; + if(!p1Found && cumsum >= thresh1) { + p1Bin = i; + p1Found = true; + } + if(cumsum >= thresh99) { + p99Bin = i; + break; + } + } + + float rawMin = sampleMin + p1Bin * binWidth; + float rawMax = sampleMin + p99Bin * binWidth; + if(rawMax <= rawMin + 1.0f) { + rawMax = rawMin + 1.0f; + } + + if(!m_leftIrDisplayRangeInited) { + m_leftIrDisplayMin = rawMin; + m_leftIrDisplayMax = rawMax; + m_leftIrDisplayRangeInited = true; + } else { + const float prevMin = m_leftIrDisplayMin; + const float prevMax = m_leftIrDisplayMax; + const float maxJump = qMax(120.0f, (rawMax - rawMin) * 0.25f); + const float minClamped = qBound(prevMin - maxJump, rawMin, prevMin + maxJump); + const float maxClamped = qBound(prevMax - maxJump, rawMax, prevMax + maxJump); + + m_leftIrDisplayMin = prevMin * 0.85f + minClamped * 0.15f; + m_leftIrDisplayMax = prevMax * 0.85f + maxClamped * 0.15f; + if(m_leftIrDisplayMax <= m_leftIrDisplayMin + 32.0f) { + m_leftIrDisplayMax = m_leftIrDisplayMin + 32.0f; + } + } + + rangeMin = m_leftIrDisplayMin; + rangeMax = m_leftIrDisplayMax; + } + } else if(m_leftIrDisplayRangeInited) { + rangeMin = m_leftIrDisplayMin; + rangeMax = m_leftIrDisplayMax; + } + + QImage image(kWidth, kHeight, QImage::Format_Grayscale8); + uint8_t* dst = image.bits(); + const float scale = (rangeMax > rangeMin) ? (255.0f / (rangeMax - rangeMin)) : 0.0f; + + for(int i = 0; i < kPixels; ++i) { + const uint16_t val = src[i]; + if(val == 0 || val <= rangeMin) { + dst[i] = 0; + } else if(val >= rangeMax) { + dst[i] = 255; + } else { + dst[i] = static_cast((val - rangeMin) * scale); + } + } + imageCopy = image.copy(); + } + + QMetaObject::invokeMethod(this, [this, imageCopy]() { + if(m_leftImageDisplay) { + QPixmap pixmap = QPixmap::fromImage(imageCopy); + m_leftImageDisplay->setPixmap(pixmap.scaled( + m_leftImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); + } + }, Qt::QueuedConnection); + } catch (const std::exception &e) { + qDebug() << "[MainWindow] ERROR: Left IR processing exception:" << e.what(); + } catch (...) { + qDebug() << "[MainWindow] ERROR: Left IR processing unknown exception"; + } + m_leftIRProcessing.deref(); + }); } } @@ -1195,122 +1351,148 @@ void MainWindow::onRightImageReceived(const QByteArray &jpegData, uint32_t block // 使用后台线程处理红外数据,避免阻塞UI if(m_rightImageDisplay && jpegData.size() > 0) { - // 检查数据大小:8位下采样(612x512)或16位原始(1224x1024) - size_t size8bit = 612 * 512; - size_t size16bit = 1224 * 1024 * sizeof(uint16_t); - - if(jpegData.size() == size8bit) { - // 8位下采样格式:直接显示 - QByteArray dataCopy = jpegData; - QtConcurrent::run([this, dataCopy]() { - try { - QImage image(reinterpret_cast(dataCopy.constData()), - 612, 512, 612, QImage::Format_Grayscale8); - QImage imageCopy = image.copy(); - - QMetaObject::invokeMethod(this, [this, imageCopy]() { - if(m_rightImageDisplay) { - QPixmap pixmap = QPixmap::fromImage(imageCopy); - m_rightImageDisplay->setPixmap(pixmap.scaled( - m_rightImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); - } - }, Qt::QueuedConnection); - } catch (const std::exception &e) { - qDebug() << "[MainWindow] ERROR: Right IR 8bit processing exception:" << e.what(); - } - }); - } else if(jpegData.size() == size16bit) { - // 16位原始格式:需要归一化处理 - QByteArray dataCopy = jpegData; - - // 在后台线程处理 - QtConcurrent::run([this, dataCopy]() { - try { - const uint16_t* src = reinterpret_cast(dataCopy.constData()); - - // 方案2:快速百分位数估算(无需排序,采样估算) - // 优点:适应不同环境,画面对比度好,速度快10倍以上 - uint16_t minVal = 65535, maxVal = 0; - - // 第一遍:快速扫描找到粗略范围(每隔8个像素采样) - for (int i = 0; i < 1224 * 1024; i += 8) { - uint16_t val = src[i]; - if(val > 0) { - if(val < minVal) minVal = val; - if(val > maxVal) maxVal = val; - } - } - - // 第二遍:使用直方图统计精确百分位数(避免排序) - if(maxVal > minVal) { - const int histSize = 256; - int histogram[histSize] = {0}; - float binWidth = (maxVal - minVal) / (float)histSize; - - // 构建直方图 - for (int i = 0; i < 1224 * 1024; i++) { - if(src[i] > 0) { - int bin = (src[i] - minVal) / binWidth; - if(bin >= histSize) bin = histSize - 1; - histogram[bin]++; - } - } - - // 计算1%和99%百分位数 - int totalPixels = 0; - for (int i = 0; i < histSize; i++) totalPixels += histogram[i]; - - int thresh_1 = totalPixels * 0.01; - int thresh_99 = totalPixels * 0.99; - - int cumsum = 0; - for (int i = 0; i < histSize; i++) { - cumsum += histogram[i]; - if(cumsum >= thresh_1 && minVal == 65535) { - minVal = minVal + i * binWidth; - } - if(cumsum >= thresh_99) { - maxVal = minVal + i * binWidth; - break; - } - } - } - - // 创建8位图像并归一化 - QImage image(1224, 1024, QImage::Format_Grayscale8); - uint8_t* dst = image.bits(); - float scale = (maxVal > minVal) ? (255.0f / (maxVal - minVal)) : 0.0f; - - for (int i = 0; i < 1224 * 1024; i++) { - if(src[i] == 0) { - dst[i] = 0; - } else if(src[i] <= minVal) { - dst[i] = 0; - } else if(src[i] >= maxVal) { - dst[i] = 255; - } else { - dst[i] = static_cast((src[i] - minVal) * scale); - } - } - - QImage imageCopy = image.copy(); - - // 在主线程更新UI - QMetaObject::invokeMethod(this, [this, imageCopy]() { - if(m_rightImageDisplay) { - QPixmap pixmap = QPixmap::fromImage(imageCopy); - m_rightImageDisplay->setPixmap(pixmap.scaled( - m_rightImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); - } - }, Qt::QueuedConnection); - } catch (const std::exception &e) { - qDebug() << "[MainWindow] ERROR: Right IR processing exception:" << e.what(); - } - }); - } else { + const size_t size8bit = 612 * 512; + const size_t size16bit = 1224 * 1024 * sizeof(uint16_t); + const bool is8bit = (jpegData.size() == size8bit); + const bool is16bit = (jpegData.size() == size16bit); + if(!is8bit && !is16bit) { qDebug() << "[MainWindow] ERROR: Right IR data size mismatch:" << jpegData.size() << "(expected 8bit:" << size8bit << "or 16bit:" << size16bit << ")"; + return; } + + // 忙时丢帧,避免线程池任务积压导致显示乱序和偶发闪烁。 + if(m_rightIRProcessing.loadAcquire() > 0) { + return; + } + m_rightIRProcessing.ref(); + + QByteArray dataCopy = jpegData; + QtConcurrent::run([this, dataCopy, is16bit]() { + try { + QImage imageCopy; + if(!is16bit) { + QImage image(reinterpret_cast(dataCopy.constData()), + 612, 512, 612, QImage::Format_Grayscale8); + imageCopy = image.copy(); + } else { + const uint16_t* src = reinterpret_cast(dataCopy.constData()); + constexpr int kWidth = 1224; + constexpr int kHeight = 1024; + constexpr int kPixels = kWidth * kHeight; + constexpr int kHistSize = 256; + + uint16_t sampleMin = 65535; + uint16_t sampleMax = 0; + for(int i = 0; i < kPixels; i += 8) { + const uint16_t val = src[i]; + if(val > 0) { + if(val < sampleMin) sampleMin = val; + if(val > sampleMax) sampleMax = val; + } + } + + float rangeMin = 0.0f; + float rangeMax = 65535.0f; + if(sampleMax > sampleMin) { + int histogram[kHistSize] = {0}; + const float binWidth = qMax(1.0f, (sampleMax - sampleMin) / static_cast(kHistSize)); + + int totalPixels = 0; + for(int i = 0; i < kPixels; ++i) { + const uint16_t val = src[i]; + if(val > 0) { + int bin = static_cast((val - sampleMin) / binWidth); + if(bin < 0) bin = 0; + if(bin >= kHistSize) bin = kHistSize - 1; + histogram[bin]++; + totalPixels++; + } + } + + if(totalPixels > 0) { + const int thresh1 = qMax(1, static_cast(totalPixels * 0.01f)); + const int thresh99 = qMax(thresh1 + 1, static_cast(totalPixels * 0.99f)); + + int p1Bin = 0; + int p99Bin = kHistSize - 1; + int cumsum = 0; + bool p1Found = false; + for(int i = 0; i < kHistSize; ++i) { + cumsum += histogram[i]; + if(!p1Found && cumsum >= thresh1) { + p1Bin = i; + p1Found = true; + } + if(cumsum >= thresh99) { + p99Bin = i; + break; + } + } + + float rawMin = sampleMin + p1Bin * binWidth; + float rawMax = sampleMin + p99Bin * binWidth; + if(rawMax <= rawMin + 1.0f) { + rawMax = rawMin + 1.0f; + } + + if(!m_rightIrDisplayRangeInited) { + m_rightIrDisplayMin = rawMin; + m_rightIrDisplayMax = rawMax; + m_rightIrDisplayRangeInited = true; + } else { + const float prevMin = m_rightIrDisplayMin; + const float prevMax = m_rightIrDisplayMax; + const float maxJump = qMax(120.0f, (rawMax - rawMin) * 0.25f); + const float minClamped = qBound(prevMin - maxJump, rawMin, prevMin + maxJump); + const float maxClamped = qBound(prevMax - maxJump, rawMax, prevMax + maxJump); + + m_rightIrDisplayMin = prevMin * 0.85f + minClamped * 0.15f; + m_rightIrDisplayMax = prevMax * 0.85f + maxClamped * 0.15f; + if(m_rightIrDisplayMax <= m_rightIrDisplayMin + 32.0f) { + m_rightIrDisplayMax = m_rightIrDisplayMin + 32.0f; + } + } + + rangeMin = m_rightIrDisplayMin; + rangeMax = m_rightIrDisplayMax; + } + } else if(m_rightIrDisplayRangeInited) { + rangeMin = m_rightIrDisplayMin; + rangeMax = m_rightIrDisplayMax; + } + + QImage image(kWidth, kHeight, QImage::Format_Grayscale8); + uint8_t* dst = image.bits(); + const float scale = (rangeMax > rangeMin) ? (255.0f / (rangeMax - rangeMin)) : 0.0f; + + for(int i = 0; i < kPixels; ++i) { + const uint16_t val = src[i]; + if(val == 0 || val <= rangeMin) { + dst[i] = 0; + } else if(val >= rangeMax) { + dst[i] = 255; + } else { + dst[i] = static_cast((val - rangeMin) * scale); + } + } + imageCopy = image.copy(); + } + + QMetaObject::invokeMethod(this, [this, imageCopy]() { + if(m_rightImageDisplay) { + QPixmap pixmap = QPixmap::fromImage(imageCopy); + m_rightImageDisplay->setPixmap(pixmap.scaled( + m_rightImageDisplay->size(), Qt::KeepAspectRatio, Qt::FastTransformation)); + } + }, Qt::QueuedConnection); + } catch (const std::exception &e) { + qDebug() << "[MainWindow] ERROR: Right IR processing exception:" << e.what(); + } catch (...) { + qDebug() << "[MainWindow] ERROR: Right IR processing unknown exception"; + } + m_rightIRProcessing.deref(); + }); } } @@ -1407,21 +1589,57 @@ void MainWindow::onRgbImageReceived(const QByteArray &jpegData, uint32_t blockId void MainWindow::onDepthDataReceived(const QByteArray &depthData, uint32_t blockId) { - // 实时处理每一帧 - // 注释掉频繁的日志输出 - // qDebug() << "Depth data received: Block" << blockId << "Size:" << depthData.size() << "bytes"; + // 点云处理忙时直接丢弃新帧,避免任务堆积拖垮线程池和UI响应。 + if(m_pointCloudProcessing.loadAcquire() > 0) { + int dropped = m_pointCloudDropCounter.fetchAndAddRelaxed(1) + 1; + if((dropped % 60) == 0) { + qDebug() << "[MainWindow] Point cloud(depth) busy, dropped frames:" << dropped; + } + return; + } - // 调用PointCloudProcessor进行OpenCL计算 - m_pointCloudProcessor->processDepthData(depthData, blockId); + m_pointCloudProcessing.ref(); + QByteArray dataCopy = depthData; + QtConcurrent::run([this, dataCopy, blockId]() { + try { + if(m_pointCloudProcessor) { + m_pointCloudProcessor->processDepthData(dataCopy, blockId); + } + } catch (const std::exception &e) { + qDebug() << "[MainWindow] ERROR: Depth point cloud process exception:" << e.what(); + } catch (...) { + qDebug() << "[MainWindow] ERROR: Depth point cloud process unknown exception"; + } + m_pointCloudProcessing.deref(); + }); } void MainWindow::onPointCloudDataReceived(const QByteArray &cloudData, uint32_t blockId) { // qDebug() << "[MainWindow] Point cloud data received: Block" << blockId << "Size:" << cloudData.size() << "bytes"; - // 使用QtConcurrent在后台线程处理点云数据 - QtConcurrent::run([this, cloudData, blockId]() { - m_pointCloudProcessor->processPointCloudData(cloudData, blockId); + // 点云处理忙时直接丢弃新帧,避免任务堆积拖垮线程池和UI响应。 + if(m_pointCloudProcessing.loadAcquire() > 0) { + int dropped = m_pointCloudDropCounter.fetchAndAddRelaxed(1) + 1; + if((dropped % 60) == 0) { + qDebug() << "[MainWindow] Point cloud(z/xyz) busy, dropped frames:" << dropped; + } + return; + } + + m_pointCloudProcessing.ref(); + QByteArray dataCopy = cloudData; + QtConcurrent::run([this, dataCopy, blockId]() { + try { + if(m_pointCloudProcessor) { + m_pointCloudProcessor->processPointCloudData(dataCopy, blockId); + } + } catch (const std::exception &e) { + qDebug() << "[MainWindow] ERROR: Point cloud process exception:" << e.what(); + } catch (...) { + qDebug() << "[MainWindow] ERROR: Point cloud process unknown exception"; + } + m_pointCloudProcessing.deref(); }); } diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 2bbeb32..885d7af 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -141,6 +141,7 @@ private: QPushButton *m_rightIRToggle; QPushButton *m_rgbToggle; QPushButton *m_pointCloudColorToggle; // 点云颜色开关 + QPushButton *m_pointCloudDenoiseToggle; // Point cloud denoise toggle // 单目/双目模式切换按钮 QPushButton *m_monocularBtn; @@ -157,6 +158,12 @@ private: QPushButton *m_browseSavePathBtn; class QComboBox *m_depthFormatCombo; class QComboBox *m_pointCloudFormatCombo; + QSlider *m_denoiseSupportSlider; + QSpinBox *m_denoiseSupportSpinBox; + QSlider *m_denoiseTailSlider; + QSpinBox *m_denoiseTailSpinBox; + QSlider *m_denoiseBandSlider; + QSpinBox *m_denoiseBandSpinBox; // 显示控件 QLabel *m_statusLabel; @@ -212,6 +219,14 @@ private: QAtomicInt m_rgbProcessing; QAtomicInt m_leftIRProcessing; QAtomicInt m_rightIRProcessing; + QAtomicInt m_pointCloudProcessing; + QAtomicInt m_pointCloudDropCounter; + bool m_leftIrDisplayRangeInited; + float m_leftIrDisplayMin; + float m_leftIrDisplayMax; + bool m_rightIrDisplayRangeInited; + float m_rightIrDisplayMin; + float m_rightIrDisplayMax; int m_rgbSkipCounter; // RGB帧跳过计数器 // 相机启用状态标志(防止关闭后闪烁) diff --git a/src/gui/PointCloudGLWidget.cpp b/src/gui/PointCloudGLWidget.cpp index 00bd57b..f4d6d5f 100644 --- a/src/gui/PointCloudGLWidget.cpp +++ b/src/gui/PointCloudGLWidget.cpp @@ -257,17 +257,18 @@ void PointCloudGLWidget::updatePointCloud(pcl::PointCloud::Ptr cl for (const auto& point : cloud->points) { if (point.z > 0.01f) { // 过滤掉无效的零点 + const float displayZ = -point.z; // Flip front/back axis for viewer convention. m_vertices.push_back(point.x); m_vertices.push_back(-point.y); - m_vertices.push_back(point.z); + m_vertices.push_back(displayZ); // 更新包围盒 if (point.x < minX) minX = point.x; if (point.x > maxX) maxX = point.x; if (point.y < minY) minY = point.y; if (point.y > maxY) maxY = point.y; - if (point.z < minZ) minZ = point.z; - if (point.z > maxZ) maxZ = point.z; + if (displayZ < minZ) minZ = displayZ; + if (displayZ > maxZ) maxZ = displayZ; } }