· 9 years ago · Jun 09, 2017, 12:06 AM
1diff --git a/.gitignore b/.gitignore
2index 7290fd5..9f7d59e 100644
3--- a/.gitignore
4+++ b/.gitignore
5@@ -1,287 +1,287 @@
6-## Ignore Visual Studio temporary files, build results, and
7-## files generated by popular Visual Studio add-ons.
8-##
9-## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
10-
11-# User-specific files
12-*.suo
13-*.user
14-*.userosscache
15-*.sln.docstates
16-
17-# User-specific files (MonoDevelop/Xamarin Studio)
18-*.userprefs
19-
20-# Build results
21-[Dd]ebug/
22-[Dd]ebugPublic/
23-[Rr]elease/
24-[Rr]eleases/
25-x64/
26-x86/
27-bld/
28-[Bb]in/
29-[Oo]bj/
30-[Ll]og/
31-
32-# Visual Studio 2015 cache/options directory
33-.vs/
34-# Uncomment if you have tasks that create the project's static files in wwwroot
35-#wwwroot/
36-
37-# MSTest test Results
38-[Tt]est[Rr]esult*/
39-[Bb]uild[Ll]og.*
40-
41-# NUNIT
42-*.VisualState.xml
43-TestResult.xml
44-
45-# Build Results of an ATL Project
46-[Dd]ebugPS/
47-[Rr]eleasePS/
48-dlldata.c
49-
50-# .NET Core
51-project.lock.json
52-project.fragment.lock.json
53-artifacts/
54-**/Properties/launchSettings.json
55-
56-*_i.c
57-*_p.c
58-*_i.h
59-*.ilk
60-*.meta
61-*.obj
62-*.pch
63-*.pdb
64-*.pgc
65-*.pgd
66-*.rsp
67-*.sbr
68-*.tlb
69-*.tli
70-*.tlh
71-*.tmp
72-*.tmp_proj
73-*.log
74-*.vspscc
75-*.vssscc
76-.builds
77-*.pidb
78-*.svclog
79-*.scc
80-
81-# Chutzpah Test files
82-_Chutzpah*
83-
84-# Visual C++ cache files
85-ipch/
86-*.aps
87-*.ncb
88-*.opendb
89-*.opensdf
90-*.sdf
91-*.cachefile
92-*.VC.db
93-*.VC.VC.opendb
94-
95-# Visual Studio profiler
96-*.psess
97-*.vsp
98-*.vspx
99-*.sap
100-
101-# TFS 2012 Local Workspace
102-$tf/
103-
104-# Guidance Automation Toolkit
105-*.gpState
106-
107-# ReSharper is a .NET coding add-in
108-_ReSharper*/
109-*.[Rr]e[Ss]harper
110-*.DotSettings.user
111-
112-# JustCode is a .NET coding add-in
113-.JustCode
114-
115-# TeamCity is a build add-in
116-_TeamCity*
117-
118-# DotCover is a Code Coverage Tool
119-*.dotCover
120-
121-# Visual Studio code coverage results
122-*.coverage
123-*.coveragexml
124-
125-# NCrunch
126-_NCrunch_*
127-.*crunch*.local.xml
128-nCrunchTemp_*
129-
130-# MightyMoose
131-*.mm.*
132-AutoTest.Net/
133-
134-# Web workbench (sass)
135-.sass-cache/
136-
137-# Installshield output folder
138-[Ee]xpress/
139-
140-# DocProject is a documentation generator add-in
141-DocProject/buildhelp/
142-DocProject/Help/*.HxT
143-DocProject/Help/*.HxC
144-DocProject/Help/*.hhc
145-DocProject/Help/*.hhk
146-DocProject/Help/*.hhp
147-DocProject/Help/Html2
148-DocProject/Help/html
149-
150-# Click-Once directory
151-publish/
152-
153-# Publish Web Output
154-*.[Pp]ublish.xml
155-*.azurePubxml
156-# TODO: Comment the next line if you want to checkin your web deploy settings
157-# but database connection strings (with potential passwords) will be unencrypted
158-*.pubxml
159-*.publishproj
160-
161-# Microsoft Azure Web App publish settings. Comment the next line if you want to
162-# checkin your Azure Web App publish settings, but sensitive information contained
163-# in these scripts will be unencrypted
164-PublishScripts/
165-
166-# NuGet Packages
167-*.nupkg
168-# The packages folder can be ignored because of Package Restore
169-**/packages/*
170-# except build/, which is used as an MSBuild target.
171-!**/packages/build/
172-# Uncomment if necessary however generally it will be regenerated when needed
173-#!**/packages/repositories.config
174-# NuGet v3's project.json files produces more ignorable files
175-*.nuget.props
176-*.nuget.targets
177-
178-# Microsoft Azure Build Output
179-csx/
180-*.build.csdef
181-
182-# Microsoft Azure Emulator
183-ecf/
184-rcf/
185-
186-# Windows Store app package directories and files
187-AppPackages/
188-BundleArtifacts/
189-Package.StoreAssociation.xml
190-_pkginfo.txt
191-
192-# Visual Studio cache files
193-# files ending in .cache can be ignored
194-*.[Cc]ache
195-# but keep track of directories ending in .cache
196-!*.[Cc]ache/
197-
198-# Others
199-ClientBin/
200-~$*
201-*~
202-*.dbmdl
203-*.dbproj.schemaview
204-*.jfm
205-*.pfx
206-*.publishsettings
207-orleans.codegen.cs
208-
209-# Since there are multiple workflows, uncomment next line to ignore bower_components
210-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
211-#bower_components/
212-
213-# RIA/Silverlight projects
214-Generated_Code/
215-
216-# Backup & report files from converting an old project file
217-# to a newer Visual Studio version. Backup files are not needed,
218-# because we have git ;-)
219-_UpgradeReport_Files/
220-Backup*/
221-UpgradeLog*.XML
222-UpgradeLog*.htm
223-
224-# SQL Server files
225-*.mdf
226-*.ldf
227-
228-# Business Intelligence projects
229-*.rdl.data
230-*.bim.layout
231-*.bim_*.settings
232-
233-# Microsoft Fakes
234-FakesAssemblies/
235-
236-# GhostDoc plugin setting file
237-*.GhostDoc.xml
238-
239-# Node.js Tools for Visual Studio
240-.ntvs_analysis.dat
241-node_modules/
242-
243-# Typescript v1 declaration files
244-typings/
245-
246-# Visual Studio 6 build log
247-*.plg
248-
249-# Visual Studio 6 workspace options file
250-*.opt
251-
252-# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
253-*.vbw
254-
255-# Visual Studio LightSwitch build output
256-**/*.HTMLClient/GeneratedArtifacts
257-**/*.DesktopClient/GeneratedArtifacts
258-**/*.DesktopClient/ModelManifest.xml
259-**/*.Server/GeneratedArtifacts
260-**/*.Server/ModelManifest.xml
261-_Pvt_Extensions
262-
263-# Paket dependency manager
264-.paket/paket.exe
265-paket-files/
266-
267-# FAKE - F# Make
268-.fake/
269-
270-# JetBrains Rider
271-.idea/
272-*.sln.iml
273-
274-# CodeRush
275-.cr/
276-
277-# Python Tools for Visual Studio (PTVS)
278-__pycache__/
279-*.pyc
280-
281-# OpenARK Third Party Resources
282-*.pap
283-*.ppp
284-*.dylib
285-opencv_*
286-pmdaccess2.dll
287-OpenNI2.dll
288-main.cpp
289-
290-# Cake - Uncomment if you are using it
291-# tools/**
292-# !tools/packages.config
293+## Ignore Visual Studio temporary files, build results, and
294+## files generated by popular Visual Studio add-ons.
295+##
296+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
297+
298+# User-specific files
299+*.suo
300+*.user
301+*.userosscache
302+*.sln.docstates
303+
304+# User-specific files (MonoDevelop/Xamarin Studio)
305+*.userprefs
306+
307+# Build results
308+[Dd]ebug/
309+[Dd]ebugPublic/
310+[Rr]elease/
311+[Rr]eleases/
312+x64/
313+x86/
314+bld/
315+[Bb]in/
316+[Oo]bj/
317+[Ll]og/
318+
319+# Visual Studio 2015 cache/options directory
320+.vs/
321+# Uncomment if you have tasks that create the project's static files in wwwroot
322+#wwwroot/
323+
324+# MSTest test Results
325+[Tt]est[Rr]esult*/
326+[Bb]uild[Ll]og.*
327+
328+# NUNIT
329+*.VisualState.xml
330+TestResult.xml
331+
332+# Build Results of an ATL Project
333+[Dd]ebugPS/
334+[Rr]eleasePS/
335+dlldata.c
336+
337+# .NET Core
338+project.lock.json
339+project.fragment.lock.json
340+artifacts/
341+**/Properties/launchSettings.json
342+
343+*_i.c
344+*_p.c
345+*_i.h
346+*.ilk
347+*.meta
348+*.obj
349+*.pch
350+*.pdb
351+*.pgc
352+*.pgd
353+*.rsp
354+*.sbr
355+*.tlb
356+*.tli
357+*.tlh
358+*.tmp
359+*.tmp_proj
360+*.log
361+*.vspscc
362+*.vssscc
363+.builds
364+*.pidb
365+*.svclog
366+*.scc
367+
368+# Chutzpah Test files
369+_Chutzpah*
370+
371+# Visual C++ cache files
372+ipch/
373+*.aps
374+*.ncb
375+*.opendb
376+*.opensdf
377+*.sdf
378+*.cachefile
379+*.VC.db
380+*.VC.VC.opendb
381+
382+# Visual Studio profiler
383+*.psess
384+*.vsp
385+*.vspx
386+*.sap
387+
388+# TFS 2012 Local Workspace
389+$tf/
390+
391+# Guidance Automation Toolkit
392+*.gpState
393+
394+# ReSharper is a .NET coding add-in
395+_ReSharper*/
396+*.[Rr]e[Ss]harper
397+*.DotSettings.user
398+
399+# JustCode is a .NET coding add-in
400+.JustCode
401+
402+# TeamCity is a build add-in
403+_TeamCity*
404+
405+# DotCover is a Code Coverage Tool
406+*.dotCover
407+
408+# Visual Studio code coverage results
409+*.coverage
410+*.coveragexml
411+
412+# NCrunch
413+_NCrunch_*
414+.*crunch*.local.xml
415+nCrunchTemp_*
416+
417+# MightyMoose
418+*.mm.*
419+AutoTest.Net/
420+
421+# Web workbench (sass)
422+.sass-cache/
423+
424+# Installshield output folder
425+[Ee]xpress/
426+
427+# DocProject is a documentation generator add-in
428+DocProject/buildhelp/
429+DocProject/Help/*.HxT
430+DocProject/Help/*.HxC
431+DocProject/Help/*.hhc
432+DocProject/Help/*.hhk
433+DocProject/Help/*.hhp
434+DocProject/Help/Html2
435+DocProject/Help/html
436+
437+# Click-Once directory
438+publish/
439+
440+# Publish Web Output
441+*.[Pp]ublish.xml
442+*.azurePubxml
443+# TODO: Comment the next line if you want to checkin your web deploy settings
444+# but database connection strings (with potential passwords) will be unencrypted
445+*.pubxml
446+*.publishproj
447+
448+# Microsoft Azure Web App publish settings. Comment the next line if you want to
449+# checkin your Azure Web App publish settings, but sensitive information contained
450+# in these scripts will be unencrypted
451+PublishScripts/
452+
453+# NuGet Packages
454+*.nupkg
455+# The packages folder can be ignored because of Package Restore
456+**/packages/*
457+# except build/, which is used as an MSBuild target.
458+!**/packages/build/
459+# Uncomment if necessary however generally it will be regenerated when needed
460+#!**/packages/repositories.config
461+# NuGet v3's project.json files produces more ignorable files
462+*.nuget.props
463+*.nuget.targets
464+
465+# Microsoft Azure Build Output
466+csx/
467+*.build.csdef
468+
469+# Microsoft Azure Emulator
470+ecf/
471+rcf/
472+
473+# Windows Store app package directories and files
474+AppPackages/
475+BundleArtifacts/
476+Package.StoreAssociation.xml
477+_pkginfo.txt
478+
479+# Visual Studio cache files
480+# files ending in .cache can be ignored
481+*.[Cc]ache
482+# but keep track of directories ending in .cache
483+!*.[Cc]ache/
484+
485+# Others
486+ClientBin/
487+~$*
488+*~
489+*.dbmdl
490+*.dbproj.schemaview
491+*.jfm
492+*.pfx
493+*.publishsettings
494+orleans.codegen.cs
495+
496+# Since there are multiple workflows, uncomment next line to ignore bower_components
497+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
498+#bower_components/
499+
500+# RIA/Silverlight projects
501+Generated_Code/
502+
503+# Backup & report files from converting an old project file
504+# to a newer Visual Studio version. Backup files are not needed,
505+# because we have git ;-)
506+_UpgradeReport_Files/
507+Backup*/
508+UpgradeLog*.XML
509+UpgradeLog*.htm
510+
511+# SQL Server files
512+*.mdf
513+*.ldf
514+
515+# Business Intelligence projects
516+*.rdl.data
517+*.bim.layout
518+*.bim_*.settings
519+
520+# Microsoft Fakes
521+FakesAssemblies/
522+
523+# GhostDoc plugin setting file
524+*.GhostDoc.xml
525+
526+# Node.js Tools for Visual Studio
527+.ntvs_analysis.dat
528+node_modules/
529+
530+# Typescript v1 declaration files
531+typings/
532+
533+# Visual Studio 6 build log
534+*.plg
535+
536+# Visual Studio 6 workspace options file
537+*.opt
538+
539+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
540+*.vbw
541+
542+# Visual Studio LightSwitch build output
543+**/*.HTMLClient/GeneratedArtifacts
544+**/*.DesktopClient/GeneratedArtifacts
545+**/*.DesktopClient/ModelManifest.xml
546+**/*.Server/GeneratedArtifacts
547+**/*.Server/ModelManifest.xml
548+_Pvt_Extensions
549+
550+# Paket dependency manager
551+.paket/paket.exe
552+paket-files/
553+
554+# FAKE - F# Make
555+.fake/
556+
557+# JetBrains Rider
558+.idea/
559+*.sln.iml
560+
561+# CodeRush
562+.cr/
563+
564+# Python Tools for Visual Studio (PTVS)
565+__pycache__/
566+*.pyc
567+
568+# OpenARK Third Party Resources
569+*.pap
570+*.ppp
571+*.dylib
572+opencv_*
573+pmdaccess2.dll
574+OpenNI2.dll
575+main.cpp
576+
577+# Cake - Uncomment if you are using it
578+# tools/**
579+# !tools/packages.config
580diff --git a/CMakeLists.txt b/CMakeLists.txt
581index 14427d1..e6cd58d 100644
582--- a/CMakeLists.txt
583+++ b/CMakeLists.txt
584@@ -1,6 +1,6 @@
585-cmake_minimum_required(VERSION 2.8)
586-project( OpenARK )
587-find_package( OpenCV REQUIRED )
588-set(SOURCES Clustering.cpp PMDSensor.cpp Sensor.cpp Webcam.cpp DepthSensor.cpp RGBSensor.cpp Visualizer.cpp main.cpp)
589-add_executable( OpenARK ${SOURCES} )
590+cmake_minimum_required(VERSION 2.8)
591+project( OpenARK )
592+find_package( OpenCV REQUIRED )
593+set(SOURCES Clustering.cpp PMDSensor.cpp Sensor.cpp Webcam.cpp DepthSensor.cpp RGBSensor.cpp Visualizer.cpp main.cpp)
594+add_executable( OpenARK ${SOURCES} )
595 target_link_libraries( OpenARK ${OpenCV_LIBS} )
596\ No newline at end of file
597diff --git a/Calibration.cpp b/Calibration.cpp
598index 5747d01..0fdd729 100644
599--- a/Calibration.cpp
600+++ b/Calibration.cpp
601@@ -1,206 +1,206 @@
602-#include "Calibration.h"
603-
604-
605-void Calibration::XYZToUnity(DepthCamera& depth_cam, int num_boards, int board_w, int board_h)
606-{
607- cv::Size board_sz = cv::Size(board_w, board_h);
608- int board_n = board_w * board_h;
609- std::vector<cv::Point2f> cornersAmp; // Corners of amplitude image
610- std::vector<cv::Point3f> cornersXYZ; // Corners of the depth image
611- std::vector<std::vector<cv::Point3f>> XYZ_points;
612-
613- // Prepare the Unity side data
614- std::vector<std::vector<cv::Point3f>> Unity_points;
615- std::vector<cv::Point3f> upper_left;
616- upper_left.push_back(cv::Point3f(-0.05, 0.03, 0.40));
617- upper_left.push_back(cv::Point3f(0.05, 0.03, 0.40));
618- upper_left.push_back(cv::Point3f(0.0, 0.08, 0.35));
619- upper_left.push_back(cv::Point3f(0.0, -0.02, 0.35));
620- Unity_points = prepareUnityData(upper_left, 0.03, board_h, board_w);
621-
622- int success = 0;
623-
624- // Collect data for calibration
625- while (success < num_boards)
626- {
627- cornersAmp.clear();
628- cornersXYZ.clear();
629- bool found1 = false;
630- depth_cam.update();
631- depth_cam.removeNoise();
632- cv::Mat xyzMap = depth_cam.getXYZMap();
633-
634- cv::Mat ampGray;
635- cv::normalize(depth_cam.getAmpMap(), ampGray, 0, 255, cv::NORM_MINMAX, CV_8UC1);
636- cv::equalizeHist(ampGray, ampGray);
637- cv::resize(ampGray, ampGray, cv::Size(ampGray.cols * 4, ampGray.rows * 4));
638-
639- // Sharpen amplitude image
640- cv::Mat unsharp_mask;
641- cv::GaussianBlur(ampGray, unsharp_mask, cv::Size(5, 5), 5);
642- cv::addWeighted(ampGray, 1.5, unsharp_mask, -0.5, 0, ampGray);
643- cv::imshow("Gray Amp", ampGray);
644-
645- // Find chessboards on amplitude
646- found1 = findChessboardCorners(ampGray, board_sz, cornersAmp, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
647-
648-
649- if (found1) {
650- cornerSubPix(ampGray, cornersAmp, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
651- cv::Mat ampRGB = ampGray.clone();
652- cv::cvtColor(ampRGB, ampRGB, CV_GRAY2BGR);
653- drawChessboardCorners(ampRGB, board_sz, cornersAmp, found1);
654- cv::imshow("Gray Corners", ampRGB);
655-
656- for (int i = 0; i < cornersAmp.size(); i++) {
657- cornersAmp[i].x = cornersAmp[i].x / 4;
658- cornersAmp[i].y = cornersAmp[i].y / 4;
659- }
660-
661- for (int i = 0; i < cornersAmp.size(); i++) {
662- cv::Vec3f xyz = Util::averageAroundPoint(xyzMap, cv::Point2i(cornersAmp[i].x, cornersAmp[i].y), 5);
663- cv::Point3f pt;
664- pt.x = xyz[0]; pt.y = xyz[1], pt.z = xyz[2];
665- if (pt.z == 0) {
666- continue;
667- }
668- cornersXYZ.push_back(pt);
669- }
670-
671- int c = cvWaitKey(1);
672- if (c == ' ') {
673- success++;
674- XYZ_points.push_back(cornersXYZ);
675- printf("%d points recorded!\n", cornersXYZ.size());
676- }
677- }
678-
679-
680- int c = cvWaitKey(1);
681- if (c == 'q' || c == 'Q' || c == 27) {
682- break;
683- }
684- }
685-
686- /**** Perform calculations ****/
687- Calibration::writeDataToFile(Unity_points, 4, 3, "Unity.txt");
688- Calibration::writeDataToFile(XYZ_points, 4, 3, "XYZ.txt");
689- float x_input[3][48];
690- float y_input[3][48];
691- int count = 0;
692- for (int i = 0; i < XYZ_points.size(); i++) {
693- for (int v = 0; v < XYZ_points[i].size(); v++) {
694- x_input[0][count] = XYZ_points[i][v].x;
695- x_input[1][count] = XYZ_points[i][v].y;
696- x_input[2][count] = XYZ_points[i][v].z;
697-
698- y_input[0][count] = Unity_points[i][v].x;
699- y_input[1][count] = Unity_points[i][v].y;
700- y_input[2][count] = Unity_points[i][v].z;
701-
702- count++;
703- }
704- }
705-
706- cv::Mat x = cv::Mat(3, 48, CV_32FC1, &x_input); //XYZ
707- cv::Mat y = cv::Mat(3, 48, CV_32FC1, &y_input); //Unity
708- cv::Mat r, t;
709- computeRT(x, y, &r, &t);
710-
711- cv::FileStorage fs("RT_Transform.txt", cv::FileStorage::WRITE);
712-
713- fs << "R" << r;
714- fs << "T" << t;
715-
716- fs.release();
717-}
718-void Calibration::computeRT(cv::Mat x, cv::Mat y, cv::Mat *R, cv::Mat *t) {
719-
720- cv::Mat x_mean, y_mean, H;
721- cv::reduce(x, x_mean, 1, CV_REDUCE_AVG);
722- cv::reduce(y, y_mean, 1, CV_REDUCE_AVG);
723- for (int i = 0; i < x.cols; i++) {
724- H = H + (x.col(i) - x_mean) * ((y.col(i) - y_mean).t());
725- }
726- cv::Mat u, s, v;
727- cv::SVD::compute(H, s, u, v);
728- u = -1 * u;
729- v = -1 * v.t();
730- *R = v * u.t();
731- if (cv::determinant(*R) > 0) {
732- v.col(2) = -1 * v.col(2);
733- *R = v * u.t();
734- }
735- *t = -1 * *R * x_mean + y_mean;
736-}
737-
738-void Calibration::XYZToRGB(DepthCamera* depth_cam, RGBCamera* rgb_cam, int num_boards, int board_w, int board_h)
739-{
740- return;
741-}
742-
743-double Calibration::reprojectXYZToUnity(std::vector<std::vector<cv::Point3f>> XYZ_points, std::vector<std::vector<cv::Point3f>> Unity_points, Eigen::MatrixXf R, Eigen::MatrixXf T)
744-{
745- // Return error value if there is a size mismatch
746- if (XYZ_points.size() != Unity_points.size())
747- {
748- return -1.00;
749- }
750-
751- double error = 0;
752- for (int i = 0; i < XYZ_points.size(); i++) {
753- for (int v = 0; v < XYZ_points[i].size(); v++) {
754- Eigen::MatrixXf pt_xyz(3, 1);
755- Eigen::MatrixXf pt_unity(3, 1);
756- pt_xyz(0, 0) = XYZ_points[i][v].x;
757- pt_xyz(1, 0) = XYZ_points[i][v].y;
758- pt_xyz(2, 0) = XYZ_points[i][v].z;
759- pt_unity(0, 0) = Unity_points[i][v].x;
760- pt_unity(1, 0) = Unity_points[i][v].y;
761- pt_unity(2, 0) = Unity_points[i][v].z;
762-
763- Eigen::MatrixXf result = R * T * pt_xyz;
764- error += abs((result - pt_unity).norm());
765- }
766- }
767-
768- return error;
769-}
770-
771-double Calibration::reprojectXYZtoRGB()
772-{
773- return false;
774-}
775-
776-std::vector<std::vector<cv::Point3f>> Calibration::prepareUnityData(std::vector<cv::Point3f> upper_left, float distance, int num_rows, int num_cols)
777-{
778- std::vector<std::vector<cv::Point3f>> Unity_points;
779-
780- for (int i = 0; i < upper_left.size(); i++) {
781- std::vector<cv::Point3f> points;
782- for (int y = 0; y < num_rows; y++) {
783- for (int x = 0; x < num_cols; x++) {
784- points.push_back(cv::Point3f(upper_left[i].x + x * distance, upper_left[i].y - y * distance, upper_left[i].z));
785- }
786- }
787- Unity_points.push_back(points);
788- }
789-
790- return Unity_points;
791-}
792-
793-void Calibration::writeDataToFile(std::vector<std::vector<cv::Point3f>> points, int board_w, int board_h, std::string filename)
794-{
795- ofstream output_file;
796- output_file.open(filename);
797- for (int i = 0; i < points.size(); i++) {
798- for (int v = 0; v < points[i].size(); v++) {
799- if (v%board_w == 0) {
800- output_file << "\n";
801- }
802- output_file << "(" << points[i][v].x << ", " << points[i][v].y << ", " << points[i][v].z << ") ";
803- }
804- output_file << "\n\n";
805- }
806- output_file.close();
807+#include "Calibration.h"
808+
809+
810+void Calibration::XYZToUnity(DepthCamera& depth_cam, int num_boards, int board_w, int board_h)
811+{
812+ cv::Size board_sz = cv::Size(board_w, board_h);
813+ int board_n = board_w * board_h;
814+ std::vector<cv::Point2f> cornersAmp; // Corners of amplitude image
815+ std::vector<cv::Point3f> cornersXYZ; // Corners of the depth image
816+ std::vector<std::vector<cv::Point3f>> XYZ_points;
817+
818+ // Prepare the Unity side data
819+ std::vector<std::vector<cv::Point3f>> Unity_points;
820+ std::vector<cv::Point3f> upper_left;
821+ upper_left.push_back(cv::Point3f(-0.05, 0.03, 0.40));
822+ upper_left.push_back(cv::Point3f(0.05, 0.03, 0.40));
823+ upper_left.push_back(cv::Point3f(0.0, 0.08, 0.35));
824+ upper_left.push_back(cv::Point3f(0.0, -0.02, 0.35));
825+ Unity_points = prepareUnityData(upper_left, 0.03, board_h, board_w);
826+
827+ int success = 0;
828+
829+ // Collect data for calibration
830+ while (success < num_boards)
831+ {
832+ cornersAmp.clear();
833+ cornersXYZ.clear();
834+ bool found1 = false;
835+ depth_cam.update();
836+ depth_cam.removeNoise();
837+ cv::Mat xyzMap = depth_cam.getXYZMap();
838+
839+ cv::Mat ampGray;
840+ cv::normalize(depth_cam.getAmpMap(), ampGray, 0, 255, cv::NORM_MINMAX, CV_8UC1);
841+ cv::equalizeHist(ampGray, ampGray);
842+ cv::resize(ampGray, ampGray, cv::Size(ampGray.cols * 4, ampGray.rows * 4));
843+
844+ // Sharpen amplitude image
845+ cv::Mat unsharp_mask;
846+ cv::GaussianBlur(ampGray, unsharp_mask, cv::Size(5, 5), 5);
847+ cv::addWeighted(ampGray, 1.5, unsharp_mask, -0.5, 0, ampGray);
848+ cv::imshow("Gray Amp", ampGray);
849+
850+ // Find chessboards on amplitude
851+ found1 = findChessboardCorners(ampGray, board_sz, cornersAmp, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
852+
853+
854+ if (found1) {
855+ cornerSubPix(ampGray, cornersAmp, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
856+ cv::Mat ampRGB = ampGray.clone();
857+ cv::cvtColor(ampRGB, ampRGB, CV_GRAY2BGR);
858+ drawChessboardCorners(ampRGB, board_sz, cornersAmp, found1);
859+ cv::imshow("Gray Corners", ampRGB);
860+
861+ for (int i = 0; i < cornersAmp.size(); i++) {
862+ cornersAmp[i].x = cornersAmp[i].x / 4;
863+ cornersAmp[i].y = cornersAmp[i].y / 4;
864+ }
865+
866+ for (int i = 0; i < cornersAmp.size(); i++) {
867+ cv::Vec3f xyz = Util::averageAroundPoint(xyzMap, cv::Point2i(cornersAmp[i].x, cornersAmp[i].y), 5);
868+ cv::Point3f pt;
869+ pt.x = xyz[0]; pt.y = xyz[1], pt.z = xyz[2];
870+ if (pt.z == 0) {
871+ continue;
872+ }
873+ cornersXYZ.push_back(pt);
874+ }
875+
876+ int c = cvWaitKey(1);
877+ if (c == ' ') {
878+ success++;
879+ XYZ_points.push_back(cornersXYZ);
880+ printf("%d points recorded!\n", cornersXYZ.size());
881+ }
882+ }
883+
884+
885+ int c = cvWaitKey(1);
886+ if (c == 'q' || c == 'Q' || c == 27) {
887+ break;
888+ }
889+ }
890+
891+ /**** Perform calculations ****/
892+ Calibration::writeDataToFile(Unity_points, 4, 3, "Unity.txt");
893+ Calibration::writeDataToFile(XYZ_points, 4, 3, "XYZ.txt");
894+ float x_input[3][48];
895+ float y_input[3][48];
896+ int count = 0;
897+ for (int i = 0; i < XYZ_points.size(); i++) {
898+ for (int v = 0; v < XYZ_points[i].size(); v++) {
899+ x_input[0][count] = XYZ_points[i][v].x;
900+ x_input[1][count] = XYZ_points[i][v].y;
901+ x_input[2][count] = XYZ_points[i][v].z;
902+
903+ y_input[0][count] = Unity_points[i][v].x;
904+ y_input[1][count] = Unity_points[i][v].y;
905+ y_input[2][count] = Unity_points[i][v].z;
906+
907+ count++;
908+ }
909+ }
910+
911+ cv::Mat x = cv::Mat(3, 48, CV_32FC1, &x_input); //XYZ
912+ cv::Mat y = cv::Mat(3, 48, CV_32FC1, &y_input); //Unity
913+ cv::Mat r, t;
914+ computeRT(x, y, &r, &t);
915+
916+ cv::FileStorage fs("RT_Transform.txt", cv::FileStorage::WRITE);
917+
918+ fs << "R" << r;
919+ fs << "T" << t;
920+
921+ fs.release();
922+}
923+void Calibration::computeRT(cv::Mat x, cv::Mat y, cv::Mat *R, cv::Mat *t) {
924+
925+ cv::Mat x_mean, y_mean, H;
926+ cv::reduce(x, x_mean, 1, CV_REDUCE_AVG);
927+ cv::reduce(y, y_mean, 1, CV_REDUCE_AVG);
928+ for (int i = 0; i < x.cols; i++) {
929+ H = H + (x.col(i) - x_mean) * ((y.col(i) - y_mean).t());
930+ }
931+ cv::Mat u, s, v;
932+ cv::SVD::compute(H, s, u, v);
933+ u = -1 * u;
934+ v = -1 * v.t();
935+ *R = v * u.t();
936+ if (cv::determinant(*R) > 0) {
937+ v.col(2) = -1 * v.col(2);
938+ *R = v * u.t();
939+ }
940+ *t = -1 * *R * x_mean + y_mean;
941+}
942+
943+void Calibration::XYZToRGB(DepthCamera* depth_cam, RGBCamera* rgb_cam, int num_boards, int board_w, int board_h)
944+{
945+ return;
946+}
947+
948+double Calibration::reprojectXYZToUnity(std::vector<std::vector<cv::Point3f>> XYZ_points, std::vector<std::vector<cv::Point3f>> Unity_points, Eigen::MatrixXf R, Eigen::MatrixXf T)
949+{
950+ // Return error value if there is a size mismatch
951+ if (XYZ_points.size() != Unity_points.size())
952+ {
953+ return -1.00;
954+ }
955+
956+ double error = 0;
957+ for (int i = 0; i < XYZ_points.size(); i++) {
958+ for (int v = 0; v < XYZ_points[i].size(); v++) {
959+ Eigen::MatrixXf pt_xyz(3, 1);
960+ Eigen::MatrixXf pt_unity(3, 1);
961+ pt_xyz(0, 0) = XYZ_points[i][v].x;
962+ pt_xyz(1, 0) = XYZ_points[i][v].y;
963+ pt_xyz(2, 0) = XYZ_points[i][v].z;
964+ pt_unity(0, 0) = Unity_points[i][v].x;
965+ pt_unity(1, 0) = Unity_points[i][v].y;
966+ pt_unity(2, 0) = Unity_points[i][v].z;
967+
968+ Eigen::MatrixXf result = R * T * pt_xyz;
969+ error += abs((result - pt_unity).norm());
970+ }
971+ }
972+
973+ return error;
974+}
975+
976+double Calibration::reprojectXYZtoRGB()
977+{
978+ return false;
979+}
980+
981+std::vector<std::vector<cv::Point3f>> Calibration::prepareUnityData(std::vector<cv::Point3f> upper_left, float distance, int num_rows, int num_cols)
982+{
983+ std::vector<std::vector<cv::Point3f>> Unity_points;
984+
985+ for (int i = 0; i < upper_left.size(); i++) {
986+ std::vector<cv::Point3f> points;
987+ for (int y = 0; y < num_rows; y++) {
988+ for (int x = 0; x < num_cols; x++) {
989+ points.push_back(cv::Point3f(upper_left[i].x + x * distance, upper_left[i].y - y * distance, upper_left[i].z));
990+ }
991+ }
992+ Unity_points.push_back(points);
993+ }
994+
995+ return Unity_points;
996+}
997+
998+void Calibration::writeDataToFile(std::vector<std::vector<cv::Point3f>> points, int board_w, int board_h, std::string filename)
999+{
1000+ ofstream output_file;
1001+ output_file.open(filename);
1002+ for (int i = 0; i < points.size(); i++) {
1003+ for (int v = 0; v < points[i].size(); v++) {
1004+ if (v%board_w == 0) {
1005+ output_file << "\n";
1006+ }
1007+ output_file << "(" << points[i][v].x << ", " << points[i][v].y << ", " << points[i][v].z << ") ";
1008+ }
1009+ output_file << "\n\n";
1010+ }
1011+ output_file.close();
1012 }
1013\ No newline at end of file
1014diff --git a/Calibration.h b/Calibration.h
1015index 665de28..b6fe383 100644
1016--- a/Calibration.h
1017+++ b/Calibration.h
1018@@ -1,90 +1,92 @@
1019-#pragma once
1020-// C++ Libaries
1021-#include <fstream>
1022-
1023-// OpenCV Libraries
1024-#include "opencv2/calib3d/calib3d.hpp"
1025-#include "opencv2/highgui/highgui.hpp"
1026-#include <opencv2/video/tracking.hpp>
1027-#include "opencv2/imgproc/imgproc.hpp"
1028-#include <opencv2/objdetect/objdetect.hpp>
1029-#include <opencv2/features2d/features2d.hpp>
1030-
1031-// Eigen Libaries
1032-#include <Eigen/SVD>
1033-
1034-// OpenARK Libraries
1035-#include "Visualizer.h"
1036-#include "DepthCamera.h"
1037-#include "RGBCamera.h"
1038-#include "Util.h"
1039-
1040-/**
1041-* Class for various calibration operations.
1042-*/
1043-class Calibration
1044-{
1045-public:
1046- /**
1047- * Compute a calibration from (x,y,z) real world coordinates to (x',y',z') Unity coordinates.
1048- * @param depth_cam instance of a live @see DepthCamera
1049- * @param num_boards number of checkboard positions
1050- * @param board_w width of the board (number of inner intersections)
1051- * @param board_h height of the board (number of inner intersections)
1052- */
1053- static void XYZToUnity(DepthCamera& depth_cam, int num_boards, int board_w, int board_h);
1054-
1055- /**
1056- * Compute a calibration from (x,y,z) real world coordiantes to (i,j) RGB camera coordinates.
1057- * @param depth_cam instance of a live @see DepthCamera
1058- * @param rgb_cam instance of a live @see RGBCamera
1059- * @param num_boards number of checkboard positions
1060- * @param board_w width of the board (number of inner intersections)
1061- * @param board_h height of the board (number of inner intersections)
1062- */
1063- static void XYZToRGB(DepthCamera* depth_cam, RGBCamera* rgb_cam, int num_boards, int board_w, int board_h);
1064-
1065- /**
1066- * Reproject the (x,y,z) points to (x',y',z') Unity points with the RT matrix to test for error.
1067- * @param XYZ_points coordinates from the PMD sensor
1068- * @param Unity_points coordinates from the game engine
1069- * @param R the rotation matrix to use
1070- * @param T the translation matrix to use
1071- * @return cummulative reprojection error
1072- */
1073- static double reprojectXYZToUnity(std::vector<std::vector<cv::Point3f>> XYZ_points, std::vector<std::vector<cv::Point3f>> Unity_points, Eigen::MatrixXf R, Eigen::MatrixXf T);
1074-
1075- /**
1076- * Reproject the (x,y,z) points to (i,j) RGB image points with the RT matrix to test for error.
1077- */
1078- static double reprojectXYZtoRGB();
1079-
1080- /**
1081- * Compute full set of Unity checkboard coordinates.
1082- * @param upper_left the upper left corner coordinates of the chessboard
1083- * @param distance size of the checkerboard (meters)
1084- * @param num_rows number of rows (inner intersections)
1085- * @param num_cols number of columns (inner intersections)
1086- */
1087- static std::vector<std::vector<cv::Point3f>> prepareUnityData(std::vector<cv::Point3f> upper_left, float distance, int num_rows, int num_cols);
1088-
1089- /**
1090- * Write calibration data points to file
1091- * @param points data points to be written to file
1092- * @param board_w board width (used for formatting the file)
1093- * @param board_h board height (used for formatting the file)
1094- * @param filename path of the file
1095- */
1096- static void writeDataToFile(std::vector<std::vector<cv::Point3f>> points, int board_w, int board_h, std::string filename);
1097-
1098-private:
1099- /**
1100- * Compute the translation and rotation matrix from coordinate system x->y given a set of corresponding points
1101- * @param [in] x set of coordinates from the first coordinate system
1102- * @param [in] y set of corresponding coordinates from the second coordinate system
1103- * @param [out] R resultant rotation matrix
1104- * @param [out] t resultant translation matrix
1105- */
1106- static void computeRT(cv::Mat x, cv::Mat y, cv::Mat *R, cv::Mat *t);
1107-
1108+#pragma once
1109+// C++ Libaries
1110+#include <fstream>
1111+
1112+// OpenCV Libraries
1113+#include <opencv/cxcore.h>
1114+#include <opencv/highgui.h>
1115+#include "opencv2/calib3d/calib3d.hpp"
1116+#include "opencv2/highgui/highgui.hpp"
1117+#include <opencv2/video/tracking.hpp>
1118+#include "opencv2/imgproc/imgproc.hpp"
1119+#include <opencv2/objdetect/objdetect.hpp>
1120+#include <opencv2/features2d/features2d.hpp>
1121+
1122+// Eigen Libaries
1123+#include <Eigen/SVD>
1124+
1125+// OpenARK Libraries
1126+#include "Visualizer.h"
1127+#include "DepthCamera.h"
1128+#include "RGBCamera.h"
1129+#include "Util.h"
1130+
1131+/**
1132+* Class for various calibration operations.
1133+*/
1134+class Calibration
1135+{
1136+public:
1137+ /**
1138+ * Compute a calibration from (x,y,z) real world coordinates to (x',y',z') Unity coordinates.
1139+ * @param depth_cam instance of a live @see DepthCamera
1140+ * @param num_boards number of checkboard positions
1141+ * @param board_w width of the board (number of inner intersections)
1142+ * @param board_h height of the board (number of inner intersections)
1143+ */
1144+ static void XYZToUnity(DepthCamera& depth_cam, int num_boards, int board_w, int board_h);
1145+
1146+ /**
1147+ * Compute a calibration from (x,y,z) real world coordiantes to (i,j) RGB camera coordinates.
1148+ * @param depth_cam instance of a live @see DepthCamera
1149+ * @param rgb_cam instance of a live @see RGBCamera
1150+ * @param num_boards number of checkboard positions
1151+ * @param board_w width of the board (number of inner intersections)
1152+ * @param board_h height of the board (number of inner intersections)
1153+ */
1154+ static void XYZToRGB(DepthCamera* depth_cam, RGBCamera* rgb_cam, int num_boards, int board_w, int board_h);
1155+
1156+ /**
1157+ * Reproject the (x,y,z) points to (x',y',z') Unity points with the RT matrix to test for error.
1158+ * @param XYZ_points coordinates from the PMD sensor
1159+ * @param Unity_points coordinates from the game engine
1160+ * @param R the rotation matrix to use
1161+ * @param T the translation matrix to use
1162+ * @return cummulative reprojection error
1163+ */
1164+ static double reprojectXYZToUnity(std::vector<std::vector<cv::Point3f>> XYZ_points, std::vector<std::vector<cv::Point3f>> Unity_points, Eigen::MatrixXf R, Eigen::MatrixXf T);
1165+
1166+ /**
1167+ * Reproject the (x,y,z) points to (i,j) RGB image points with the RT matrix to test for error.
1168+ */
1169+ static double reprojectXYZtoRGB();
1170+
1171+ /**
1172+ * Compute full set of Unity checkboard coordinates.
1173+ * @param upper_left the upper left corner coordinates of the chessboard
1174+ * @param distance size of the checkerboard (meters)
1175+ * @param num_rows number of rows (inner intersections)
1176+ * @param num_cols number of columns (inner intersections)
1177+ */
1178+ static std::vector<std::vector<cv::Point3f>> prepareUnityData(std::vector<cv::Point3f> upper_left, float distance, int num_rows, int num_cols);
1179+
1180+ /**
1181+ * Write calibration data points to file
1182+ * @param points data points to be written to file
1183+ * @param board_w board width (used for formatting the file)
1184+ * @param board_h board height (used for formatting the file)
1185+ * @param filename path of the file
1186+ */
1187+ static void writeDataToFile(std::vector<std::vector<cv::Point3f>> points, int board_w, int board_h, std::string filename);
1188+
1189+private:
1190+ /**
1191+ * Compute the translation and rotation matrix from coordinate system x->y given a set of corresponding points
1192+ * @param [in] x set of coordinates from the first coordinate system
1193+ * @param [in] y set of corresponding coordinates from the second coordinate system
1194+ * @param [out] R resultant rotation matrix
1195+ * @param [out] t resultant translation matrix
1196+ */
1197+ static void computeRT(cv::Mat x, cv::Mat y, cv::Mat *R, cv::Mat *t);
1198+
1199 };
1200\ No newline at end of file
1201diff --git a/Converter.cpp b/Converter.cpp
1202deleted file mode 100644
1203index 718a81a..0000000
1204--- a/Converter.cpp
1205+++ /dev/null
1206@@ -1,65 +0,0 @@
1207-#include "Converter.h"
1208-
1209-
1210-/***
1211-Returns the next frame if next frame is recorded
1212-Returns the previous frame if next frame is not recorded
1213-***/
1214-void Converter::ConvertPXCImageToOpenCVMat(Intel::RealSense::Image *inImg, Intel::RealSense::ImageData data, cv::Mat *outImg) {
1215-
1216- int cvDataType;
1217- int cvDataWidth;
1218-
1219- Intel::RealSense::Image::ImageInfo imgInfo = inImg->QueryInfo();
1220-
1221- switch (data.format) {
1222- /* STREAM_TYPE_COLOR */
1223- case Intel::RealSense::Image::PIXEL_FORMAT_YUY2: /* YUY2 image */
1224- case Intel::RealSense::Image::PIXEL_FORMAT_NV12: /* NV12 image */
1225- throw(0); // Not implemented
1226- case Intel::RealSense::Image::PIXEL_FORMAT_RGB32: /* BGRA layout on a little-endian machine */
1227- cvDataType = CV_8UC4;
1228- cvDataWidth = 4;
1229- break;
1230- case Intel::RealSense::Image::PIXEL_FORMAT_RGB24: /* BGR layout on a little-endian machine */
1231- cvDataType = CV_8UC3;
1232- cvDataWidth = 3;
1233- break;
1234- case Intel::RealSense::Image::PIXEL_FORMAT_Y8: /* 8-Bit Gray Image, or IR 8-bit */
1235- cvDataType = CV_8U;
1236- cvDataWidth = 1;
1237- break;
1238-
1239- /* STREAM_TYPE_DEPTH */
1240- case Intel::RealSense::Image::PIXEL_FORMAT_DEPTH: /* 16-bit unsigned integer with precision mm. */
1241- case Intel::RealSense::Image::PIXEL_FORMAT_DEPTH_RAW: /* 16-bit unsigned integer with device specific precision (call device->QueryDepthUnit()) */
1242- cvDataType = CV_16U;
1243- cvDataWidth = 2;
1244- break;
1245- case Intel::RealSense::Image::PIXEL_FORMAT_DEPTH_F32: /* 32-bit float-point with precision mm. */
1246- cvDataType = CV_32F;
1247- cvDataWidth = 4;
1248- break;
1249-
1250- /* STREAM_TYPE_IR */
1251- case Intel::RealSense::Image::PIXEL_FORMAT_Y16: /* 16-Bit Gray Image */
1252- cvDataType = CV_16U;
1253- cvDataWidth = 2;
1254- break;
1255- case Intel::RealSense::Image::PIXEL_FORMAT_Y8_IR_RELATIVE: /* Relative IR Image */
1256- cvDataType = CV_8U;
1257- cvDataWidth = 1;
1258- break;
1259- }
1260-
1261- // suppose that no other planes
1262- if (data.planes[1] != NULL) throw(0); // not implemented
1263- // suppose that no sub pixel padding needed
1264- if (data.pitches[0] % cvDataWidth != 0) throw(0); // not implemented
1265-
1266- outImg->create(imgInfo.height, data.pitches[0] / cvDataWidth, cvDataType);
1267-
1268- //memcpy(outImg->data, data.planes[0], imgInfo.height*imgInfo.width*cvDataWidth * sizeof(pxcBYTE));
1269- memcpy(outImg->data, data.planes[0], imgInfo.height*imgInfo.width*cvDataWidth * sizeof(uint8_t));
1270-}
1271-
1272diff --git a/Converter.h b/Converter.h
1273deleted file mode 100644
1274index 265ee26..0000000
1275--- a/Converter.h
1276+++ /dev/null
1277@@ -1,29 +0,0 @@
1278-#pragma once
1279-//Intel RealSense 3D SDK libraries
1280-#include "RealSense/SenseManager.h"
1281-#include "RealSense/SampleReader.h"
1282-#include "RealSense/Session.h"
1283-
1284-//OpenCV libraries
1285-#include <opencv2/opencv.hpp>
1286-#include "opencv2/highgui/highgui.hpp"
1287-#include <opencv2/video/tracking.hpp>
1288-#include "opencv2/imgproc/imgproc.hpp"
1289-#include <opencv2/objdetect/objdetect.hpp>
1290-#include <opencv2/features2d/features2d.hpp>
1291-
1292-/**
1293-* Class for converting Intel RealSense images to OpenCV image format
1294-*/
1295-class Converter
1296-{
1297-public:
1298-
1299- /**
1300- * Converting an Intel RealSense 3D camera image to OpenCV image format
1301- * @param inImg input image
1302- * @param data Intel RealSense image data
1303- * @param outImg output image in form of OpenCV image
1304- */
1305- static void Converter::ConvertPXCImageToOpenCVMat(Intel::RealSense::Image *inImg, Intel::RealSense::ImageData data, cv::Mat *outImg);
1306-};
1307\ No newline at end of file
1308diff --git a/DepthCamera.cpp b/DepthCamera.cpp
1309index 2a67e46..18577db 100644
1310--- a/DepthCamera.cpp
1311+++ b/DepthCamera.cpp
1312@@ -1,198 +1,188 @@
1313-#include "DepthCamera.h"
1314-
1315-void DepthCamera::computeClusters(double max_distance, double min_size)
1316-{
1317- clusters.clear();
1318- cv::Mat depthMap = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
1319- cv::medianBlur(xyzMap, depthMap, 3);
1320- cv::Mat mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
1321- for (int r = depthMap.rows - 1; r >= 0; r--) {
1322- for (int c = 0; c < depthMap.cols; c++) {
1323- if (depthMap.at<cv::Vec3f>(r, c)[2] > 0.2) {
1324- mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
1325- floodFill(c, r, depthMap, mask, max_distance);
1326- cv::Mat channels[3];
1327- cv::split(mask, channels);
1328- if (cv::countNonZero(channels[2]) > min_size) {
1329- cv::medianBlur(mask, mask, 3);
1330- clusters.push_back(mask.clone());
1331- }
1332- }
1333- }
1334- }
1335-}
1336-
1337-/***
1338-Recursively performs floodfill on depthMap
1339-***/
1340-void DepthCamera::floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)
1341-{
1342- if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] == 0.0)
1343- return;
1344- if (closeEnough(x, y, depthMap, 4, max_distance)) {
1345- mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
1346- depthMap.at<cv::Vec3f>(y, x)[0] = 0;
1347- depthMap.at<cv::Vec3f>(y, x)[1] = 0;
1348- depthMap.at<cv::Vec3f>(y, x)[2] = 0;
1349- }
1350- else {
1351- return;
1352- }
1353-
1354- floodFill(x + 1, y, depthMap, mask, max_distance);
1355- floodFill(x - 1, y, depthMap, mask, max_distance);
1356- floodFill(x, y + 1, depthMap, mask, max_distance);
1357- floodFill(x, y - 1, depthMap, mask, max_distance);
1358-}
1359-
1360-/***
1361-Check whether candidate point is close enough to neighboring points
1362-***/
1363-bool DepthCamera::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)
1364-{
1365- int num_close = 0;
1366- if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) {
1367- num_close++;
1368- }
1369- if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) {
1370- num_close++;
1371- }
1372- if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) {
1373- num_close++;
1374- }
1375- if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) {
1376- num_close++;
1377- }
1378-
1379- if (num_close >= num_neighbors) {
1380- return true;
1381- }
1382-
1383- return false;
1384-}
1385-
1386-/***
1387-Remove noise on zMap and xyzMap based on INVALID_FLAG_VALUE and CONFIDENCE_THRESHOLD
1388-***/
1389-void DepthCamera::removeNoise() {
1390-
1391- for (int y = 0; y < xyzMap.rows; y++) {
1392- for (int x = 0; x < xyzMap.cols; x++) {
1393- if (ampMap.data != NULL) {
1394- if (xyzMap.at<cv::Vec3f>(y, x)[2] > 0.9f || ampMap.at<float>(y, x) < CONFIDENCE_THRESHHOLD) {
1395- xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
1396- xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
1397- xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
1398- }
1399- }
1400- else {
1401- if (xyzMap.at<cv::Vec3f>(y, x)[2] > 0.9f){
1402- xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
1403- xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
1404- xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
1405- }
1406- }
1407- }
1408- }
1409-
1410-
1411- cv::Mat channels[3];
1412- cv::split(xyzMap, channels);
1413- if ((float)cv::countNonZero(channels[2]) / (xyzMap.rows*xyzMap.cols) > 0.5) {
1414- badInput = true;
1415- }
1416- else {
1417- badInput = false;
1418- }
1419-
1420- return;
1421-}
1422-
1423-void DepthCamera::removePoints(std::vector<cv::Point2i> points)
1424-{
1425- for (int i = 0; i < points.size(); i++) {
1426- int x = points[i].x;
1427- int y = points[i].y;
1428- xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
1429- xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
1430- xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
1431- }
1432- return;
1433-}
1434-
1435-int DepthCamera::getWidth()
1436-{
1437- return X_DIMENSION;
1438-}
1439-
1440-int DepthCamera::getHeight()
1441-{
1442- return Y_DIMENSION;
1443-}
1444-
1445-cv::Mat DepthCamera::getXYZMap()
1446-{
1447- return xyzMap;
1448-}
1449-
1450-cv::Mat DepthCamera::getAmpMap()
1451-{
1452- return ampMap;
1453-}
1454-
1455-cv::Mat DepthCamera::getFlagMap()
1456-{
1457- return flagMap;
1458-}
1459-
1460-std::vector<cv::Mat> DepthCamera::getClusters()
1461-{
1462- return clusters;
1463-}
1464-
1465-void DepthCamera::initilizeImages()
1466-{
1467- cv::Size dimension = cv::Size(X_DIMENSION, Y_DIMENSION);
1468- ampMap = cv::Mat(dimension, CV_32FC1);
1469- xyzMap = cv::Mat(dimension, CV_32FC3);
1470- flagMap = cv::Mat(dimension, CV_8UC1);
1471- clusters.clear();
1472-
1473- return;
1474-}
1475-
1476-/***
1477-write a frame into file located at "destination"
1478-***/
1479-bool DepthCamera::writeImage(std::string destination) {
1480- cv::FileStorage fs(destination, cv::FileStorage::WRITE);
1481-
1482- fs << "xyzMap" << xyzMap;
1483- fs << "ampMap" << ampMap;
1484- fs << "flagMap" << flagMap;
1485-
1486- fs.release();
1487- return true;
1488-}
1489-
1490-/***
1491-Reads a frame from file located at "source"
1492-***/
1493-bool DepthCamera::readImage(std::string source) {
1494- cv::FileStorage fs;
1495- fs.open(source, cv::FileStorage::READ);
1496-
1497- initilizeImages();
1498- fs["xyzMap"] >> xyzMap;
1499- fs["ampMap"] >> ampMap;
1500- fs["flagMap"] >> flagMap;
1501-
1502- fs.release();
1503-
1504- if (xyzMap.rows == 0 || ampMap.rows == 0 || flagMap.rows == 0) {
1505- return false;
1506- }
1507- else {
1508- return true;
1509- }
1510+#include "DepthCamera.h"
1511+
1512+void DepthCamera::computeClusters(double max_distance, double min_size)
1513+{
1514+ clusters.clear();
1515+ cv::Mat depthMap = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
1516+ cv::medianBlur(xyzMap, depthMap, 3);
1517+ cv::Mat mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
1518+ for (int r = depthMap.rows - 1; r >= 0; r--) {
1519+ for (int c = 0; c < depthMap.cols; c++) {
1520+ if (depthMap.at<cv::Vec3f>(r, c)[2] > 0.2) {
1521+ mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
1522+ floodFill(c, r, depthMap, mask, max_distance);
1523+ cv::Mat channels[3];
1524+ cv::split(mask, channels);
1525+ if (cv::countNonZero(channels[2]) > min_size) {
1526+ cv::medianBlur(mask, mask, 3);
1527+ clusters.push_back(mask.clone());
1528+ }
1529+ }
1530+ }
1531+ }
1532+}
1533+
1534+/***
1535+Recursively performs floodfill on depthMap
1536+***/
1537+void DepthCamera::floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)
1538+{
1539+ if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] == 0.0)
1540+ return;
1541+ if (closeEnough(x, y, depthMap, 4, max_distance)) {
1542+ mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
1543+ depthMap.at<cv::Vec3f>(y, x)[0] = 0;
1544+ depthMap.at<cv::Vec3f>(y, x)[1] = 0;
1545+ depthMap.at<cv::Vec3f>(y, x)[2] = 0;
1546+ }
1547+ else {
1548+ return;
1549+ }
1550+
1551+ floodFill(x + 1, y, depthMap, mask, max_distance);
1552+ floodFill(x - 1, y, depthMap, mask, max_distance);
1553+ floodFill(x, y + 1, depthMap, mask, max_distance);
1554+ floodFill(x, y - 1, depthMap, mask, max_distance);
1555+}
1556+
1557+/***
1558+Check whether candidate point is close enough to neighboring points
1559+***/
1560+bool DepthCamera::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)
1561+{
1562+ int num_close = 0;
1563+ if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) {
1564+ num_close++;
1565+ }
1566+ if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) {
1567+ num_close++;
1568+ }
1569+ if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) {
1570+ num_close++;
1571+ }
1572+ if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) {
1573+ num_close++;
1574+ }
1575+
1576+ if (num_close >= num_neighbors) {
1577+ return true;
1578+ }
1579+
1580+ return false;
1581+}
1582+
1583+/***
1584+Remove noise on zMap and xyzMap based on INVALID_FLAG_VALUE and CONFIDENCE_THRESHOLD
1585+***/
1586+void DepthCamera::removeNoise() {
1587+
1588+ for (int y = 0; y < xyzMap.rows; y++) {
1589+ for (int x = 0; x < xyzMap.cols; x++) {
1590+ if (xyzMap.at<cv::Vec3f>(y, x)[2] > 0.9f || ampMap.at<float>(y, x) < CONFIDENCE_THRESHHOLD)
1591+ {
1592+ xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
1593+ xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
1594+ xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
1595+ }
1596+ }
1597+ }
1598+
1599+ cv::Mat channels[3];
1600+ cv::split(xyzMap, channels);
1601+ if ((float)cv::countNonZero(channels[2]) / (xyzMap.rows*xyzMap.cols) > 0.5) {
1602+ badInput = true;
1603+ } else {
1604+ badInput = false;
1605+ }
1606+
1607+ return;
1608+}
1609+
1610+void DepthCamera::removePoints(std::vector<cv::Point2i> points)
1611+{
1612+ for (int i = 0; i < points.size();i++) {
1613+ int x = points[i].x;
1614+ int y = points[i].y;
1615+ xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
1616+ xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
1617+ xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
1618+ }
1619+ return;
1620+}
1621+
1622+int DepthCamera::getWidth()
1623+{
1624+ return X_DIMENSION;
1625+}
1626+
1627+int DepthCamera::getHeight()
1628+{
1629+ return Y_DIMENSION;
1630+}
1631+
1632+cv::Mat DepthCamera::getXYZMap()
1633+{
1634+ return xyzMap;
1635+}
1636+
1637+cv::Mat DepthCamera::getAmpMap()
1638+{
1639+ return ampMap;
1640+}
1641+
1642+cv::Mat DepthCamera::getFlagMap()
1643+{
1644+ return flagMap;
1645+}
1646+
1647+std::vector<cv::Mat> DepthCamera::getClusters()
1648+{
1649+ return clusters;
1650+}
1651+
1652+void DepthCamera::initilizeImages()
1653+{
1654+ cv::Size dimension = cv::Size(X_DIMENSION, Y_DIMENSION);
1655+ ampMap = cv::Mat(dimension, CV_32FC1);
1656+ xyzMap = cv::Mat(dimension, CV_32FC3);
1657+ flagMap = cv::Mat(dimension, CV_8UC1);
1658+ clusters.clear();
1659+
1660+ return;
1661+}
1662+
1663+/***
1664+write a frame into file located at "destination"
1665+***/
1666+bool DepthCamera::writeImage(std::string destination) {
1667+ cv::FileStorage fs(destination, cv::FileStorage::WRITE);
1668+
1669+ fs << "xyzMap" << xyzMap;
1670+ fs << "ampMap" << ampMap;
1671+ fs << "flagMap" << flagMap;
1672+
1673+ fs.release();
1674+ return true;
1675+}
1676+
1677+/***
1678+Reads a frame from file located at "source"
1679+***/
1680+bool DepthCamera::readImage(std::string source) {
1681+ cv::FileStorage fs;
1682+ fs.open(source, cv::FileStorage::READ);
1683+
1684+ initilizeImages();
1685+ fs["xyzMap"] >> xyzMap;
1686+ fs["ampMap"] >> ampMap;
1687+ fs["flagMap"] >> flagMap;
1688+
1689+ fs.release();
1690+
1691+ if (xyzMap.rows == 0 || ampMap.rows == 0 || flagMap.rows == 0) {
1692+ return false;
1693+ }
1694+ else {
1695+ return true;
1696+ }
1697 }
1698\ No newline at end of file
1699diff --git a/DepthCamera.h b/DepthCamera.h
1700index e199060..4672faa 100644
1701--- a/DepthCamera.h
1702+++ b/DepthCamera.h
1703@@ -1,173 +1,173 @@
1704-#pragma once
1705-// C++ Libraries
1706-#include <iostream>
1707-
1708-// OpenCV Libraries
1709-#include "opencv2/highgui/highgui.hpp"
1710-#include <opencv2/video/tracking.hpp>
1711-#include "opencv2/imgproc/imgproc.hpp"
1712-#include <opencv2/objdetect/objdetect.hpp>
1713-#include <opencv2/features2d/features2d.hpp>
1714-
1715-// OpenARK Libraries
1716-#include "Util.h"
1717-
1718-/**
1719- * Class defining general behavior of a depth camera.
1720- * Any depth camera should be able to generate a XYXMap, AmpMap (confidence), and FlagMap.
1721- */
1722-class DepthCamera
1723-{
1724-public:
1725- /**
1726- * Update the depth camera by one frame.
1727- * This function should be overriden with a concrete implementation depending on the specific depth camera
1728- */
1729- virtual void update() = 0;
1730-
1731- /**
1732- * Closes and exists the depth camera.
1733- * This function should be overriden with a concrete implementation depending on the specific depth camera
1734- */
1735- virtual void destroyInstance() = 0;
1736-
1737- /**
1738- * Performs euclidean clustering to separate discrete objects in the input point cloud.
1739- * @param max_distance the maximum allowed distance to be clustered
1740- * @param min_size the minimum number of points a valid cluster should have
1741- */
1742- void computeClusters(double max_distance, double min_size);
1743-
1744- /**
1745- * Reads a sample frame from file.
1746- * @param source the directory which the frame file is stored
1747- */
1748- bool readImage(std::string source);
1749-
1750- /**
1751- * Writes the current frame into file.
1752- * @param destination the directory which the frame should be written to
1753- */
1754- bool writeImage(std::string destination);
1755-
1756- /**
1757- * Removes noise from the XYZMap based on confidence provided in the AmpMap and FlagMap.
1758- */
1759- void removeNoise();
1760-
1761- /**
1762- * Removes all points defined by the coordinates in the points vector from the XYZMap.
1763- * @param [in] points the list of coordinates where data from the XYZMap should be removed
1764- */
1765- void removePoints(std::vector<cv::Point2i> points);
1766-
1767- /**
1768- * Return the current XYZMap.
1769- */
1770- cv::Mat getXYZMap();
1771-
1772- /**
1773- * Return the current AmpMap
1774- */
1775- cv::Mat getAmpMap();
1776-
1777- /**
1778- * Return the current FlagMap.
1779- */
1780- cv::Mat getFlagMap();
1781-
1782- /**
1783- * Returns the width of the frame in pixels.
1784- */
1785- int getWidth();
1786-
1787- /**
1788- * Returns the height of the frame in pixels.
1789- */
1790- int getHeight();
1791-
1792- /**
1793- * Returns all the clusters (discrete objects) in the current frame.
1794- * @see computeClusters
1795- * @return vector of matrixes with each matrix corresponding to a cluster in no particular order
1796- */
1797- std::vector<cv::Mat> getClusters();
1798-
1799- bool badInput;
1800-
1801-
1802-protected:
1803- /**
1804- * Initializes all variables used by the generic depth camera.
1805- * Sets xyzMap, ampMap, flagMap, and clusters to empty
1806- */
1807- void initilizeImages();
1808-
1809- /**
1810- * Performs floodfill starting from seed point (x,y).
1811- * @param x x-coordinate of the seed point
1812- * @param y y-coordinate of the seed point
1813- * @param [in] zMap the xyzMap point cloud
1814- * @param [out] mask the resulting region of the floodfill
1815- * @param max_distance the maximum euclidean distance allowed between neighbors
1816- */
1817- void floodFill(int x, int y, cv::Mat& zMap, cv::Mat& mask, double max_distance);
1818-
1819- /**
1820- * Analyze the candidate point with its neighbors to determine whether they belong to the same cluster.
1821- * @param x x-coordinate of the candidate point
1822- * @param y y-coordinate of the candidate point
1823- * @param [in] depthMap the xyzMap point cloud of the scene
1824- * @param num_neighbors the number of neighbors to consider
1825- * @param max_distance the maximum euclidean distance allowed between neighbors
1826- */
1827- bool closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance);
1828-
1829- /**
1830- * Stores the (x,y,z) data of every point in the observable world.
1831- * Matrix type CV_32FC3
1832- */
1833- cv::Mat xyzMap;
1834-
1835- /**
1836- * Stores the confidence value of each corresponding point in the world.
1837- * Matrix type CV_32FC1
1838- */
1839- cv::Mat ampMap;
1840-
1841- /**
1842- * Stores additional information about the points in the world.
1843- * Matrix type CV_8UC1
1844- */
1845- cv::Mat flagMap;
1846-
1847- /**
1848- * Stores the each individual cluster in its individual XYZMap.
1849- */
1850- std::vector<cv::Mat> clusters;
1851-
1852- /**
1853- * Value that determines the validity of a point in respect to the ampMap.
1854- * This value varies from sensor to sensor so it should be define when constructing child class
1855- */
1856- double CONFIDENCE_THRESHHOLD;
1857-
1858- /**
1859- * Value that determines the validity of a point in respect to the flagMap.
1860- * This value varies from sensor to sensor so it should be defined when constructing child class
1861- */
1862- int INVALID_FLAG_VALUE;
1863-
1864- /**
1865- * The image width resolution (pixels) that the depth sensor produces.
1866- */
1867- //mona int X_DIMENSION = 176;
1868- int X_DIMENSION = 640;
1869-
1870-
1871- /**
1872- * The image height resolution (pixels) that the depth sensor produces.
1873- */
1874- //mona int Y_DIMENSION = 120;
1875- int Y_DIMENSION = 480;
1876+#pragma once
1877+
1878+// C++ Libraries
1879+#include <iostream>
1880+
1881+// OpenCV Libraries
1882+#include <opencv/cxcore.h>
1883+#include <opencv/highgui.h>
1884+#include "opencv2/highgui/highgui.hpp"
1885+#include <opencv2/video/tracking.hpp>
1886+#include "opencv2/imgproc/imgproc.hpp"
1887+#include <opencv2/objdetect/objdetect.hpp>
1888+#include <opencv2/features2d/features2d.hpp>
1889+
1890+// OpenARK Libraries
1891+#include "Util.h"
1892+
1893+/**
1894+ * Class defining general behavior of a depth camera.
1895+ * Any depth camera should be able to generate a XYXMap, AmpMap (confidence), and FlagMap.
1896+ */
1897+class DepthCamera
1898+{
1899+public:
1900+ /**
1901+ * Update the depth camera by one frame.
1902+ * This function should be overriden with a concrete implementation depending on the specific depth camera
1903+ */
1904+ virtual void update() = 0;
1905+
1906+ /**
1907+ * Closes and exists the depth camera.
1908+ * This function should be overriden with a concrete implementation depending on the specific depth camera
1909+ */
1910+ virtual void destroyInstance() = 0;
1911+
1912+ /**
1913+ * Performs euclidean clustering to separate discrete objects in the input point cloud.
1914+ * @param max_distance the maximum allowed distance to be clustered
1915+ * @param min_size the minimum number of points a valid cluster should have
1916+ */
1917+ void computeClusters(double max_distance, double min_size);
1918+
1919+ /**
1920+ * Reads a sample frame from file.
1921+ * @param source the directory which the frame file is stored
1922+ */
1923+ bool readImage(std::string source);
1924+
1925+ /**
1926+ * Writes the current frame into file.
1927+ * @param destination the directory which the frame should be written to
1928+ */
1929+ bool writeImage(std::string destination);
1930+
1931+ /**
1932+ * Removes noise from the XYZMap based on confidence provided in the AmpMap and FlagMap.
1933+ */
1934+ void removeNoise();
1935+
1936+ /**
1937+ * Removes all points defined by the coordinates in the points vector from the XYZMap.
1938+ * @param [in] points the list of coordinates where data from the XYZMap should be removed
1939+ */
1940+ void removePoints(std::vector<cv::Point2i> points);
1941+
1942+ /**
1943+ * Return the current XYZMap.
1944+ */
1945+ cv::Mat getXYZMap();
1946+
1947+ /**
1948+ * Return the current AmpMap
1949+ */
1950+ cv::Mat getAmpMap();
1951+
1952+ /**
1953+ * Return the current FlagMap.
1954+ */
1955+ cv::Mat getFlagMap();
1956+
1957+ /**
1958+ * Returns the width of the frame in pixels.
1959+ */
1960+ int getWidth();
1961+
1962+ /**
1963+ * Returns the height of the frame in pixels.
1964+ */
1965+ int getHeight();
1966+
1967+ /**
1968+ * Returns all the clusters (discrete objects) in the current frame.
1969+ * @see computeClusters
1970+ * @return vector of matrixes with each matrix corresponding to a cluster in no particular order
1971+ */
1972+ std::vector<cv::Mat> getClusters();
1973+
1974+ bool badInput;
1975+
1976+
1977+protected:
1978+ /**
1979+ * Initializes all variables used by the generic depth camera.
1980+ * Sets xyzMap, ampMap, flagMap, and clusters to empty
1981+ */
1982+ void initilizeImages();
1983+
1984+ /**
1985+ * Performs floodfill starting from seed point (x,y).
1986+ * @param x x-coordinate of the seed point
1987+ * @param y y-coordinate of the seed point
1988+ * @param [in] zMap the xyzMap point cloud
1989+ * @param [out] mask the resulting region of the floodfill
1990+ * @param max_distance the maximum euclidean distance allowed between neighbors
1991+ */
1992+ void floodFill(int x, int y, cv::Mat& zMap, cv::Mat& mask, double max_distance);
1993+
1994+ /**
1995+ * Analyze the candidate point with its neighbors to determine whether they belong to the same cluster.
1996+ * @param x x-coordinate of the candidate point
1997+ * @param y y-coordinate of the candidate point
1998+ * @param [in] depthMap the xyzMap point cloud of the scene
1999+ * @param num_neighbors the number of neighbors to consider
2000+ * @param max_distance the maximum euclidean distance allowed between neighbors
2001+ */
2002+ bool closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance);
2003+
2004+ /**
2005+ * Stores the (x,y,z) data of every point in the observable world.
2006+ * Matrix type CV_32FC3
2007+ */
2008+ cv::Mat xyzMap;
2009+
2010+ /**
2011+ * Stores the confidence value of each corresponding point in the world.
2012+ * Matrix type CV_32FC1
2013+ */
2014+ cv::Mat ampMap;
2015+
2016+ /**
2017+ * Stores additional information about the points in the world.
2018+ * Matrix type CV_8UC1
2019+ */
2020+ cv::Mat flagMap;
2021+
2022+ /**
2023+ * Stores the each individual cluster in its individual XYZMap.
2024+ */
2025+ std::vector<cv::Mat> clusters;
2026+
2027+ /**
2028+ * Value that determines the validity of a point in respect to the ampMap.
2029+ * This value varies from sensor to sensor so it should be define when constructing child class
2030+ */
2031+ double CONFIDENCE_THRESHHOLD;
2032+
2033+ /**
2034+ * Value that determines the validity of a point in respect to the flagMap.
2035+ * This value varies from sensor to sensor so it should be defined when constructing child class
2036+ */
2037+ int INVALID_FLAG_VALUE;
2038+
2039+ /**
2040+ * The image width resolution (pixels) that the depth sensor produces.
2041+ */
2042+ int X_DIMENSION = 176;
2043+
2044+ /**
2045+ * The image height resolution (pixels) that the depth sensor produces.
2046+ */
2047+ int Y_DIMENSION = 120;
2048 };
2049\ No newline at end of file
2050diff --git a/DoxygenConfig b/DoxygenConfig
2051index 17e8556..ee7aca3 100644
2052--- a/DoxygenConfig
2053+++ b/DoxygenConfig
2054@@ -1,2487 +1,2487 @@
2055-# Doxyfile 1.8.12
2056-
2057-# This file describes the settings to be used by the documentation system
2058-# doxygen (www.doxygen.org) for a project.
2059-#
2060-# All text after a double hash (##) is considered a comment and is placed in
2061-# front of the TAG it is preceding.
2062-#
2063-# All text after a single hash (#) is considered a comment and will be ignored.
2064-# The format is:
2065-# TAG = value [value, ...]
2066-# For lists, items can also be appended using:
2067-# TAG += value [value, ...]
2068-# Values that contain spaces should be placed between quotes (\" \").
2069-
2070-#---------------------------------------------------------------------------
2071-# Project related configuration options
2072-#---------------------------------------------------------------------------
2073-
2074-# This tag specifies the encoding used for all characters in the config file
2075-# that follow. The default is UTF-8 which is also the encoding used for all text
2076-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
2077-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
2078-# for the list of possible encodings.
2079-# The default value is: UTF-8.
2080-
2081-DOXYFILE_ENCODING = UTF-8
2082-
2083-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
2084-# double-quotes, unless you are using Doxywizard) that should identify the
2085-# project for which the documentation is generated. This name is used in the
2086-# title of most generated pages and in a few other places.
2087-# The default value is: My Project.
2088-
2089-PROJECT_NAME = "Open Augmented Reality Kit (OpenARK)"
2090-
2091-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
2092-# could be handy for archiving the generated documentation or if some version
2093-# control system is used.
2094-
2095-PROJECT_NUMBER = 0.8
2096-
2097-# Using the PROJECT_BRIEF tag one can provide an optional one line description
2098-# for a project that appears at the top of each page and should give viewer a
2099-# quick idea about the purpose of the project. Keep the description short.
2100-
2101-PROJECT_BRIEF = "Open-source wearable augmented reality (AR) system founded at UC Berkeley in 2016"
2102-
2103-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
2104-# in the documentation. The maximum height of the logo should not exceed 55
2105-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
2106-# the logo to the output directory.
2107-
2108-PROJECT_LOGO =
2109-
2110-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
2111-# into which the generated documentation will be written. If a relative path is
2112-# entered, it will be relative to the location where doxygen was started. If
2113-# left blank the current directory will be used.
2114-
2115-OUTPUT_DIRECTORY = D:\OpenARK-Documentation\0.8
2116-
2117-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
2118-# directories (in 2 levels) under the output directory of each output format and
2119-# will distribute the generated files over these directories. Enabling this
2120-# option can be useful when feeding doxygen a huge amount of source files, where
2121-# putting all generated files in the same directory would otherwise causes
2122-# performance problems for the file system.
2123-# The default value is: NO.
2124-
2125-CREATE_SUBDIRS = NO
2126-
2127-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
2128-# characters to appear in the names of generated files. If set to NO, non-ASCII
2129-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
2130-# U+3044.
2131-# The default value is: NO.
2132-
2133-ALLOW_UNICODE_NAMES = NO
2134-
2135-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
2136-# documentation generated by doxygen is written. Doxygen will use this
2137-# information to generate all constant output in the proper language.
2138-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
2139-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
2140-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
2141-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
2142-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
2143-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
2144-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
2145-# Ukrainian and Vietnamese.
2146-# The default value is: English.
2147-
2148-OUTPUT_LANGUAGE = English
2149-
2150-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
2151-# descriptions after the members that are listed in the file and class
2152-# documentation (similar to Javadoc). Set to NO to disable this.
2153-# The default value is: YES.
2154-
2155-BRIEF_MEMBER_DESC = YES
2156-
2157-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
2158-# description of a member or function before the detailed description
2159-#
2160-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
2161-# brief descriptions will be completely suppressed.
2162-# The default value is: YES.
2163-
2164-REPEAT_BRIEF = YES
2165-
2166-# This tag implements a quasi-intelligent brief description abbreviator that is
2167-# used to form the text in various listings. Each string in this list, if found
2168-# as the leading text of the brief description, will be stripped from the text
2169-# and the result, after processing the whole list, is used as the annotated
2170-# text. Otherwise, the brief description is used as-is. If left blank, the
2171-# following values are used ($name is automatically replaced with the name of
2172-# the entity):The $name class, The $name widget, The $name file, is, provides,
2173-# specifies, contains, represents, a, an and the.
2174-
2175-ABBREVIATE_BRIEF = "The $name class" \
2176- "The $name widget" \
2177- "The $name file" \
2178- is \
2179- provides \
2180- specifies \
2181- contains \
2182- represents \
2183- a \
2184- an \
2185- the
2186-
2187-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
2188-# doxygen will generate a detailed section even if there is only a brief
2189-# description.
2190-# The default value is: NO.
2191-
2192-ALWAYS_DETAILED_SEC = NO
2193-
2194-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
2195-# inherited members of a class in the documentation of that class as if those
2196-# members were ordinary class members. Constructors, destructors and assignment
2197-# operators of the base classes will not be shown.
2198-# The default value is: NO.
2199-
2200-INLINE_INHERITED_MEMB = NO
2201-
2202-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
2203-# before files name in the file list and in the header files. If set to NO the
2204-# shortest path that makes the file name unique will be used
2205-# The default value is: YES.
2206-
2207-FULL_PATH_NAMES = NO
2208-
2209-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
2210-# Stripping is only done if one of the specified strings matches the left-hand
2211-# part of the path. The tag can be used to show relative paths in the file list.
2212-# If left blank the directory from which doxygen is run is used as the path to
2213-# strip.
2214-#
2215-# Note that you can specify absolute paths here, but also relative paths, which
2216-# will be relative from the directory where doxygen is started.
2217-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
2218-
2219-STRIP_FROM_PATH =
2220-
2221-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
2222-# path mentioned in the documentation of a class, which tells the reader which
2223-# header file to include in order to use a class. If left blank only the name of
2224-# the header file containing the class definition is used. Otherwise one should
2225-# specify the list of include paths that are normally passed to the compiler
2226-# using the -I flag.
2227-
2228-STRIP_FROM_INC_PATH =
2229-
2230-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
2231-# less readable) file names. This can be useful is your file systems doesn't
2232-# support long names like on DOS, Mac, or CD-ROM.
2233-# The default value is: NO.
2234-
2235-SHORT_NAMES = NO
2236-
2237-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
2238-# first line (until the first dot) of a Javadoc-style comment as the brief
2239-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
2240-# style comments (thus requiring an explicit @brief command for a brief
2241-# description.)
2242-# The default value is: NO.
2243-
2244-JAVADOC_AUTOBRIEF = YES
2245-
2246-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
2247-# line (until the first dot) of a Qt-style comment as the brief description. If
2248-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
2249-# requiring an explicit \brief command for a brief description.)
2250-# The default value is: NO.
2251-
2252-QT_AUTOBRIEF = NO
2253-
2254-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
2255-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
2256-# a brief description. This used to be the default behavior. The new default is
2257-# to treat a multi-line C++ comment block as a detailed description. Set this
2258-# tag to YES if you prefer the old behavior instead.
2259-#
2260-# Note that setting this tag to YES also means that rational rose comments are
2261-# not recognized any more.
2262-# The default value is: NO.
2263-
2264-MULTILINE_CPP_IS_BRIEF = NO
2265-
2266-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
2267-# documentation from any documented member that it re-implements.
2268-# The default value is: YES.
2269-
2270-INHERIT_DOCS = YES
2271-
2272-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
2273-# page for each member. If set to NO, the documentation of a member will be part
2274-# of the file/class/namespace that contains it.
2275-# The default value is: NO.
2276-
2277-SEPARATE_MEMBER_PAGES = NO
2278-
2279-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
2280-# uses this value to replace tabs by spaces in code fragments.
2281-# Minimum value: 1, maximum value: 16, default value: 4.
2282-
2283-TAB_SIZE = 4
2284-
2285-# This tag can be used to specify a number of aliases that act as commands in
2286-# the documentation. An alias has the form:
2287-# name=value
2288-# For example adding
2289-# "sideeffect=@par Side Effects:\n"
2290-# will allow you to put the command \sideeffect (or @sideeffect) in the
2291-# documentation, which will result in a user-defined paragraph with heading
2292-# "Side Effects:". You can put \n's in the value part of an alias to insert
2293-# newlines.
2294-
2295-ALIASES =
2296-
2297-# This tag can be used to specify a number of word-keyword mappings (TCL only).
2298-# A mapping has the form "name=value". For example adding "class=itcl::class"
2299-# will allow you to use the command class in the itcl::class meaning.
2300-
2301-TCL_SUBST =
2302-
2303-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
2304-# only. Doxygen will then generate output that is more tailored for C. For
2305-# instance, some of the names that are used will be different. The list of all
2306-# members will be omitted, etc.
2307-# The default value is: NO.
2308-
2309-OPTIMIZE_OUTPUT_FOR_C = NO
2310-
2311-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
2312-# Python sources only. Doxygen will then generate output that is more tailored
2313-# for that language. For instance, namespaces will be presented as packages,
2314-# qualified scopes will look different, etc.
2315-# The default value is: NO.
2316-
2317-OPTIMIZE_OUTPUT_JAVA = NO
2318-
2319-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
2320-# sources. Doxygen will then generate output that is tailored for Fortran.
2321-# The default value is: NO.
2322-
2323-OPTIMIZE_FOR_FORTRAN = NO
2324-
2325-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
2326-# sources. Doxygen will then generate output that is tailored for VHDL.
2327-# The default value is: NO.
2328-
2329-OPTIMIZE_OUTPUT_VHDL = NO
2330-
2331-# Doxygen selects the parser to use depending on the extension of the files it
2332-# parses. With this tag you can assign which parser to use for a given
2333-# extension. Doxygen has a built-in mapping, but you can override or extend it
2334-# using this tag. The format is ext=language, where ext is a file extension, and
2335-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
2336-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
2337-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
2338-# Fortran. In the later case the parser tries to guess whether the code is fixed
2339-# or free formatted code, this is the default for Fortran type files), VHDL. For
2340-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
2341-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
2342-#
2343-# Note: For files without extension you can use no_extension as a placeholder.
2344-#
2345-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
2346-# the files are not read by doxygen.
2347-
2348-EXTENSION_MAPPING =
2349-
2350-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
2351-# according to the Markdown format, which allows for more readable
2352-# documentation. See http://daringfireball.net/projects/markdown/ for details.
2353-# The output of markdown processing is further processed by doxygen, so you can
2354-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
2355-# case of backward compatibilities issues.
2356-# The default value is: YES.
2357-
2358-MARKDOWN_SUPPORT = YES
2359-
2360-# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
2361-# to that level are automatically included in the table of contents, even if
2362-# they do not have an id attribute.
2363-# Note: This feature currently applies only to Markdown headings.
2364-# Minimum value: 0, maximum value: 99, default value: 0.
2365-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
2366-
2367-TOC_INCLUDE_HEADINGS = 0
2368-
2369-# When enabled doxygen tries to link words that correspond to documented
2370-# classes, or namespaces to their corresponding documentation. Such a link can
2371-# be prevented in individual cases by putting a % sign in front of the word or
2372-# globally by setting AUTOLINK_SUPPORT to NO.
2373-# The default value is: YES.
2374-
2375-AUTOLINK_SUPPORT = YES
2376-
2377-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
2378-# to include (a tag file for) the STL sources as input, then you should set this
2379-# tag to YES in order to let doxygen match functions declarations and
2380-# definitions whose arguments contain STL classes (e.g. func(std::string);
2381-# versus func(std::string) {}). This also make the inheritance and collaboration
2382-# diagrams that involve STL classes more complete and accurate.
2383-# The default value is: NO.
2384-
2385-BUILTIN_STL_SUPPORT = NO
2386-
2387-# If you use Microsoft's C++/CLI language, you should set this option to YES to
2388-# enable parsing support.
2389-# The default value is: NO.
2390-
2391-CPP_CLI_SUPPORT = NO
2392-
2393-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
2394-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
2395-# will parse them like normal C++ but will assume all classes use public instead
2396-# of private inheritance when no explicit protection keyword is present.
2397-# The default value is: NO.
2398-
2399-SIP_SUPPORT = NO
2400-
2401-# For Microsoft's IDL there are propget and propput attributes to indicate
2402-# getter and setter methods for a property. Setting this option to YES will make
2403-# doxygen to replace the get and set methods by a property in the documentation.
2404-# This will only work if the methods are indeed getting or setting a simple
2405-# type. If this is not the case, or you want to show the methods anyway, you
2406-# should set this option to NO.
2407-# The default value is: YES.
2408-
2409-IDL_PROPERTY_SUPPORT = YES
2410-
2411-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
2412-# tag is set to YES then doxygen will reuse the documentation of the first
2413-# member in the group (if any) for the other members of the group. By default
2414-# all members of a group must be documented explicitly.
2415-# The default value is: NO.
2416-
2417-DISTRIBUTE_GROUP_DOC = NO
2418-
2419-# If one adds a struct or class to a group and this option is enabled, then also
2420-# any nested class or struct is added to the same group. By default this option
2421-# is disabled and one has to add nested compounds explicitly via \ingroup.
2422-# The default value is: NO.
2423-
2424-GROUP_NESTED_COMPOUNDS = NO
2425-
2426-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
2427-# (for instance a group of public functions) to be put as a subgroup of that
2428-# type (e.g. under the Public Functions section). Set it to NO to prevent
2429-# subgrouping. Alternatively, this can be done per class using the
2430-# \nosubgrouping command.
2431-# The default value is: YES.
2432-
2433-SUBGROUPING = YES
2434-
2435-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
2436-# are shown inside the group in which they are included (e.g. using \ingroup)
2437-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
2438-# and RTF).
2439-#
2440-# Note that this feature does not work in combination with
2441-# SEPARATE_MEMBER_PAGES.
2442-# The default value is: NO.
2443-
2444-INLINE_GROUPED_CLASSES = NO
2445-
2446-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
2447-# with only public data fields or simple typedef fields will be shown inline in
2448-# the documentation of the scope in which they are defined (i.e. file,
2449-# namespace, or group documentation), provided this scope is documented. If set
2450-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
2451-# Man pages) or section (for LaTeX and RTF).
2452-# The default value is: NO.
2453-
2454-INLINE_SIMPLE_STRUCTS = NO
2455-
2456-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
2457-# enum is documented as struct, union, or enum with the name of the typedef. So
2458-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
2459-# with name TypeT. When disabled the typedef will appear as a member of a file,
2460-# namespace, or class. And the struct will be named TypeS. This can typically be
2461-# useful for C code in case the coding convention dictates that all compound
2462-# types are typedef'ed and only the typedef is referenced, never the tag name.
2463-# The default value is: NO.
2464-
2465-TYPEDEF_HIDES_STRUCT = NO
2466-
2467-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
2468-# cache is used to resolve symbols given their name and scope. Since this can be
2469-# an expensive process and often the same symbol appears multiple times in the
2470-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
2471-# doxygen will become slower. If the cache is too large, memory is wasted. The
2472-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
2473-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
2474-# symbols. At the end of a run doxygen will report the cache usage and suggest
2475-# the optimal cache size from a speed point of view.
2476-# Minimum value: 0, maximum value: 9, default value: 0.
2477-
2478-LOOKUP_CACHE_SIZE = 0
2479-
2480-#---------------------------------------------------------------------------
2481-# Build related configuration options
2482-#---------------------------------------------------------------------------
2483-
2484-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
2485-# documentation are documented, even if no documentation was available. Private
2486-# class members and static file members will be hidden unless the
2487-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
2488-# Note: This will also disable the warnings about undocumented members that are
2489-# normally produced when WARNINGS is set to YES.
2490-# The default value is: NO.
2491-
2492-EXTRACT_ALL = YES
2493-
2494-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
2495-# be included in the documentation.
2496-# The default value is: NO.
2497-
2498-EXTRACT_PRIVATE = YES
2499-
2500-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
2501-# scope will be included in the documentation.
2502-# The default value is: NO.
2503-
2504-EXTRACT_PACKAGE = NO
2505-
2506-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
2507-# included in the documentation.
2508-# The default value is: NO.
2509-
2510-EXTRACT_STATIC = YES
2511-
2512-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
2513-# locally in source files will be included in the documentation. If set to NO,
2514-# only classes defined in header files are included. Does not have any effect
2515-# for Java sources.
2516-# The default value is: YES.
2517-
2518-EXTRACT_LOCAL_CLASSES = YES
2519-
2520-# This flag is only useful for Objective-C code. If set to YES, local methods,
2521-# which are defined in the implementation section but not in the interface are
2522-# included in the documentation. If set to NO, only methods in the interface are
2523-# included.
2524-# The default value is: NO.
2525-
2526-EXTRACT_LOCAL_METHODS = NO
2527-
2528-# If this flag is set to YES, the members of anonymous namespaces will be
2529-# extracted and appear in the documentation as a namespace called
2530-# 'anonymous_namespace{file}', where file will be replaced with the base name of
2531-# the file that contains the anonymous namespace. By default anonymous namespace
2532-# are hidden.
2533-# The default value is: NO.
2534-
2535-EXTRACT_ANON_NSPACES = NO
2536-
2537-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
2538-# undocumented members inside documented classes or files. If set to NO these
2539-# members will be included in the various overviews, but no documentation
2540-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
2541-# The default value is: NO.
2542-
2543-HIDE_UNDOC_MEMBERS = NO
2544-
2545-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
2546-# undocumented classes that are normally visible in the class hierarchy. If set
2547-# to NO, these classes will be included in the various overviews. This option
2548-# has no effect if EXTRACT_ALL is enabled.
2549-# The default value is: NO.
2550-
2551-HIDE_UNDOC_CLASSES = NO
2552-
2553-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
2554-# (class|struct|union) declarations. If set to NO, these declarations will be
2555-# included in the documentation.
2556-# The default value is: NO.
2557-
2558-HIDE_FRIEND_COMPOUNDS = NO
2559-
2560-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
2561-# documentation blocks found inside the body of a function. If set to NO, these
2562-# blocks will be appended to the function's detailed documentation block.
2563-# The default value is: NO.
2564-
2565-HIDE_IN_BODY_DOCS = NO
2566-
2567-# The INTERNAL_DOCS tag determines if documentation that is typed after a
2568-# \internal command is included. If the tag is set to NO then the documentation
2569-# will be excluded. Set it to YES to include the internal documentation.
2570-# The default value is: NO.
2571-
2572-INTERNAL_DOCS = NO
2573-
2574-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
2575-# names in lower-case letters. If set to YES, upper-case letters are also
2576-# allowed. This is useful if you have classes or files whose names only differ
2577-# in case and if your file system supports case sensitive file names. Windows
2578-# and Mac users are advised to set this option to NO.
2579-# The default value is: system dependent.
2580-
2581-CASE_SENSE_NAMES = NO
2582-
2583-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
2584-# their full class and namespace scopes in the documentation. If set to YES, the
2585-# scope will be hidden.
2586-# The default value is: NO.
2587-
2588-HIDE_SCOPE_NAMES = NO
2589-
2590-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
2591-# append additional text to a page's title, such as Class Reference. If set to
2592-# YES the compound reference will be hidden.
2593-# The default value is: NO.
2594-
2595-HIDE_COMPOUND_REFERENCE= NO
2596-
2597-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
2598-# the files that are included by a file in the documentation of that file.
2599-# The default value is: YES.
2600-
2601-SHOW_INCLUDE_FILES = YES
2602-
2603-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
2604-# grouped member an include statement to the documentation, telling the reader
2605-# which file to include in order to use the member.
2606-# The default value is: NO.
2607-
2608-SHOW_GROUPED_MEMB_INC = NO
2609-
2610-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
2611-# files with double quotes in the documentation rather than with sharp brackets.
2612-# The default value is: NO.
2613-
2614-FORCE_LOCAL_INCLUDES = NO
2615-
2616-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
2617-# documentation for inline members.
2618-# The default value is: YES.
2619-
2620-INLINE_INFO = YES
2621-
2622-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
2623-# (detailed) documentation of file and class members alphabetically by member
2624-# name. If set to NO, the members will appear in declaration order.
2625-# The default value is: YES.
2626-
2627-SORT_MEMBER_DOCS = YES
2628-
2629-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
2630-# descriptions of file, namespace and class members alphabetically by member
2631-# name. If set to NO, the members will appear in declaration order. Note that
2632-# this will also influence the order of the classes in the class list.
2633-# The default value is: NO.
2634-
2635-SORT_BRIEF_DOCS = NO
2636-
2637-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
2638-# (brief and detailed) documentation of class members so that constructors and
2639-# destructors are listed first. If set to NO the constructors will appear in the
2640-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
2641-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
2642-# member documentation.
2643-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
2644-# detailed member documentation.
2645-# The default value is: NO.
2646-
2647-SORT_MEMBERS_CTORS_1ST = NO
2648-
2649-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
2650-# of group names into alphabetical order. If set to NO the group names will
2651-# appear in their defined order.
2652-# The default value is: NO.
2653-
2654-SORT_GROUP_NAMES = NO
2655-
2656-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
2657-# fully-qualified names, including namespaces. If set to NO, the class list will
2658-# be sorted only by class name, not including the namespace part.
2659-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
2660-# Note: This option applies only to the class list, not to the alphabetical
2661-# list.
2662-# The default value is: NO.
2663-
2664-SORT_BY_SCOPE_NAME = NO
2665-
2666-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
2667-# type resolution of all parameters of a function it will reject a match between
2668-# the prototype and the implementation of a member function even if there is
2669-# only one candidate or it is obvious which candidate to choose by doing a
2670-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
2671-# accept a match between prototype and implementation in such cases.
2672-# The default value is: NO.
2673-
2674-STRICT_PROTO_MATCHING = NO
2675-
2676-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
2677-# list. This list is created by putting \todo commands in the documentation.
2678-# The default value is: YES.
2679-
2680-GENERATE_TODOLIST = YES
2681-
2682-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
2683-# list. This list is created by putting \test commands in the documentation.
2684-# The default value is: YES.
2685-
2686-GENERATE_TESTLIST = YES
2687-
2688-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
2689-# list. This list is created by putting \bug commands in the documentation.
2690-# The default value is: YES.
2691-
2692-GENERATE_BUGLIST = YES
2693-
2694-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
2695-# the deprecated list. This list is created by putting \deprecated commands in
2696-# the documentation.
2697-# The default value is: YES.
2698-
2699-GENERATE_DEPRECATEDLIST= YES
2700-
2701-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
2702-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
2703-# ... \endcond blocks.
2704-
2705-ENABLED_SECTIONS =
2706-
2707-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
2708-# initial value of a variable or macro / define can have for it to appear in the
2709-# documentation. If the initializer consists of more lines than specified here
2710-# it will be hidden. Use a value of 0 to hide initializers completely. The
2711-# appearance of the value of individual variables and macros / defines can be
2712-# controlled using \showinitializer or \hideinitializer command in the
2713-# documentation regardless of this setting.
2714-# Minimum value: 0, maximum value: 10000, default value: 30.
2715-
2716-MAX_INITIALIZER_LINES = 30
2717-
2718-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
2719-# the bottom of the documentation of classes and structs. If set to YES, the
2720-# list will mention the files that were used to generate the documentation.
2721-# The default value is: YES.
2722-
2723-SHOW_USED_FILES = YES
2724-
2725-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
2726-# will remove the Files entry from the Quick Index and from the Folder Tree View
2727-# (if specified).
2728-# The default value is: YES.
2729-
2730-SHOW_FILES = YES
2731-
2732-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
2733-# page. This will remove the Namespaces entry from the Quick Index and from the
2734-# Folder Tree View (if specified).
2735-# The default value is: YES.
2736-
2737-SHOW_NAMESPACES = YES
2738-
2739-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
2740-# doxygen should invoke to get the current version for each file (typically from
2741-# the version control system). Doxygen will invoke the program by executing (via
2742-# popen()) the command command input-file, where command is the value of the
2743-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
2744-# by doxygen. Whatever the program writes to standard output is used as the file
2745-# version. For an example see the documentation.
2746-
2747-FILE_VERSION_FILTER =
2748-
2749-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
2750-# by doxygen. The layout file controls the global structure of the generated
2751-# output files in an output format independent way. To create the layout file
2752-# that represents doxygen's defaults, run doxygen with the -l option. You can
2753-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
2754-# will be used as the name of the layout file.
2755-#
2756-# Note that if you run doxygen from a directory containing a file called
2757-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
2758-# tag is left empty.
2759-
2760-LAYOUT_FILE =
2761-
2762-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
2763-# the reference definitions. This must be a list of .bib files. The .bib
2764-# extension is automatically appended if omitted. This requires the bibtex tool
2765-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
2766-# For LaTeX the style of the bibliography can be controlled using
2767-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
2768-# search path. See also \cite for info how to create references.
2769-
2770-CITE_BIB_FILES =
2771-
2772-#---------------------------------------------------------------------------
2773-# Configuration options related to warning and progress messages
2774-#---------------------------------------------------------------------------
2775-
2776-# The QUIET tag can be used to turn on/off the messages that are generated to
2777-# standard output by doxygen. If QUIET is set to YES this implies that the
2778-# messages are off.
2779-# The default value is: NO.
2780-
2781-QUIET = NO
2782-
2783-# The WARNINGS tag can be used to turn on/off the warning messages that are
2784-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
2785-# this implies that the warnings are on.
2786-#
2787-# Tip: Turn warnings on while writing the documentation.
2788-# The default value is: YES.
2789-
2790-WARNINGS = YES
2791-
2792-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
2793-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
2794-# will automatically be disabled.
2795-# The default value is: YES.
2796-
2797-WARN_IF_UNDOCUMENTED = YES
2798-
2799-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
2800-# potential errors in the documentation, such as not documenting some parameters
2801-# in a documented function, or documenting parameters that don't exist or using
2802-# markup commands wrongly.
2803-# The default value is: YES.
2804-
2805-WARN_IF_DOC_ERROR = YES
2806-
2807-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
2808-# are documented, but have no documentation for their parameters or return
2809-# value. If set to NO, doxygen will only warn about wrong or incomplete
2810-# parameter documentation, but not about the absence of documentation.
2811-# The default value is: NO.
2812-
2813-WARN_NO_PARAMDOC = NO
2814-
2815-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
2816-# a warning is encountered.
2817-# The default value is: NO.
2818-
2819-WARN_AS_ERROR = NO
2820-
2821-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
2822-# can produce. The string should contain the $file, $line, and $text tags, which
2823-# will be replaced by the file and line number from which the warning originated
2824-# and the warning text. Optionally the format may contain $version, which will
2825-# be replaced by the version of the file (if it could be obtained via
2826-# FILE_VERSION_FILTER)
2827-# The default value is: $file:$line: $text.
2828-
2829-WARN_FORMAT = "$file:$line: $text"
2830-
2831-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
2832-# messages should be written. If left blank the output is written to standard
2833-# error (stderr).
2834-
2835-WARN_LOGFILE =
2836-
2837-#---------------------------------------------------------------------------
2838-# Configuration options related to the input files
2839-#---------------------------------------------------------------------------
2840-
2841-# The INPUT tag is used to specify the files and/or directories that contain
2842-# documented source files. You may enter file names like myfile.cpp or
2843-# directories like /usr/src/myproject. Separate the files or directories with
2844-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
2845-# Note: If this tag is empty the current directory is searched.
2846-
2847-INPUT = D:\OpenARK
2848-
2849-# This tag can be used to specify the character encoding of the source files
2850-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
2851-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
2852-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
2853-# possible encodings.
2854-# The default value is: UTF-8.
2855-
2856-INPUT_ENCODING = UTF-8
2857-
2858-# If the value of the INPUT tag contains directories, you can use the
2859-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
2860-# *.h) to filter out the source-files in the directories.
2861-#
2862-# Note that for custom extensions or not directly supported extensions you also
2863-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
2864-# read by doxygen.
2865-#
2866-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
2867-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
2868-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
2869-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
2870-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
2871-
2872-FILE_PATTERNS = *.c \
2873- *.cc \
2874- *.cxx \
2875- *.cpp \
2876- *.c++ \
2877- *.java \
2878- *.ii \
2879- *.ixx \
2880- *.ipp \
2881- *.i++ \
2882- *.inl \
2883- *.idl \
2884- *.ddl \
2885- *.odl \
2886- *.h \
2887- *.hh \
2888- *.hxx \
2889- *.hpp \
2890- *.h++ \
2891- *.cs \
2892- *.d \
2893- *.php \
2894- *.php4 \
2895- *.php5 \
2896- *.phtml \
2897- *.inc \
2898- *.m \
2899- *.markdown \
2900- *.md \
2901- *.mm \
2902- *.dox \
2903- *.py \
2904- *.pyw \
2905- *.f90 \
2906- *.f95 \
2907- *.f03 \
2908- *.f08 \
2909- *.f \
2910- *.for \
2911- *.tcl \
2912- *.vhd \
2913- *.vhdl \
2914- *.ucf \
2915- *.qsf
2916-
2917-# The RECURSIVE tag can be used to specify whether or not subdirectories should
2918-# be searched for input files as well.
2919-# The default value is: NO.
2920-
2921-RECURSIVE = YES
2922-
2923-# The EXCLUDE tag can be used to specify files and/or directories that should be
2924-# excluded from the INPUT source files. This way you can easily exclude a
2925-# subdirectory from a directory tree whose root is specified with the INPUT tag.
2926-#
2927-# Note that relative paths are relative to the directory from which doxygen is
2928-# run.
2929-
2930-EXCLUDE = D:\OpenARK\SampleCode
2931-
2932-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
2933-# directories that are symbolic links (a Unix file system feature) are excluded
2934-# from the input.
2935-# The default value is: NO.
2936-
2937-EXCLUDE_SYMLINKS = NO
2938-
2939-# If the value of the INPUT tag contains directories, you can use the
2940-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
2941-# certain files from those directories.
2942-#
2943-# Note that the wildcards are matched against the file with absolute path, so to
2944-# exclude all test directories for example use the pattern */test/*
2945-
2946-EXCLUDE_PATTERNS =
2947-
2948-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
2949-# (namespaces, classes, functions, etc.) that should be excluded from the
2950-# output. The symbol name can be a fully qualified name, a word, or if the
2951-# wildcard * is used, a substring. Examples: ANamespace, AClass,
2952-# AClass::ANamespace, ANamespace::*Test
2953-#
2954-# Note that the wildcards are matched against the file with absolute path, so to
2955-# exclude all test directories use the pattern */test/*
2956-
2957-EXCLUDE_SYMBOLS =
2958-
2959-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
2960-# that contain example code fragments that are included (see the \include
2961-# command).
2962-
2963-EXAMPLE_PATH = D:\OpenARK\SampleCode
2964-
2965-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
2966-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
2967-# *.h) to filter out the source-files in the directories. If left blank all
2968-# files are included.
2969-
2970-EXAMPLE_PATTERNS = *
2971-
2972-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
2973-# searched for input files to be used with the \include or \dontinclude commands
2974-# irrespective of the value of the RECURSIVE tag.
2975-# The default value is: NO.
2976-
2977-EXAMPLE_RECURSIVE = YES
2978-
2979-# The IMAGE_PATH tag can be used to specify one or more files or directories
2980-# that contain images that are to be included in the documentation (see the
2981-# \image command).
2982-
2983-IMAGE_PATH =
2984-
2985-# The INPUT_FILTER tag can be used to specify a program that doxygen should
2986-# invoke to filter for each input file. Doxygen will invoke the filter program
2987-# by executing (via popen()) the command:
2988-#
2989-# <filter> <input-file>
2990-#
2991-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
2992-# name of an input file. Doxygen will then use the output that the filter
2993-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
2994-# will be ignored.
2995-#
2996-# Note that the filter must not add or remove lines; it is applied before the
2997-# code is scanned, but not when the output code is generated. If lines are added
2998-# or removed, the anchors will not be placed correctly.
2999-#
3000-# Note that for custom extensions or not directly supported extensions you also
3001-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
3002-# properly processed by doxygen.
3003-
3004-INPUT_FILTER =
3005-
3006-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
3007-# basis. Doxygen will compare the file name with each pattern and apply the
3008-# filter if there is a match. The filters are a list of the form: pattern=filter
3009-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
3010-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
3011-# patterns match the file name, INPUT_FILTER is applied.
3012-#
3013-# Note that for custom extensions or not directly supported extensions you also
3014-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
3015-# properly processed by doxygen.
3016-
3017-FILTER_PATTERNS =
3018-
3019-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
3020-# INPUT_FILTER) will also be used to filter the input files that are used for
3021-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
3022-# The default value is: NO.
3023-
3024-FILTER_SOURCE_FILES = NO
3025-
3026-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
3027-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
3028-# it is also possible to disable source filtering for a specific pattern using
3029-# *.ext= (so without naming a filter).
3030-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
3031-
3032-FILTER_SOURCE_PATTERNS =
3033-
3034-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
3035-# is part of the input, its contents will be placed on the main page
3036-# (index.html). This can be useful if you have a project on for instance GitHub
3037-# and want to reuse the introduction page also for the doxygen output.
3038-
3039-USE_MDFILE_AS_MAINPAGE =
3040-
3041-#---------------------------------------------------------------------------
3042-# Configuration options related to source browsing
3043-#---------------------------------------------------------------------------
3044-
3045-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
3046-# generated. Documented entities will be cross-referenced with these sources.
3047-#
3048-# Note: To get rid of all source code in the generated output, make sure that
3049-# also VERBATIM_HEADERS is set to NO.
3050-# The default value is: NO.
3051-
3052-SOURCE_BROWSER = NO
3053-
3054-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
3055-# classes and enums directly into the documentation.
3056-# The default value is: NO.
3057-
3058-INLINE_SOURCES = NO
3059-
3060-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
3061-# special comment blocks from generated source code fragments. Normal C, C++ and
3062-# Fortran comments will always remain visible.
3063-# The default value is: YES.
3064-
3065-STRIP_CODE_COMMENTS = YES
3066-
3067-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
3068-# function all documented functions referencing it will be listed.
3069-# The default value is: NO.
3070-
3071-REFERENCED_BY_RELATION = NO
3072-
3073-# If the REFERENCES_RELATION tag is set to YES then for each documented function
3074-# all documented entities called/used by that function will be listed.
3075-# The default value is: NO.
3076-
3077-REFERENCES_RELATION = NO
3078-
3079-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
3080-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
3081-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
3082-# link to the documentation.
3083-# The default value is: YES.
3084-
3085-REFERENCES_LINK_SOURCE = YES
3086-
3087-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
3088-# source code will show a tooltip with additional information such as prototype,
3089-# brief description and links to the definition and documentation. Since this
3090-# will make the HTML file larger and loading of large files a bit slower, you
3091-# can opt to disable this feature.
3092-# The default value is: YES.
3093-# This tag requires that the tag SOURCE_BROWSER is set to YES.
3094-
3095-SOURCE_TOOLTIPS = YES
3096-
3097-# If the USE_HTAGS tag is set to YES then the references to source code will
3098-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
3099-# source browser. The htags tool is part of GNU's global source tagging system
3100-# (see http://www.gnu.org/software/global/global.html). You will need version
3101-# 4.8.6 or higher.
3102-#
3103-# To use it do the following:
3104-# - Install the latest version of global
3105-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
3106-# - Make sure the INPUT points to the root of the source tree
3107-# - Run doxygen as normal
3108-#
3109-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
3110-# tools must be available from the command line (i.e. in the search path).
3111-#
3112-# The result: instead of the source browser generated by doxygen, the links to
3113-# source code will now point to the output of htags.
3114-# The default value is: NO.
3115-# This tag requires that the tag SOURCE_BROWSER is set to YES.
3116-
3117-USE_HTAGS = NO
3118-
3119-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
3120-# verbatim copy of the header file for each class for which an include is
3121-# specified. Set to NO to disable this.
3122-# See also: Section \class.
3123-# The default value is: YES.
3124-
3125-VERBATIM_HEADERS = YES
3126-
3127-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
3128-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
3129-# cost of reduced performance. This can be particularly helpful with template
3130-# rich C++ code for which doxygen's built-in parser lacks the necessary type
3131-# information.
3132-# Note: The availability of this option depends on whether or not doxygen was
3133-# generated with the -Duse-libclang=ON option for CMake.
3134-# The default value is: NO.
3135-
3136-CLANG_ASSISTED_PARSING = NO
3137-
3138-# If clang assisted parsing is enabled you can provide the compiler with command
3139-# line options that you would normally use when invoking the compiler. Note that
3140-# the include paths will already be set by doxygen for the files and directories
3141-# specified with INPUT and INCLUDE_PATH.
3142-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
3143-
3144-CLANG_OPTIONS =
3145-
3146-#---------------------------------------------------------------------------
3147-# Configuration options related to the alphabetical class index
3148-#---------------------------------------------------------------------------
3149-
3150-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
3151-# compounds will be generated. Enable this if the project contains a lot of
3152-# classes, structs, unions or interfaces.
3153-# The default value is: YES.
3154-
3155-ALPHABETICAL_INDEX = YES
3156-
3157-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
3158-# which the alphabetical index list will be split.
3159-# Minimum value: 1, maximum value: 20, default value: 5.
3160-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
3161-
3162-COLS_IN_ALPHA_INDEX = 5
3163-
3164-# In case all classes in a project start with a common prefix, all classes will
3165-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
3166-# can be used to specify a prefix (or a list of prefixes) that should be ignored
3167-# while generating the index headers.
3168-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
3169-
3170-IGNORE_PREFIX =
3171-
3172-#---------------------------------------------------------------------------
3173-# Configuration options related to the HTML output
3174-#---------------------------------------------------------------------------
3175-
3176-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
3177-# The default value is: YES.
3178-
3179-GENERATE_HTML = YES
3180-
3181-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
3182-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
3183-# it.
3184-# The default directory is: html.
3185-# This tag requires that the tag GENERATE_HTML is set to YES.
3186-
3187-HTML_OUTPUT = html
3188-
3189-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
3190-# generated HTML page (for example: .htm, .php, .asp).
3191-# The default value is: .html.
3192-# This tag requires that the tag GENERATE_HTML is set to YES.
3193-
3194-HTML_FILE_EXTENSION = .html
3195-
3196-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
3197-# each generated HTML page. If the tag is left blank doxygen will generate a
3198-# standard header.
3199-#
3200-# To get valid HTML the header file that includes any scripts and style sheets
3201-# that doxygen needs, which is dependent on the configuration options used (e.g.
3202-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
3203-# default header using
3204-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
3205-# YourConfigFile
3206-# and then modify the file new_header.html. See also section "Doxygen usage"
3207-# for information on how to generate the default header that doxygen normally
3208-# uses.
3209-# Note: The header is subject to change so you typically have to regenerate the
3210-# default header when upgrading to a newer version of doxygen. For a description
3211-# of the possible markers and block names see the documentation.
3212-# This tag requires that the tag GENERATE_HTML is set to YES.
3213-
3214-HTML_HEADER =
3215-
3216-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
3217-# generated HTML page. If the tag is left blank doxygen will generate a standard
3218-# footer. See HTML_HEADER for more information on how to generate a default
3219-# footer and what special commands can be used inside the footer. See also
3220-# section "Doxygen usage" for information on how to generate the default footer
3221-# that doxygen normally uses.
3222-# This tag requires that the tag GENERATE_HTML is set to YES.
3223-
3224-HTML_FOOTER =
3225-
3226-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
3227-# sheet that is used by each HTML page. It can be used to fine-tune the look of
3228-# the HTML output. If left blank doxygen will generate a default style sheet.
3229-# See also section "Doxygen usage" for information on how to generate the style
3230-# sheet that doxygen normally uses.
3231-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
3232-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
3233-# obsolete.
3234-# This tag requires that the tag GENERATE_HTML is set to YES.
3235-
3236-HTML_STYLESHEET =
3237-
3238-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
3239-# cascading style sheets that are included after the standard style sheets
3240-# created by doxygen. Using this option one can overrule certain style aspects.
3241-# This is preferred over using HTML_STYLESHEET since it does not replace the
3242-# standard style sheet and is therefore more robust against future updates.
3243-# Doxygen will copy the style sheet files to the output directory.
3244-# Note: The order of the extra style sheet files is of importance (e.g. the last
3245-# style sheet in the list overrules the setting of the previous ones in the
3246-# list). For an example see the documentation.
3247-# This tag requires that the tag GENERATE_HTML is set to YES.
3248-
3249-HTML_EXTRA_STYLESHEET =
3250-
3251-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
3252-# other source files which should be copied to the HTML output directory. Note
3253-# that these files will be copied to the base HTML output directory. Use the
3254-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
3255-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
3256-# files will be copied as-is; there are no commands or markers available.
3257-# This tag requires that the tag GENERATE_HTML is set to YES.
3258-
3259-HTML_EXTRA_FILES =
3260-
3261-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
3262-# will adjust the colors in the style sheet and background images according to
3263-# this color. Hue is specified as an angle on a colorwheel, see
3264-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
3265-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
3266-# purple, and 360 is red again.
3267-# Minimum value: 0, maximum value: 359, default value: 220.
3268-# This tag requires that the tag GENERATE_HTML is set to YES.
3269-
3270-HTML_COLORSTYLE_HUE = 220
3271-
3272-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
3273-# in the HTML output. For a value of 0 the output will use grayscales only. A
3274-# value of 255 will produce the most vivid colors.
3275-# Minimum value: 0, maximum value: 255, default value: 100.
3276-# This tag requires that the tag GENERATE_HTML is set to YES.
3277-
3278-HTML_COLORSTYLE_SAT = 100
3279-
3280-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
3281-# luminance component of the colors in the HTML output. Values below 100
3282-# gradually make the output lighter, whereas values above 100 make the output
3283-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
3284-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
3285-# change the gamma.
3286-# Minimum value: 40, maximum value: 240, default value: 80.
3287-# This tag requires that the tag GENERATE_HTML is set to YES.
3288-
3289-HTML_COLORSTYLE_GAMMA = 80
3290-
3291-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
3292-# page will contain the date and time when the page was generated. Setting this
3293-# to YES can help to show when doxygen was last run and thus if the
3294-# documentation is up to date.
3295-# The default value is: NO.
3296-# This tag requires that the tag GENERATE_HTML is set to YES.
3297-
3298-HTML_TIMESTAMP = NO
3299-
3300-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
3301-# documentation will contain sections that can be hidden and shown after the
3302-# page has loaded.
3303-# The default value is: NO.
3304-# This tag requires that the tag GENERATE_HTML is set to YES.
3305-
3306-HTML_DYNAMIC_SECTIONS = NO
3307-
3308-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
3309-# shown in the various tree structured indices initially; the user can expand
3310-# and collapse entries dynamically later on. Doxygen will expand the tree to
3311-# such a level that at most the specified number of entries are visible (unless
3312-# a fully collapsed tree already exceeds this amount). So setting the number of
3313-# entries 1 will produce a full collapsed tree by default. 0 is a special value
3314-# representing an infinite number of entries and will result in a full expanded
3315-# tree by default.
3316-# Minimum value: 0, maximum value: 9999, default value: 100.
3317-# This tag requires that the tag GENERATE_HTML is set to YES.
3318-
3319-HTML_INDEX_NUM_ENTRIES = 100
3320-
3321-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
3322-# generated that can be used as input for Apple's Xcode 3 integrated development
3323-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
3324-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
3325-# Makefile in the HTML output directory. Running make will produce the docset in
3326-# that directory and running make install will install the docset in
3327-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
3328-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
3329-# for more information.
3330-# The default value is: NO.
3331-# This tag requires that the tag GENERATE_HTML is set to YES.
3332-
3333-GENERATE_DOCSET = NO
3334-
3335-# This tag determines the name of the docset feed. A documentation feed provides
3336-# an umbrella under which multiple documentation sets from a single provider
3337-# (such as a company or product suite) can be grouped.
3338-# The default value is: Doxygen generated docs.
3339-# This tag requires that the tag GENERATE_DOCSET is set to YES.
3340-
3341-DOCSET_FEEDNAME = "Doxygen generated docs"
3342-
3343-# This tag specifies a string that should uniquely identify the documentation
3344-# set bundle. This should be a reverse domain-name style string, e.g.
3345-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
3346-# The default value is: org.doxygen.Project.
3347-# This tag requires that the tag GENERATE_DOCSET is set to YES.
3348-
3349-DOCSET_BUNDLE_ID = org.doxygen.Project
3350-
3351-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
3352-# the documentation publisher. This should be a reverse domain-name style
3353-# string, e.g. com.mycompany.MyDocSet.documentation.
3354-# The default value is: org.doxygen.Publisher.
3355-# This tag requires that the tag GENERATE_DOCSET is set to YES.
3356-
3357-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
3358-
3359-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
3360-# The default value is: Publisher.
3361-# This tag requires that the tag GENERATE_DOCSET is set to YES.
3362-
3363-DOCSET_PUBLISHER_NAME = Publisher
3364-
3365-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
3366-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
3367-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
3368-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
3369-# Windows.
3370-#
3371-# The HTML Help Workshop contains a compiler that can convert all HTML output
3372-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
3373-# files are now used as the Windows 98 help format, and will replace the old
3374-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
3375-# HTML files also contain an index, a table of contents, and you can search for
3376-# words in the documentation. The HTML workshop also contains a viewer for
3377-# compressed HTML files.
3378-# The default value is: NO.
3379-# This tag requires that the tag GENERATE_HTML is set to YES.
3380-
3381-GENERATE_HTMLHELP = NO
3382-
3383-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
3384-# file. You can add a path in front of the file if the result should not be
3385-# written to the html output directory.
3386-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
3387-
3388-CHM_FILE =
3389-
3390-# The HHC_LOCATION tag can be used to specify the location (absolute path
3391-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
3392-# doxygen will try to run the HTML help compiler on the generated index.hhp.
3393-# The file has to be specified with full path.
3394-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
3395-
3396-HHC_LOCATION =
3397-
3398-# The GENERATE_CHI flag controls if a separate .chi index file is generated
3399-# (YES) or that it should be included in the master .chm file (NO).
3400-# The default value is: NO.
3401-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
3402-
3403-GENERATE_CHI = NO
3404-
3405-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
3406-# and project file content.
3407-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
3408-
3409-CHM_INDEX_ENCODING =
3410-
3411-# The BINARY_TOC flag controls whether a binary table of contents is generated
3412-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
3413-# enables the Previous and Next buttons.
3414-# The default value is: NO.
3415-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
3416-
3417-BINARY_TOC = NO
3418-
3419-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
3420-# the table of contents of the HTML help documentation and to the tree view.
3421-# The default value is: NO.
3422-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
3423-
3424-TOC_EXPAND = NO
3425-
3426-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
3427-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
3428-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
3429-# (.qch) of the generated HTML documentation.
3430-# The default value is: NO.
3431-# This tag requires that the tag GENERATE_HTML is set to YES.
3432-
3433-GENERATE_QHP = NO
3434-
3435-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
3436-# the file name of the resulting .qch file. The path specified is relative to
3437-# the HTML output folder.
3438-# This tag requires that the tag GENERATE_QHP is set to YES.
3439-
3440-QCH_FILE =
3441-
3442-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
3443-# Project output. For more information please see Qt Help Project / Namespace
3444-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
3445-# The default value is: org.doxygen.Project.
3446-# This tag requires that the tag GENERATE_QHP is set to YES.
3447-
3448-QHP_NAMESPACE = org.doxygen.Project
3449-
3450-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
3451-# Help Project output. For more information please see Qt Help Project / Virtual
3452-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
3453-# folders).
3454-# The default value is: doc.
3455-# This tag requires that the tag GENERATE_QHP is set to YES.
3456-
3457-QHP_VIRTUAL_FOLDER = doc
3458-
3459-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
3460-# filter to add. For more information please see Qt Help Project / Custom
3461-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
3462-# filters).
3463-# This tag requires that the tag GENERATE_QHP is set to YES.
3464-
3465-QHP_CUST_FILTER_NAME =
3466-
3467-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
3468-# custom filter to add. For more information please see Qt Help Project / Custom
3469-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
3470-# filters).
3471-# This tag requires that the tag GENERATE_QHP is set to YES.
3472-
3473-QHP_CUST_FILTER_ATTRS =
3474-
3475-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
3476-# project's filter section matches. Qt Help Project / Filter Attributes (see:
3477-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
3478-# This tag requires that the tag GENERATE_QHP is set to YES.
3479-
3480-QHP_SECT_FILTER_ATTRS =
3481-
3482-# The QHG_LOCATION tag can be used to specify the location of Qt's
3483-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
3484-# generated .qhp file.
3485-# This tag requires that the tag GENERATE_QHP is set to YES.
3486-
3487-QHG_LOCATION =
3488-
3489-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
3490-# generated, together with the HTML files, they form an Eclipse help plugin. To
3491-# install this plugin and make it available under the help contents menu in
3492-# Eclipse, the contents of the directory containing the HTML and XML files needs
3493-# to be copied into the plugins directory of eclipse. The name of the directory
3494-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
3495-# After copying Eclipse needs to be restarted before the help appears.
3496-# The default value is: NO.
3497-# This tag requires that the tag GENERATE_HTML is set to YES.
3498-
3499-GENERATE_ECLIPSEHELP = NO
3500-
3501-# A unique identifier for the Eclipse help plugin. When installing the plugin
3502-# the directory name containing the HTML and XML files should also have this
3503-# name. Each documentation set should have its own identifier.
3504-# The default value is: org.doxygen.Project.
3505-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
3506-
3507-ECLIPSE_DOC_ID = org.doxygen.Project
3508-
3509-# If you want full control over the layout of the generated HTML pages it might
3510-# be necessary to disable the index and replace it with your own. The
3511-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
3512-# of each HTML page. A value of NO enables the index and the value YES disables
3513-# it. Since the tabs in the index contain the same information as the navigation
3514-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
3515-# The default value is: NO.
3516-# This tag requires that the tag GENERATE_HTML is set to YES.
3517-
3518-DISABLE_INDEX = NO
3519-
3520-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
3521-# structure should be generated to display hierarchical information. If the tag
3522-# value is set to YES, a side panel will be generated containing a tree-like
3523-# index structure (just like the one that is generated for HTML Help). For this
3524-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
3525-# (i.e. any modern browser). Windows users are probably better off using the
3526-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
3527-# further fine-tune the look of the index. As an example, the default style
3528-# sheet generated by doxygen has an example that shows how to put an image at
3529-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
3530-# the same information as the tab index, you could consider setting
3531-# DISABLE_INDEX to YES when enabling this option.
3532-# The default value is: NO.
3533-# This tag requires that the tag GENERATE_HTML is set to YES.
3534-
3535-GENERATE_TREEVIEW = YES
3536-
3537-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
3538-# doxygen will group on one line in the generated HTML documentation.
3539-#
3540-# Note that a value of 0 will completely suppress the enum values from appearing
3541-# in the overview section.
3542-# Minimum value: 0, maximum value: 20, default value: 4.
3543-# This tag requires that the tag GENERATE_HTML is set to YES.
3544-
3545-ENUM_VALUES_PER_LINE = 4
3546-
3547-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
3548-# to set the initial width (in pixels) of the frame in which the tree is shown.
3549-# Minimum value: 0, maximum value: 1500, default value: 250.
3550-# This tag requires that the tag GENERATE_HTML is set to YES.
3551-
3552-TREEVIEW_WIDTH = 250
3553-
3554-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
3555-# external symbols imported via tag files in a separate window.
3556-# The default value is: NO.
3557-# This tag requires that the tag GENERATE_HTML is set to YES.
3558-
3559-EXT_LINKS_IN_WINDOW = NO
3560-
3561-# Use this tag to change the font size of LaTeX formulas included as images in
3562-# the HTML documentation. When you change the font size after a successful
3563-# doxygen run you need to manually remove any form_*.png images from the HTML
3564-# output directory to force them to be regenerated.
3565-# Minimum value: 8, maximum value: 50, default value: 10.
3566-# This tag requires that the tag GENERATE_HTML is set to YES.
3567-
3568-FORMULA_FONTSIZE = 10
3569-
3570-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
3571-# generated for formulas are transparent PNGs. Transparent PNGs are not
3572-# supported properly for IE 6.0, but are supported on all modern browsers.
3573-#
3574-# Note that when changing this option you need to delete any form_*.png files in
3575-# the HTML output directory before the changes have effect.
3576-# The default value is: YES.
3577-# This tag requires that the tag GENERATE_HTML is set to YES.
3578-
3579-FORMULA_TRANSPARENT = YES
3580-
3581-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
3582-# http://www.mathjax.org) which uses client side Javascript for the rendering
3583-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
3584-# installed or if you want to formulas look prettier in the HTML output. When
3585-# enabled you may also need to install MathJax separately and configure the path
3586-# to it using the MATHJAX_RELPATH option.
3587-# The default value is: NO.
3588-# This tag requires that the tag GENERATE_HTML is set to YES.
3589-
3590-USE_MATHJAX = NO
3591-
3592-# When MathJax is enabled you can set the default output format to be used for
3593-# the MathJax output. See the MathJax site (see:
3594-# http://docs.mathjax.org/en/latest/output.html) for more details.
3595-# Possible values are: HTML-CSS (which is slower, but has the best
3596-# compatibility), NativeMML (i.e. MathML) and SVG.
3597-# The default value is: HTML-CSS.
3598-# This tag requires that the tag USE_MATHJAX is set to YES.
3599-
3600-MATHJAX_FORMAT = HTML-CSS
3601-
3602-# When MathJax is enabled you need to specify the location relative to the HTML
3603-# output directory using the MATHJAX_RELPATH option. The destination directory
3604-# should contain the MathJax.js script. For instance, if the mathjax directory
3605-# is located at the same level as the HTML output directory, then
3606-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
3607-# Content Delivery Network so you can quickly see the result without installing
3608-# MathJax. However, it is strongly recommended to install a local copy of
3609-# MathJax from http://www.mathjax.org before deployment.
3610-# The default value is: http://cdn.mathjax.org/mathjax/latest.
3611-# This tag requires that the tag USE_MATHJAX is set to YES.
3612-
3613-MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
3614-
3615-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
3616-# extension names that should be enabled during MathJax rendering. For example
3617-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
3618-# This tag requires that the tag USE_MATHJAX is set to YES.
3619-
3620-MATHJAX_EXTENSIONS =
3621-
3622-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
3623-# of code that will be used on startup of the MathJax code. See the MathJax site
3624-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
3625-# example see the documentation.
3626-# This tag requires that the tag USE_MATHJAX is set to YES.
3627-
3628-MATHJAX_CODEFILE =
3629-
3630-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
3631-# the HTML output. The underlying search engine uses javascript and DHTML and
3632-# should work on any modern browser. Note that when using HTML help
3633-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
3634-# there is already a search function so this one should typically be disabled.
3635-# For large projects the javascript based search engine can be slow, then
3636-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
3637-# search using the keyboard; to jump to the search box use <access key> + S
3638-# (what the <access key> is depends on the OS and browser, but it is typically
3639-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
3640-# key> to jump into the search results window, the results can be navigated
3641-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
3642-# the search. The filter options can be selected when the cursor is inside the
3643-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
3644-# to select a filter and <Enter> or <escape> to activate or cancel the filter
3645-# option.
3646-# The default value is: YES.
3647-# This tag requires that the tag GENERATE_HTML is set to YES.
3648-
3649-SEARCHENGINE = YES
3650-
3651-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
3652-# implemented using a web server instead of a web client using Javascript. There
3653-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
3654-# setting. When disabled, doxygen will generate a PHP script for searching and
3655-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
3656-# and searching needs to be provided by external tools. See the section
3657-# "External Indexing and Searching" for details.
3658-# The default value is: NO.
3659-# This tag requires that the tag SEARCHENGINE is set to YES.
3660-
3661-SERVER_BASED_SEARCH = NO
3662-
3663-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
3664-# script for searching. Instead the search results are written to an XML file
3665-# which needs to be processed by an external indexer. Doxygen will invoke an
3666-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
3667-# search results.
3668-#
3669-# Doxygen ships with an example indexer (doxyindexer) and search engine
3670-# (doxysearch.cgi) which are based on the open source search engine library
3671-# Xapian (see: http://xapian.org/).
3672-#
3673-# See the section "External Indexing and Searching" for details.
3674-# The default value is: NO.
3675-# This tag requires that the tag SEARCHENGINE is set to YES.
3676-
3677-EXTERNAL_SEARCH = NO
3678-
3679-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
3680-# which will return the search results when EXTERNAL_SEARCH is enabled.
3681-#
3682-# Doxygen ships with an example indexer (doxyindexer) and search engine
3683-# (doxysearch.cgi) which are based on the open source search engine library
3684-# Xapian (see: http://xapian.org/). See the section "External Indexing and
3685-# Searching" for details.
3686-# This tag requires that the tag SEARCHENGINE is set to YES.
3687-
3688-SEARCHENGINE_URL =
3689-
3690-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
3691-# search data is written to a file for indexing by an external tool. With the
3692-# SEARCHDATA_FILE tag the name of this file can be specified.
3693-# The default file is: searchdata.xml.
3694-# This tag requires that the tag SEARCHENGINE is set to YES.
3695-
3696-SEARCHDATA_FILE = searchdata.xml
3697-
3698-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
3699-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
3700-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
3701-# projects and redirect the results back to the right project.
3702-# This tag requires that the tag SEARCHENGINE is set to YES.
3703-
3704-EXTERNAL_SEARCH_ID =
3705-
3706-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
3707-# projects other than the one defined by this configuration file, but that are
3708-# all added to the same external search index. Each project needs to have a
3709-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
3710-# to a relative location where the documentation can be found. The format is:
3711-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
3712-# This tag requires that the tag SEARCHENGINE is set to YES.
3713-
3714-EXTRA_SEARCH_MAPPINGS =
3715-
3716-#---------------------------------------------------------------------------
3717-# Configuration options related to the LaTeX output
3718-#---------------------------------------------------------------------------
3719-
3720-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
3721-# The default value is: YES.
3722-
3723-GENERATE_LATEX = YES
3724-
3725-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
3726-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
3727-# it.
3728-# The default directory is: latex.
3729-# This tag requires that the tag GENERATE_LATEX is set to YES.
3730-
3731-LATEX_OUTPUT = latex
3732-
3733-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
3734-# invoked.
3735-#
3736-# Note that when enabling USE_PDFLATEX this option is only used for generating
3737-# bitmaps for formulas in the HTML output, but not in the Makefile that is
3738-# written to the output directory.
3739-# The default file is: latex.
3740-# This tag requires that the tag GENERATE_LATEX is set to YES.
3741-
3742-LATEX_CMD_NAME = latex
3743-
3744-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
3745-# index for LaTeX.
3746-# The default file is: makeindex.
3747-# This tag requires that the tag GENERATE_LATEX is set to YES.
3748-
3749-MAKEINDEX_CMD_NAME = makeindex
3750-
3751-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
3752-# documents. This may be useful for small projects and may help to save some
3753-# trees in general.
3754-# The default value is: NO.
3755-# This tag requires that the tag GENERATE_LATEX is set to YES.
3756-
3757-COMPACT_LATEX = NO
3758-
3759-# The PAPER_TYPE tag can be used to set the paper type that is used by the
3760-# printer.
3761-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
3762-# 14 inches) and executive (7.25 x 10.5 inches).
3763-# The default value is: a4.
3764-# This tag requires that the tag GENERATE_LATEX is set to YES.
3765-
3766-PAPER_TYPE = a4
3767-
3768-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
3769-# that should be included in the LaTeX output. The package can be specified just
3770-# by its name or with the correct syntax as to be used with the LaTeX
3771-# \usepackage command. To get the times font for instance you can specify :
3772-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
3773-# To use the option intlimits with the amsmath package you can specify:
3774-# EXTRA_PACKAGES=[intlimits]{amsmath}
3775-# If left blank no extra packages will be included.
3776-# This tag requires that the tag GENERATE_LATEX is set to YES.
3777-
3778-EXTRA_PACKAGES =
3779-
3780-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
3781-# generated LaTeX document. The header should contain everything until the first
3782-# chapter. If it is left blank doxygen will generate a standard header. See
3783-# section "Doxygen usage" for information on how to let doxygen write the
3784-# default header to a separate file.
3785-#
3786-# Note: Only use a user-defined header if you know what you are doing! The
3787-# following commands have a special meaning inside the header: $title,
3788-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
3789-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
3790-# string, for the replacement values of the other commands the user is referred
3791-# to HTML_HEADER.
3792-# This tag requires that the tag GENERATE_LATEX is set to YES.
3793-
3794-LATEX_HEADER =
3795-
3796-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
3797-# generated LaTeX document. The footer should contain everything after the last
3798-# chapter. If it is left blank doxygen will generate a standard footer. See
3799-# LATEX_HEADER for more information on how to generate a default footer and what
3800-# special commands can be used inside the footer.
3801-#
3802-# Note: Only use a user-defined footer if you know what you are doing!
3803-# This tag requires that the tag GENERATE_LATEX is set to YES.
3804-
3805-LATEX_FOOTER =
3806-
3807-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
3808-# LaTeX style sheets that are included after the standard style sheets created
3809-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
3810-# will copy the style sheet files to the output directory.
3811-# Note: The order of the extra style sheet files is of importance (e.g. the last
3812-# style sheet in the list overrules the setting of the previous ones in the
3813-# list).
3814-# This tag requires that the tag GENERATE_LATEX is set to YES.
3815-
3816-LATEX_EXTRA_STYLESHEET =
3817-
3818-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
3819-# other source files which should be copied to the LATEX_OUTPUT output
3820-# directory. Note that the files will be copied as-is; there are no commands or
3821-# markers available.
3822-# This tag requires that the tag GENERATE_LATEX is set to YES.
3823-
3824-LATEX_EXTRA_FILES =
3825-
3826-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
3827-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
3828-# contain links (just like the HTML output) instead of page references. This
3829-# makes the output suitable for online browsing using a PDF viewer.
3830-# The default value is: YES.
3831-# This tag requires that the tag GENERATE_LATEX is set to YES.
3832-
3833-PDF_HYPERLINKS = YES
3834-
3835-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
3836-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
3837-# higher quality PDF documentation.
3838-# The default value is: YES.
3839-# This tag requires that the tag GENERATE_LATEX is set to YES.
3840-
3841-USE_PDFLATEX = YES
3842-
3843-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
3844-# command to the generated LaTeX files. This will instruct LaTeX to keep running
3845-# if errors occur, instead of asking the user for help. This option is also used
3846-# when generating formulas in HTML.
3847-# The default value is: NO.
3848-# This tag requires that the tag GENERATE_LATEX is set to YES.
3849-
3850-LATEX_BATCHMODE = NO
3851-
3852-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
3853-# index chapters (such as File Index, Compound Index, etc.) in the output.
3854-# The default value is: NO.
3855-# This tag requires that the tag GENERATE_LATEX is set to YES.
3856-
3857-LATEX_HIDE_INDICES = NO
3858-
3859-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
3860-# code with syntax highlighting in the LaTeX output.
3861-#
3862-# Note that which sources are shown also depends on other settings such as
3863-# SOURCE_BROWSER.
3864-# The default value is: NO.
3865-# This tag requires that the tag GENERATE_LATEX is set to YES.
3866-
3867-LATEX_SOURCE_CODE = NO
3868-
3869-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
3870-# bibliography, e.g. plainnat, or ieeetr. See
3871-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
3872-# The default value is: plain.
3873-# This tag requires that the tag GENERATE_LATEX is set to YES.
3874-
3875-LATEX_BIB_STYLE = plain
3876-
3877-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
3878-# page will contain the date and time when the page was generated. Setting this
3879-# to NO can help when comparing the output of multiple runs.
3880-# The default value is: NO.
3881-# This tag requires that the tag GENERATE_LATEX is set to YES.
3882-
3883-LATEX_TIMESTAMP = NO
3884-
3885-#---------------------------------------------------------------------------
3886-# Configuration options related to the RTF output
3887-#---------------------------------------------------------------------------
3888-
3889-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
3890-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
3891-# readers/editors.
3892-# The default value is: NO.
3893-
3894-GENERATE_RTF = NO
3895-
3896-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
3897-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
3898-# it.
3899-# The default directory is: rtf.
3900-# This tag requires that the tag GENERATE_RTF is set to YES.
3901-
3902-RTF_OUTPUT = rtf
3903-
3904-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
3905-# documents. This may be useful for small projects and may help to save some
3906-# trees in general.
3907-# The default value is: NO.
3908-# This tag requires that the tag GENERATE_RTF is set to YES.
3909-
3910-COMPACT_RTF = NO
3911-
3912-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
3913-# contain hyperlink fields. The RTF file will contain links (just like the HTML
3914-# output) instead of page references. This makes the output suitable for online
3915-# browsing using Word or some other Word compatible readers that support those
3916-# fields.
3917-#
3918-# Note: WordPad (write) and others do not support links.
3919-# The default value is: NO.
3920-# This tag requires that the tag GENERATE_RTF is set to YES.
3921-
3922-RTF_HYPERLINKS = NO
3923-
3924-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
3925-# file, i.e. a series of assignments. You only have to provide replacements,
3926-# missing definitions are set to their default value.
3927-#
3928-# See also section "Doxygen usage" for information on how to generate the
3929-# default style sheet that doxygen normally uses.
3930-# This tag requires that the tag GENERATE_RTF is set to YES.
3931-
3932-RTF_STYLESHEET_FILE =
3933-
3934-# Set optional variables used in the generation of an RTF document. Syntax is
3935-# similar to doxygen's config file. A template extensions file can be generated
3936-# using doxygen -e rtf extensionFile.
3937-# This tag requires that the tag GENERATE_RTF is set to YES.
3938-
3939-RTF_EXTENSIONS_FILE =
3940-
3941-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
3942-# with syntax highlighting in the RTF output.
3943-#
3944-# Note that which sources are shown also depends on other settings such as
3945-# SOURCE_BROWSER.
3946-# The default value is: NO.
3947-# This tag requires that the tag GENERATE_RTF is set to YES.
3948-
3949-RTF_SOURCE_CODE = NO
3950-
3951-#---------------------------------------------------------------------------
3952-# Configuration options related to the man page output
3953-#---------------------------------------------------------------------------
3954-
3955-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
3956-# classes and files.
3957-# The default value is: NO.
3958-
3959-GENERATE_MAN = NO
3960-
3961-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
3962-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
3963-# it. A directory man3 will be created inside the directory specified by
3964-# MAN_OUTPUT.
3965-# The default directory is: man.
3966-# This tag requires that the tag GENERATE_MAN is set to YES.
3967-
3968-MAN_OUTPUT = man
3969-
3970-# The MAN_EXTENSION tag determines the extension that is added to the generated
3971-# man pages. In case the manual section does not start with a number, the number
3972-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
3973-# optional.
3974-# The default value is: .3.
3975-# This tag requires that the tag GENERATE_MAN is set to YES.
3976-
3977-MAN_EXTENSION = .3
3978-
3979-# The MAN_SUBDIR tag determines the name of the directory created within
3980-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
3981-# MAN_EXTENSION with the initial . removed.
3982-# This tag requires that the tag GENERATE_MAN is set to YES.
3983-
3984-MAN_SUBDIR =
3985-
3986-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
3987-# will generate one additional man file for each entity documented in the real
3988-# man page(s). These additional files only source the real man page, but without
3989-# them the man command would be unable to find the correct page.
3990-# The default value is: NO.
3991-# This tag requires that the tag GENERATE_MAN is set to YES.
3992-
3993-MAN_LINKS = NO
3994-
3995-#---------------------------------------------------------------------------
3996-# Configuration options related to the XML output
3997-#---------------------------------------------------------------------------
3998-
3999-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
4000-# captures the structure of the code including all documentation.
4001-# The default value is: NO.
4002-
4003-GENERATE_XML = NO
4004-
4005-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
4006-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
4007-# it.
4008-# The default directory is: xml.
4009-# This tag requires that the tag GENERATE_XML is set to YES.
4010-
4011-XML_OUTPUT = xml
4012-
4013-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
4014-# listings (including syntax highlighting and cross-referencing information) to
4015-# the XML output. Note that enabling this will significantly increase the size
4016-# of the XML output.
4017-# The default value is: YES.
4018-# This tag requires that the tag GENERATE_XML is set to YES.
4019-
4020-XML_PROGRAMLISTING = YES
4021-
4022-#---------------------------------------------------------------------------
4023-# Configuration options related to the DOCBOOK output
4024-#---------------------------------------------------------------------------
4025-
4026-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
4027-# that can be used to generate PDF.
4028-# The default value is: NO.
4029-
4030-GENERATE_DOCBOOK = NO
4031-
4032-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
4033-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
4034-# front of it.
4035-# The default directory is: docbook.
4036-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
4037-
4038-DOCBOOK_OUTPUT = docbook
4039-
4040-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
4041-# program listings (including syntax highlighting and cross-referencing
4042-# information) to the DOCBOOK output. Note that enabling this will significantly
4043-# increase the size of the DOCBOOK output.
4044-# The default value is: NO.
4045-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
4046-
4047-DOCBOOK_PROGRAMLISTING = NO
4048-
4049-#---------------------------------------------------------------------------
4050-# Configuration options for the AutoGen Definitions output
4051-#---------------------------------------------------------------------------
4052-
4053-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
4054-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
4055-# structure of the code including all documentation. Note that this feature is
4056-# still experimental and incomplete at the moment.
4057-# The default value is: NO.
4058-
4059-GENERATE_AUTOGEN_DEF = NO
4060-
4061-#---------------------------------------------------------------------------
4062-# Configuration options related to the Perl module output
4063-#---------------------------------------------------------------------------
4064-
4065-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
4066-# file that captures the structure of the code including all documentation.
4067-#
4068-# Note that this feature is still experimental and incomplete at the moment.
4069-# The default value is: NO.
4070-
4071-GENERATE_PERLMOD = NO
4072-
4073-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
4074-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
4075-# output from the Perl module output.
4076-# The default value is: NO.
4077-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
4078-
4079-PERLMOD_LATEX = NO
4080-
4081-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
4082-# formatted so it can be parsed by a human reader. This is useful if you want to
4083-# understand what is going on. On the other hand, if this tag is set to NO, the
4084-# size of the Perl module output will be much smaller and Perl will parse it
4085-# just the same.
4086-# The default value is: YES.
4087-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
4088-
4089-PERLMOD_PRETTY = YES
4090-
4091-# The names of the make variables in the generated doxyrules.make file are
4092-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
4093-# so different doxyrules.make files included by the same Makefile don't
4094-# overwrite each other's variables.
4095-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
4096-
4097-PERLMOD_MAKEVAR_PREFIX =
4098-
4099-#---------------------------------------------------------------------------
4100-# Configuration options related to the preprocessor
4101-#---------------------------------------------------------------------------
4102-
4103-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
4104-# C-preprocessor directives found in the sources and include files.
4105-# The default value is: YES.
4106-
4107-ENABLE_PREPROCESSING = YES
4108-
4109-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
4110-# in the source code. If set to NO, only conditional compilation will be
4111-# performed. Macro expansion can be done in a controlled way by setting
4112-# EXPAND_ONLY_PREDEF to YES.
4113-# The default value is: NO.
4114-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4115-
4116-MACRO_EXPANSION = NO
4117-
4118-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
4119-# the macro expansion is limited to the macros specified with the PREDEFINED and
4120-# EXPAND_AS_DEFINED tags.
4121-# The default value is: NO.
4122-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4123-
4124-EXPAND_ONLY_PREDEF = NO
4125-
4126-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
4127-# INCLUDE_PATH will be searched if a #include is found.
4128-# The default value is: YES.
4129-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4130-
4131-SEARCH_INCLUDES = YES
4132-
4133-# The INCLUDE_PATH tag can be used to specify one or more directories that
4134-# contain include files that are not input files but should be processed by the
4135-# preprocessor.
4136-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
4137-
4138-INCLUDE_PATH =
4139-
4140-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
4141-# patterns (like *.h and *.hpp) to filter out the header-files in the
4142-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
4143-# used.
4144-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4145-
4146-INCLUDE_FILE_PATTERNS =
4147-
4148-# The PREDEFINED tag can be used to specify one or more macro names that are
4149-# defined before the preprocessor is started (similar to the -D option of e.g.
4150-# gcc). The argument of the tag is a list of macros of the form: name or
4151-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
4152-# is assumed. To prevent a macro definition from being undefined via #undef or
4153-# recursively expanded use the := operator instead of the = operator.
4154-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4155-
4156-PREDEFINED =
4157-
4158-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
4159-# tag can be used to specify a list of macro names that should be expanded. The
4160-# macro definition that is found in the sources will be used. Use the PREDEFINED
4161-# tag if you want to use a different macro definition that overrules the
4162-# definition found in the source code.
4163-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4164-
4165-EXPAND_AS_DEFINED =
4166-
4167-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
4168-# remove all references to function-like macros that are alone on a line, have
4169-# an all uppercase name, and do not end with a semicolon. Such function macros
4170-# are typically used for boiler-plate code, and will confuse the parser if not
4171-# removed.
4172-# The default value is: YES.
4173-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
4174-
4175-SKIP_FUNCTION_MACROS = YES
4176-
4177-#---------------------------------------------------------------------------
4178-# Configuration options related to external references
4179-#---------------------------------------------------------------------------
4180-
4181-# The TAGFILES tag can be used to specify one or more tag files. For each tag
4182-# file the location of the external documentation should be added. The format of
4183-# a tag file without this location is as follows:
4184-# TAGFILES = file1 file2 ...
4185-# Adding location for the tag files is done as follows:
4186-# TAGFILES = file1=loc1 "file2 = loc2" ...
4187-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
4188-# section "Linking to external documentation" for more information about the use
4189-# of tag files.
4190-# Note: Each tag file must have a unique name (where the name does NOT include
4191-# the path). If a tag file is not located in the directory in which doxygen is
4192-# run, you must also specify the path to the tagfile here.
4193-
4194-TAGFILES =
4195-
4196-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
4197-# tag file that is based on the input files it reads. See section "Linking to
4198-# external documentation" for more information about the usage of tag files.
4199-
4200-GENERATE_TAGFILE =
4201-
4202-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
4203-# the class index. If set to NO, only the inherited external classes will be
4204-# listed.
4205-# The default value is: NO.
4206-
4207-ALLEXTERNALS = NO
4208-
4209-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
4210-# in the modules index. If set to NO, only the current project's groups will be
4211-# listed.
4212-# The default value is: YES.
4213-
4214-EXTERNAL_GROUPS = YES
4215-
4216-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
4217-# the related pages index. If set to NO, only the current project's pages will
4218-# be listed.
4219-# The default value is: YES.
4220-
4221-EXTERNAL_PAGES = YES
4222-
4223-# The PERL_PATH should be the absolute path and name of the perl script
4224-# interpreter (i.e. the result of 'which perl').
4225-# The default file (with absolute path) is: /usr/bin/perl.
4226-
4227-PERL_PATH = /usr/bin/perl
4228-
4229-#---------------------------------------------------------------------------
4230-# Configuration options related to the dot tool
4231-#---------------------------------------------------------------------------
4232-
4233-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
4234-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
4235-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
4236-# disabled, but it is recommended to install and use dot, since it yields more
4237-# powerful graphs.
4238-# The default value is: YES.
4239-
4240-CLASS_DIAGRAMS = YES
4241-
4242-# You can define message sequence charts within doxygen comments using the \msc
4243-# command. Doxygen will then run the mscgen tool (see:
4244-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
4245-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
4246-# the mscgen tool resides. If left empty the tool is assumed to be found in the
4247-# default search path.
4248-
4249-MSCGEN_PATH =
4250-
4251-# You can include diagrams made with dia in doxygen documentation. Doxygen will
4252-# then run dia to produce the diagram and insert it in the documentation. The
4253-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
4254-# If left empty dia is assumed to be found in the default search path.
4255-
4256-DIA_PATH =
4257-
4258-# If set to YES the inheritance and collaboration graphs will hide inheritance
4259-# and usage relations if the target is undocumented or is not a class.
4260-# The default value is: YES.
4261-
4262-HIDE_UNDOC_RELATIONS = YES
4263-
4264-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
4265-# available from the path. This tool is part of Graphviz (see:
4266-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
4267-# Bell Labs. The other options in this section have no effect if this option is
4268-# set to NO
4269-# The default value is: NO.
4270-
4271-HAVE_DOT = NO
4272-
4273-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
4274-# to run in parallel. When set to 0 doxygen will base this on the number of
4275-# processors available in the system. You can set it explicitly to a value
4276-# larger than 0 to get control over the balance between CPU load and processing
4277-# speed.
4278-# Minimum value: 0, maximum value: 32, default value: 0.
4279-# This tag requires that the tag HAVE_DOT is set to YES.
4280-
4281-DOT_NUM_THREADS = 0
4282-
4283-# When you want a differently looking font in the dot files that doxygen
4284-# generates you can specify the font name using DOT_FONTNAME. You need to make
4285-# sure dot is able to find the font, which can be done by putting it in a
4286-# standard location or by setting the DOTFONTPATH environment variable or by
4287-# setting DOT_FONTPATH to the directory containing the font.
4288-# The default value is: Helvetica.
4289-# This tag requires that the tag HAVE_DOT is set to YES.
4290-
4291-DOT_FONTNAME = Helvetica
4292-
4293-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
4294-# dot graphs.
4295-# Minimum value: 4, maximum value: 24, default value: 10.
4296-# This tag requires that the tag HAVE_DOT is set to YES.
4297-
4298-DOT_FONTSIZE = 10
4299-
4300-# By default doxygen will tell dot to use the default font as specified with
4301-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
4302-# the path where dot can find it using this tag.
4303-# This tag requires that the tag HAVE_DOT is set to YES.
4304-
4305-DOT_FONTPATH =
4306-
4307-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
4308-# each documented class showing the direct and indirect inheritance relations.
4309-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
4310-# The default value is: YES.
4311-# This tag requires that the tag HAVE_DOT is set to YES.
4312-
4313-CLASS_GRAPH = YES
4314-
4315-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
4316-# graph for each documented class showing the direct and indirect implementation
4317-# dependencies (inheritance, containment, and class references variables) of the
4318-# class with other documented classes.
4319-# The default value is: YES.
4320-# This tag requires that the tag HAVE_DOT is set to YES.
4321-
4322-COLLABORATION_GRAPH = YES
4323-
4324-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
4325-# groups, showing the direct groups dependencies.
4326-# The default value is: YES.
4327-# This tag requires that the tag HAVE_DOT is set to YES.
4328-
4329-GROUP_GRAPHS = YES
4330-
4331-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
4332-# collaboration diagrams in a style similar to the OMG's Unified Modeling
4333-# Language.
4334-# The default value is: NO.
4335-# This tag requires that the tag HAVE_DOT is set to YES.
4336-
4337-UML_LOOK = NO
4338-
4339-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
4340-# class node. If there are many fields or methods and many nodes the graph may
4341-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
4342-# number of items for each type to make the size more manageable. Set this to 0
4343-# for no limit. Note that the threshold may be exceeded by 50% before the limit
4344-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
4345-# but if the number exceeds 15, the total amount of fields shown is limited to
4346-# 10.
4347-# Minimum value: 0, maximum value: 100, default value: 10.
4348-# This tag requires that the tag HAVE_DOT is set to YES.
4349-
4350-UML_LIMIT_NUM_FIELDS = 10
4351-
4352-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
4353-# collaboration graphs will show the relations between templates and their
4354-# instances.
4355-# The default value is: NO.
4356-# This tag requires that the tag HAVE_DOT is set to YES.
4357-
4358-TEMPLATE_RELATIONS = NO
4359-
4360-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
4361-# YES then doxygen will generate a graph for each documented file showing the
4362-# direct and indirect include dependencies of the file with other documented
4363-# files.
4364-# The default value is: YES.
4365-# This tag requires that the tag HAVE_DOT is set to YES.
4366-
4367-INCLUDE_GRAPH = YES
4368-
4369-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
4370-# set to YES then doxygen will generate a graph for each documented file showing
4371-# the direct and indirect include dependencies of the file with other documented
4372-# files.
4373-# The default value is: YES.
4374-# This tag requires that the tag HAVE_DOT is set to YES.
4375-
4376-INCLUDED_BY_GRAPH = YES
4377-
4378-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
4379-# dependency graph for every global function or class method.
4380-#
4381-# Note that enabling this option will significantly increase the time of a run.
4382-# So in most cases it will be better to enable call graphs for selected
4383-# functions only using the \callgraph command. Disabling a call graph can be
4384-# accomplished by means of the command \hidecallgraph.
4385-# The default value is: NO.
4386-# This tag requires that the tag HAVE_DOT is set to YES.
4387-
4388-CALL_GRAPH = NO
4389-
4390-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
4391-# dependency graph for every global function or class method.
4392-#
4393-# Note that enabling this option will significantly increase the time of a run.
4394-# So in most cases it will be better to enable caller graphs for selected
4395-# functions only using the \callergraph command. Disabling a caller graph can be
4396-# accomplished by means of the command \hidecallergraph.
4397-# The default value is: NO.
4398-# This tag requires that the tag HAVE_DOT is set to YES.
4399-
4400-CALLER_GRAPH = NO
4401-
4402-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
4403-# hierarchy of all classes instead of a textual one.
4404-# The default value is: YES.
4405-# This tag requires that the tag HAVE_DOT is set to YES.
4406-
4407-GRAPHICAL_HIERARCHY = YES
4408-
4409-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
4410-# dependencies a directory has on other directories in a graphical way. The
4411-# dependency relations are determined by the #include relations between the
4412-# files in the directories.
4413-# The default value is: YES.
4414-# This tag requires that the tag HAVE_DOT is set to YES.
4415-
4416-DIRECTORY_GRAPH = YES
4417-
4418-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
4419-# generated by dot. For an explanation of the image formats see the section
4420-# output formats in the documentation of the dot tool (Graphviz (see:
4421-# http://www.graphviz.org/)).
4422-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
4423-# to make the SVG files visible in IE 9+ (other browsers do not have this
4424-# requirement).
4425-# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
4426-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
4427-# png:gdiplus:gdiplus.
4428-# The default value is: png.
4429-# This tag requires that the tag HAVE_DOT is set to YES.
4430-
4431-DOT_IMAGE_FORMAT = png
4432-
4433-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
4434-# enable generation of interactive SVG images that allow zooming and panning.
4435-#
4436-# Note that this requires a modern browser other than Internet Explorer. Tested
4437-# and working are Firefox, Chrome, Safari, and Opera.
4438-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
4439-# the SVG files visible. Older versions of IE do not have SVG support.
4440-# The default value is: NO.
4441-# This tag requires that the tag HAVE_DOT is set to YES.
4442-
4443-INTERACTIVE_SVG = NO
4444-
4445-# The DOT_PATH tag can be used to specify the path where the dot tool can be
4446-# found. If left blank, it is assumed the dot tool can be found in the path.
4447-# This tag requires that the tag HAVE_DOT is set to YES.
4448-
4449-DOT_PATH =
4450-
4451-# The DOTFILE_DIRS tag can be used to specify one or more directories that
4452-# contain dot files that are included in the documentation (see the \dotfile
4453-# command).
4454-# This tag requires that the tag HAVE_DOT is set to YES.
4455-
4456-DOTFILE_DIRS =
4457-
4458-# The MSCFILE_DIRS tag can be used to specify one or more directories that
4459-# contain msc files that are included in the documentation (see the \mscfile
4460-# command).
4461-
4462-MSCFILE_DIRS =
4463-
4464-# The DIAFILE_DIRS tag can be used to specify one or more directories that
4465-# contain dia files that are included in the documentation (see the \diafile
4466-# command).
4467-
4468-DIAFILE_DIRS =
4469-
4470-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
4471-# path where java can find the plantuml.jar file. If left blank, it is assumed
4472-# PlantUML is not used or called during a preprocessing step. Doxygen will
4473-# generate a warning when it encounters a \startuml command in this case and
4474-# will not generate output for the diagram.
4475-
4476-PLANTUML_JAR_PATH =
4477-
4478-# When using plantuml, the specified paths are searched for files specified by
4479-# the !include statement in a plantuml block.
4480-
4481-PLANTUML_INCLUDE_PATH =
4482-
4483-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
4484-# that will be shown in the graph. If the number of nodes in a graph becomes
4485-# larger than this value, doxygen will truncate the graph, which is visualized
4486-# by representing a node as a red box. Note that doxygen if the number of direct
4487-# children of the root node in a graph is already larger than
4488-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
4489-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
4490-# Minimum value: 0, maximum value: 10000, default value: 50.
4491-# This tag requires that the tag HAVE_DOT is set to YES.
4492-
4493-DOT_GRAPH_MAX_NODES = 50
4494-
4495-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
4496-# generated by dot. A depth value of 3 means that only nodes reachable from the
4497-# root by following a path via at most 3 edges will be shown. Nodes that lay
4498-# further from the root node will be omitted. Note that setting this option to 1
4499-# or 2 may greatly reduce the computation time needed for large code bases. Also
4500-# note that the size of a graph can be further restricted by
4501-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
4502-# Minimum value: 0, maximum value: 1000, default value: 0.
4503-# This tag requires that the tag HAVE_DOT is set to YES.
4504-
4505-MAX_DOT_GRAPH_DEPTH = 0
4506-
4507-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
4508-# background. This is disabled by default, because dot on Windows does not seem
4509-# to support this out of the box.
4510-#
4511-# Warning: Depending on the platform used, enabling this option may lead to
4512-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
4513-# read).
4514-# The default value is: NO.
4515-# This tag requires that the tag HAVE_DOT is set to YES.
4516-
4517-DOT_TRANSPARENT = NO
4518-
4519-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
4520-# files in one run (i.e. multiple -o and -T options on the command line). This
4521-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
4522-# this, this feature is disabled by default.
4523-# The default value is: NO.
4524-# This tag requires that the tag HAVE_DOT is set to YES.
4525-
4526-DOT_MULTI_TARGETS = NO
4527-
4528-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
4529-# explaining the meaning of the various boxes and arrows in the dot generated
4530-# graphs.
4531-# The default value is: YES.
4532-# This tag requires that the tag HAVE_DOT is set to YES.
4533-
4534-GENERATE_LEGEND = YES
4535-
4536-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
4537-# files that are used to generate the various graphs.
4538-# The default value is: YES.
4539-# This tag requires that the tag HAVE_DOT is set to YES.
4540-
4541-DOT_CLEANUP = YES
4542+# Doxyfile 1.8.12
4543+
4544+# This file describes the settings to be used by the documentation system
4545+# doxygen (www.doxygen.org) for a project.
4546+#
4547+# All text after a double hash (##) is considered a comment and is placed in
4548+# front of the TAG it is preceding.
4549+#
4550+# All text after a single hash (#) is considered a comment and will be ignored.
4551+# The format is:
4552+# TAG = value [value, ...]
4553+# For lists, items can also be appended using:
4554+# TAG += value [value, ...]
4555+# Values that contain spaces should be placed between quotes (\" \").
4556+
4557+#---------------------------------------------------------------------------
4558+# Project related configuration options
4559+#---------------------------------------------------------------------------
4560+
4561+# This tag specifies the encoding used for all characters in the config file
4562+# that follow. The default is UTF-8 which is also the encoding used for all text
4563+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
4564+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
4565+# for the list of possible encodings.
4566+# The default value is: UTF-8.
4567+
4568+DOXYFILE_ENCODING = UTF-8
4569+
4570+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
4571+# double-quotes, unless you are using Doxywizard) that should identify the
4572+# project for which the documentation is generated. This name is used in the
4573+# title of most generated pages and in a few other places.
4574+# The default value is: My Project.
4575+
4576+PROJECT_NAME = "Open Augmented Reality Kit (OpenARK)"
4577+
4578+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
4579+# could be handy for archiving the generated documentation or if some version
4580+# control system is used.
4581+
4582+PROJECT_NUMBER = 0.8
4583+
4584+# Using the PROJECT_BRIEF tag one can provide an optional one line description
4585+# for a project that appears at the top of each page and should give viewer a
4586+# quick idea about the purpose of the project. Keep the description short.
4587+
4588+PROJECT_BRIEF = "Open-source wearable augmented reality (AR) system founded at UC Berkeley in 2016"
4589+
4590+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
4591+# in the documentation. The maximum height of the logo should not exceed 55
4592+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
4593+# the logo to the output directory.
4594+
4595+PROJECT_LOGO =
4596+
4597+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
4598+# into which the generated documentation will be written. If a relative path is
4599+# entered, it will be relative to the location where doxygen was started. If
4600+# left blank the current directory will be used.
4601+
4602+OUTPUT_DIRECTORY = D:\OpenARK-Documentation\0.8
4603+
4604+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
4605+# directories (in 2 levels) under the output directory of each output format and
4606+# will distribute the generated files over these directories. Enabling this
4607+# option can be useful when feeding doxygen a huge amount of source files, where
4608+# putting all generated files in the same directory would otherwise causes
4609+# performance problems for the file system.
4610+# The default value is: NO.
4611+
4612+CREATE_SUBDIRS = NO
4613+
4614+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
4615+# characters to appear in the names of generated files. If set to NO, non-ASCII
4616+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
4617+# U+3044.
4618+# The default value is: NO.
4619+
4620+ALLOW_UNICODE_NAMES = NO
4621+
4622+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
4623+# documentation generated by doxygen is written. Doxygen will use this
4624+# information to generate all constant output in the proper language.
4625+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
4626+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
4627+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
4628+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
4629+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
4630+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
4631+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
4632+# Ukrainian and Vietnamese.
4633+# The default value is: English.
4634+
4635+OUTPUT_LANGUAGE = English
4636+
4637+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
4638+# descriptions after the members that are listed in the file and class
4639+# documentation (similar to Javadoc). Set to NO to disable this.
4640+# The default value is: YES.
4641+
4642+BRIEF_MEMBER_DESC = YES
4643+
4644+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
4645+# description of a member or function before the detailed description
4646+#
4647+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
4648+# brief descriptions will be completely suppressed.
4649+# The default value is: YES.
4650+
4651+REPEAT_BRIEF = YES
4652+
4653+# This tag implements a quasi-intelligent brief description abbreviator that is
4654+# used to form the text in various listings. Each string in this list, if found
4655+# as the leading text of the brief description, will be stripped from the text
4656+# and the result, after processing the whole list, is used as the annotated
4657+# text. Otherwise, the brief description is used as-is. If left blank, the
4658+# following values are used ($name is automatically replaced with the name of
4659+# the entity):The $name class, The $name widget, The $name file, is, provides,
4660+# specifies, contains, represents, a, an and the.
4661+
4662+ABBREVIATE_BRIEF = "The $name class" \
4663+ "The $name widget" \
4664+ "The $name file" \
4665+ is \
4666+ provides \
4667+ specifies \
4668+ contains \
4669+ represents \
4670+ a \
4671+ an \
4672+ the
4673+
4674+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
4675+# doxygen will generate a detailed section even if there is only a brief
4676+# description.
4677+# The default value is: NO.
4678+
4679+ALWAYS_DETAILED_SEC = NO
4680+
4681+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
4682+# inherited members of a class in the documentation of that class as if those
4683+# members were ordinary class members. Constructors, destructors and assignment
4684+# operators of the base classes will not be shown.
4685+# The default value is: NO.
4686+
4687+INLINE_INHERITED_MEMB = NO
4688+
4689+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
4690+# before files name in the file list and in the header files. If set to NO the
4691+# shortest path that makes the file name unique will be used
4692+# The default value is: YES.
4693+
4694+FULL_PATH_NAMES = NO
4695+
4696+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
4697+# Stripping is only done if one of the specified strings matches the left-hand
4698+# part of the path. The tag can be used to show relative paths in the file list.
4699+# If left blank the directory from which doxygen is run is used as the path to
4700+# strip.
4701+#
4702+# Note that you can specify absolute paths here, but also relative paths, which
4703+# will be relative from the directory where doxygen is started.
4704+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
4705+
4706+STRIP_FROM_PATH =
4707+
4708+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
4709+# path mentioned in the documentation of a class, which tells the reader which
4710+# header file to include in order to use a class. If left blank only the name of
4711+# the header file containing the class definition is used. Otherwise one should
4712+# specify the list of include paths that are normally passed to the compiler
4713+# using the -I flag.
4714+
4715+STRIP_FROM_INC_PATH =
4716+
4717+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
4718+# less readable) file names. This can be useful is your file systems doesn't
4719+# support long names like on DOS, Mac, or CD-ROM.
4720+# The default value is: NO.
4721+
4722+SHORT_NAMES = NO
4723+
4724+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
4725+# first line (until the first dot) of a Javadoc-style comment as the brief
4726+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
4727+# style comments (thus requiring an explicit @brief command for a brief
4728+# description.)
4729+# The default value is: NO.
4730+
4731+JAVADOC_AUTOBRIEF = YES
4732+
4733+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
4734+# line (until the first dot) of a Qt-style comment as the brief description. If
4735+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
4736+# requiring an explicit \brief command for a brief description.)
4737+# The default value is: NO.
4738+
4739+QT_AUTOBRIEF = NO
4740+
4741+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
4742+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
4743+# a brief description. This used to be the default behavior. The new default is
4744+# to treat a multi-line C++ comment block as a detailed description. Set this
4745+# tag to YES if you prefer the old behavior instead.
4746+#
4747+# Note that setting this tag to YES also means that rational rose comments are
4748+# not recognized any more.
4749+# The default value is: NO.
4750+
4751+MULTILINE_CPP_IS_BRIEF = NO
4752+
4753+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
4754+# documentation from any documented member that it re-implements.
4755+# The default value is: YES.
4756+
4757+INHERIT_DOCS = YES
4758+
4759+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
4760+# page for each member. If set to NO, the documentation of a member will be part
4761+# of the file/class/namespace that contains it.
4762+# The default value is: NO.
4763+
4764+SEPARATE_MEMBER_PAGES = NO
4765+
4766+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
4767+# uses this value to replace tabs by spaces in code fragments.
4768+# Minimum value: 1, maximum value: 16, default value: 4.
4769+
4770+TAB_SIZE = 4
4771+
4772+# This tag can be used to specify a number of aliases that act as commands in
4773+# the documentation. An alias has the form:
4774+# name=value
4775+# For example adding
4776+# "sideeffect=@par Side Effects:\n"
4777+# will allow you to put the command \sideeffect (or @sideeffect) in the
4778+# documentation, which will result in a user-defined paragraph with heading
4779+# "Side Effects:". You can put \n's in the value part of an alias to insert
4780+# newlines.
4781+
4782+ALIASES =
4783+
4784+# This tag can be used to specify a number of word-keyword mappings (TCL only).
4785+# A mapping has the form "name=value". For example adding "class=itcl::class"
4786+# will allow you to use the command class in the itcl::class meaning.
4787+
4788+TCL_SUBST =
4789+
4790+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
4791+# only. Doxygen will then generate output that is more tailored for C. For
4792+# instance, some of the names that are used will be different. The list of all
4793+# members will be omitted, etc.
4794+# The default value is: NO.
4795+
4796+OPTIMIZE_OUTPUT_FOR_C = NO
4797+
4798+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
4799+# Python sources only. Doxygen will then generate output that is more tailored
4800+# for that language. For instance, namespaces will be presented as packages,
4801+# qualified scopes will look different, etc.
4802+# The default value is: NO.
4803+
4804+OPTIMIZE_OUTPUT_JAVA = NO
4805+
4806+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
4807+# sources. Doxygen will then generate output that is tailored for Fortran.
4808+# The default value is: NO.
4809+
4810+OPTIMIZE_FOR_FORTRAN = NO
4811+
4812+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
4813+# sources. Doxygen will then generate output that is tailored for VHDL.
4814+# The default value is: NO.
4815+
4816+OPTIMIZE_OUTPUT_VHDL = NO
4817+
4818+# Doxygen selects the parser to use depending on the extension of the files it
4819+# parses. With this tag you can assign which parser to use for a given
4820+# extension. Doxygen has a built-in mapping, but you can override or extend it
4821+# using this tag. The format is ext=language, where ext is a file extension, and
4822+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
4823+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
4824+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
4825+# Fortran. In the later case the parser tries to guess whether the code is fixed
4826+# or free formatted code, this is the default for Fortran type files), VHDL. For
4827+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
4828+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
4829+#
4830+# Note: For files without extension you can use no_extension as a placeholder.
4831+#
4832+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
4833+# the files are not read by doxygen.
4834+
4835+EXTENSION_MAPPING =
4836+
4837+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
4838+# according to the Markdown format, which allows for more readable
4839+# documentation. See http://daringfireball.net/projects/markdown/ for details.
4840+# The output of markdown processing is further processed by doxygen, so you can
4841+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
4842+# case of backward compatibilities issues.
4843+# The default value is: YES.
4844+
4845+MARKDOWN_SUPPORT = YES
4846+
4847+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
4848+# to that level are automatically included in the table of contents, even if
4849+# they do not have an id attribute.
4850+# Note: This feature currently applies only to Markdown headings.
4851+# Minimum value: 0, maximum value: 99, default value: 0.
4852+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
4853+
4854+TOC_INCLUDE_HEADINGS = 0
4855+
4856+# When enabled doxygen tries to link words that correspond to documented
4857+# classes, or namespaces to their corresponding documentation. Such a link can
4858+# be prevented in individual cases by putting a % sign in front of the word or
4859+# globally by setting AUTOLINK_SUPPORT to NO.
4860+# The default value is: YES.
4861+
4862+AUTOLINK_SUPPORT = YES
4863+
4864+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
4865+# to include (a tag file for) the STL sources as input, then you should set this
4866+# tag to YES in order to let doxygen match functions declarations and
4867+# definitions whose arguments contain STL classes (e.g. func(std::string);
4868+# versus func(std::string) {}). This also make the inheritance and collaboration
4869+# diagrams that involve STL classes more complete and accurate.
4870+# The default value is: NO.
4871+
4872+BUILTIN_STL_SUPPORT = NO
4873+
4874+# If you use Microsoft's C++/CLI language, you should set this option to YES to
4875+# enable parsing support.
4876+# The default value is: NO.
4877+
4878+CPP_CLI_SUPPORT = NO
4879+
4880+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
4881+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
4882+# will parse them like normal C++ but will assume all classes use public instead
4883+# of private inheritance when no explicit protection keyword is present.
4884+# The default value is: NO.
4885+
4886+SIP_SUPPORT = NO
4887+
4888+# For Microsoft's IDL there are propget and propput attributes to indicate
4889+# getter and setter methods for a property. Setting this option to YES will make
4890+# doxygen to replace the get and set methods by a property in the documentation.
4891+# This will only work if the methods are indeed getting or setting a simple
4892+# type. If this is not the case, or you want to show the methods anyway, you
4893+# should set this option to NO.
4894+# The default value is: YES.
4895+
4896+IDL_PROPERTY_SUPPORT = YES
4897+
4898+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
4899+# tag is set to YES then doxygen will reuse the documentation of the first
4900+# member in the group (if any) for the other members of the group. By default
4901+# all members of a group must be documented explicitly.
4902+# The default value is: NO.
4903+
4904+DISTRIBUTE_GROUP_DOC = NO
4905+
4906+# If one adds a struct or class to a group and this option is enabled, then also
4907+# any nested class or struct is added to the same group. By default this option
4908+# is disabled and one has to add nested compounds explicitly via \ingroup.
4909+# The default value is: NO.
4910+
4911+GROUP_NESTED_COMPOUNDS = NO
4912+
4913+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
4914+# (for instance a group of public functions) to be put as a subgroup of that
4915+# type (e.g. under the Public Functions section). Set it to NO to prevent
4916+# subgrouping. Alternatively, this can be done per class using the
4917+# \nosubgrouping command.
4918+# The default value is: YES.
4919+
4920+SUBGROUPING = YES
4921+
4922+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
4923+# are shown inside the group in which they are included (e.g. using \ingroup)
4924+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
4925+# and RTF).
4926+#
4927+# Note that this feature does not work in combination with
4928+# SEPARATE_MEMBER_PAGES.
4929+# The default value is: NO.
4930+
4931+INLINE_GROUPED_CLASSES = NO
4932+
4933+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
4934+# with only public data fields or simple typedef fields will be shown inline in
4935+# the documentation of the scope in which they are defined (i.e. file,
4936+# namespace, or group documentation), provided this scope is documented. If set
4937+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
4938+# Man pages) or section (for LaTeX and RTF).
4939+# The default value is: NO.
4940+
4941+INLINE_SIMPLE_STRUCTS = NO
4942+
4943+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
4944+# enum is documented as struct, union, or enum with the name of the typedef. So
4945+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
4946+# with name TypeT. When disabled the typedef will appear as a member of a file,
4947+# namespace, or class. And the struct will be named TypeS. This can typically be
4948+# useful for C code in case the coding convention dictates that all compound
4949+# types are typedef'ed and only the typedef is referenced, never the tag name.
4950+# The default value is: NO.
4951+
4952+TYPEDEF_HIDES_STRUCT = NO
4953+
4954+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
4955+# cache is used to resolve symbols given their name and scope. Since this can be
4956+# an expensive process and often the same symbol appears multiple times in the
4957+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
4958+# doxygen will become slower. If the cache is too large, memory is wasted. The
4959+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
4960+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
4961+# symbols. At the end of a run doxygen will report the cache usage and suggest
4962+# the optimal cache size from a speed point of view.
4963+# Minimum value: 0, maximum value: 9, default value: 0.
4964+
4965+LOOKUP_CACHE_SIZE = 0
4966+
4967+#---------------------------------------------------------------------------
4968+# Build related configuration options
4969+#---------------------------------------------------------------------------
4970+
4971+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
4972+# documentation are documented, even if no documentation was available. Private
4973+# class members and static file members will be hidden unless the
4974+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
4975+# Note: This will also disable the warnings about undocumented members that are
4976+# normally produced when WARNINGS is set to YES.
4977+# The default value is: NO.
4978+
4979+EXTRACT_ALL = YES
4980+
4981+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
4982+# be included in the documentation.
4983+# The default value is: NO.
4984+
4985+EXTRACT_PRIVATE = YES
4986+
4987+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
4988+# scope will be included in the documentation.
4989+# The default value is: NO.
4990+
4991+EXTRACT_PACKAGE = NO
4992+
4993+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
4994+# included in the documentation.
4995+# The default value is: NO.
4996+
4997+EXTRACT_STATIC = YES
4998+
4999+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
5000+# locally in source files will be included in the documentation. If set to NO,
5001+# only classes defined in header files are included. Does not have any effect
5002+# for Java sources.
5003+# The default value is: YES.
5004+
5005+EXTRACT_LOCAL_CLASSES = YES
5006+
5007+# This flag is only useful for Objective-C code. If set to YES, local methods,
5008+# which are defined in the implementation section but not in the interface are
5009+# included in the documentation. If set to NO, only methods in the interface are
5010+# included.
5011+# The default value is: NO.
5012+
5013+EXTRACT_LOCAL_METHODS = NO
5014+
5015+# If this flag is set to YES, the members of anonymous namespaces will be
5016+# extracted and appear in the documentation as a namespace called
5017+# 'anonymous_namespace{file}', where file will be replaced with the base name of
5018+# the file that contains the anonymous namespace. By default anonymous namespace
5019+# are hidden.
5020+# The default value is: NO.
5021+
5022+EXTRACT_ANON_NSPACES = NO
5023+
5024+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
5025+# undocumented members inside documented classes or files. If set to NO these
5026+# members will be included in the various overviews, but no documentation
5027+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
5028+# The default value is: NO.
5029+
5030+HIDE_UNDOC_MEMBERS = NO
5031+
5032+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
5033+# undocumented classes that are normally visible in the class hierarchy. If set
5034+# to NO, these classes will be included in the various overviews. This option
5035+# has no effect if EXTRACT_ALL is enabled.
5036+# The default value is: NO.
5037+
5038+HIDE_UNDOC_CLASSES = NO
5039+
5040+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
5041+# (class|struct|union) declarations. If set to NO, these declarations will be
5042+# included in the documentation.
5043+# The default value is: NO.
5044+
5045+HIDE_FRIEND_COMPOUNDS = NO
5046+
5047+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
5048+# documentation blocks found inside the body of a function. If set to NO, these
5049+# blocks will be appended to the function's detailed documentation block.
5050+# The default value is: NO.
5051+
5052+HIDE_IN_BODY_DOCS = NO
5053+
5054+# The INTERNAL_DOCS tag determines if documentation that is typed after a
5055+# \internal command is included. If the tag is set to NO then the documentation
5056+# will be excluded. Set it to YES to include the internal documentation.
5057+# The default value is: NO.
5058+
5059+INTERNAL_DOCS = NO
5060+
5061+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
5062+# names in lower-case letters. If set to YES, upper-case letters are also
5063+# allowed. This is useful if you have classes or files whose names only differ
5064+# in case and if your file system supports case sensitive file names. Windows
5065+# and Mac users are advised to set this option to NO.
5066+# The default value is: system dependent.
5067+
5068+CASE_SENSE_NAMES = NO
5069+
5070+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
5071+# their full class and namespace scopes in the documentation. If set to YES, the
5072+# scope will be hidden.
5073+# The default value is: NO.
5074+
5075+HIDE_SCOPE_NAMES = NO
5076+
5077+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
5078+# append additional text to a page's title, such as Class Reference. If set to
5079+# YES the compound reference will be hidden.
5080+# The default value is: NO.
5081+
5082+HIDE_COMPOUND_REFERENCE= NO
5083+
5084+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
5085+# the files that are included by a file in the documentation of that file.
5086+# The default value is: YES.
5087+
5088+SHOW_INCLUDE_FILES = YES
5089+
5090+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
5091+# grouped member an include statement to the documentation, telling the reader
5092+# which file to include in order to use the member.
5093+# The default value is: NO.
5094+
5095+SHOW_GROUPED_MEMB_INC = NO
5096+
5097+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
5098+# files with double quotes in the documentation rather than with sharp brackets.
5099+# The default value is: NO.
5100+
5101+FORCE_LOCAL_INCLUDES = NO
5102+
5103+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
5104+# documentation for inline members.
5105+# The default value is: YES.
5106+
5107+INLINE_INFO = YES
5108+
5109+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
5110+# (detailed) documentation of file and class members alphabetically by member
5111+# name. If set to NO, the members will appear in declaration order.
5112+# The default value is: YES.
5113+
5114+SORT_MEMBER_DOCS = YES
5115+
5116+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
5117+# descriptions of file, namespace and class members alphabetically by member
5118+# name. If set to NO, the members will appear in declaration order. Note that
5119+# this will also influence the order of the classes in the class list.
5120+# The default value is: NO.
5121+
5122+SORT_BRIEF_DOCS = NO
5123+
5124+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
5125+# (brief and detailed) documentation of class members so that constructors and
5126+# destructors are listed first. If set to NO the constructors will appear in the
5127+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
5128+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
5129+# member documentation.
5130+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
5131+# detailed member documentation.
5132+# The default value is: NO.
5133+
5134+SORT_MEMBERS_CTORS_1ST = NO
5135+
5136+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
5137+# of group names into alphabetical order. If set to NO the group names will
5138+# appear in their defined order.
5139+# The default value is: NO.
5140+
5141+SORT_GROUP_NAMES = NO
5142+
5143+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
5144+# fully-qualified names, including namespaces. If set to NO, the class list will
5145+# be sorted only by class name, not including the namespace part.
5146+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
5147+# Note: This option applies only to the class list, not to the alphabetical
5148+# list.
5149+# The default value is: NO.
5150+
5151+SORT_BY_SCOPE_NAME = NO
5152+
5153+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
5154+# type resolution of all parameters of a function it will reject a match between
5155+# the prototype and the implementation of a member function even if there is
5156+# only one candidate or it is obvious which candidate to choose by doing a
5157+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
5158+# accept a match between prototype and implementation in such cases.
5159+# The default value is: NO.
5160+
5161+STRICT_PROTO_MATCHING = NO
5162+
5163+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
5164+# list. This list is created by putting \todo commands in the documentation.
5165+# The default value is: YES.
5166+
5167+GENERATE_TODOLIST = YES
5168+
5169+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
5170+# list. This list is created by putting \test commands in the documentation.
5171+# The default value is: YES.
5172+
5173+GENERATE_TESTLIST = YES
5174+
5175+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
5176+# list. This list is created by putting \bug commands in the documentation.
5177+# The default value is: YES.
5178+
5179+GENERATE_BUGLIST = YES
5180+
5181+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
5182+# the deprecated list. This list is created by putting \deprecated commands in
5183+# the documentation.
5184+# The default value is: YES.
5185+
5186+GENERATE_DEPRECATEDLIST= YES
5187+
5188+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
5189+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
5190+# ... \endcond blocks.
5191+
5192+ENABLED_SECTIONS =
5193+
5194+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
5195+# initial value of a variable or macro / define can have for it to appear in the
5196+# documentation. If the initializer consists of more lines than specified here
5197+# it will be hidden. Use a value of 0 to hide initializers completely. The
5198+# appearance of the value of individual variables and macros / defines can be
5199+# controlled using \showinitializer or \hideinitializer command in the
5200+# documentation regardless of this setting.
5201+# Minimum value: 0, maximum value: 10000, default value: 30.
5202+
5203+MAX_INITIALIZER_LINES = 30
5204+
5205+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
5206+# the bottom of the documentation of classes and structs. If set to YES, the
5207+# list will mention the files that were used to generate the documentation.
5208+# The default value is: YES.
5209+
5210+SHOW_USED_FILES = YES
5211+
5212+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
5213+# will remove the Files entry from the Quick Index and from the Folder Tree View
5214+# (if specified).
5215+# The default value is: YES.
5216+
5217+SHOW_FILES = YES
5218+
5219+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
5220+# page. This will remove the Namespaces entry from the Quick Index and from the
5221+# Folder Tree View (if specified).
5222+# The default value is: YES.
5223+
5224+SHOW_NAMESPACES = YES
5225+
5226+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
5227+# doxygen should invoke to get the current version for each file (typically from
5228+# the version control system). Doxygen will invoke the program by executing (via
5229+# popen()) the command command input-file, where command is the value of the
5230+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
5231+# by doxygen. Whatever the program writes to standard output is used as the file
5232+# version. For an example see the documentation.
5233+
5234+FILE_VERSION_FILTER =
5235+
5236+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
5237+# by doxygen. The layout file controls the global structure of the generated
5238+# output files in an output format independent way. To create the layout file
5239+# that represents doxygen's defaults, run doxygen with the -l option. You can
5240+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
5241+# will be used as the name of the layout file.
5242+#
5243+# Note that if you run doxygen from a directory containing a file called
5244+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
5245+# tag is left empty.
5246+
5247+LAYOUT_FILE =
5248+
5249+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
5250+# the reference definitions. This must be a list of .bib files. The .bib
5251+# extension is automatically appended if omitted. This requires the bibtex tool
5252+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
5253+# For LaTeX the style of the bibliography can be controlled using
5254+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
5255+# search path. See also \cite for info how to create references.
5256+
5257+CITE_BIB_FILES =
5258+
5259+#---------------------------------------------------------------------------
5260+# Configuration options related to warning and progress messages
5261+#---------------------------------------------------------------------------
5262+
5263+# The QUIET tag can be used to turn on/off the messages that are generated to
5264+# standard output by doxygen. If QUIET is set to YES this implies that the
5265+# messages are off.
5266+# The default value is: NO.
5267+
5268+QUIET = NO
5269+
5270+# The WARNINGS tag can be used to turn on/off the warning messages that are
5271+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
5272+# this implies that the warnings are on.
5273+#
5274+# Tip: Turn warnings on while writing the documentation.
5275+# The default value is: YES.
5276+
5277+WARNINGS = YES
5278+
5279+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
5280+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
5281+# will automatically be disabled.
5282+# The default value is: YES.
5283+
5284+WARN_IF_UNDOCUMENTED = YES
5285+
5286+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
5287+# potential errors in the documentation, such as not documenting some parameters
5288+# in a documented function, or documenting parameters that don't exist or using
5289+# markup commands wrongly.
5290+# The default value is: YES.
5291+
5292+WARN_IF_DOC_ERROR = YES
5293+
5294+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
5295+# are documented, but have no documentation for their parameters or return
5296+# value. If set to NO, doxygen will only warn about wrong or incomplete
5297+# parameter documentation, but not about the absence of documentation.
5298+# The default value is: NO.
5299+
5300+WARN_NO_PARAMDOC = NO
5301+
5302+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
5303+# a warning is encountered.
5304+# The default value is: NO.
5305+
5306+WARN_AS_ERROR = NO
5307+
5308+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
5309+# can produce. The string should contain the $file, $line, and $text tags, which
5310+# will be replaced by the file and line number from which the warning originated
5311+# and the warning text. Optionally the format may contain $version, which will
5312+# be replaced by the version of the file (if it could be obtained via
5313+# FILE_VERSION_FILTER)
5314+# The default value is: $file:$line: $text.
5315+
5316+WARN_FORMAT = "$file:$line: $text"
5317+
5318+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
5319+# messages should be written. If left blank the output is written to standard
5320+# error (stderr).
5321+
5322+WARN_LOGFILE =
5323+
5324+#---------------------------------------------------------------------------
5325+# Configuration options related to the input files
5326+#---------------------------------------------------------------------------
5327+
5328+# The INPUT tag is used to specify the files and/or directories that contain
5329+# documented source files. You may enter file names like myfile.cpp or
5330+# directories like /usr/src/myproject. Separate the files or directories with
5331+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
5332+# Note: If this tag is empty the current directory is searched.
5333+
5334+INPUT = D:\OpenARK
5335+
5336+# This tag can be used to specify the character encoding of the source files
5337+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
5338+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
5339+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
5340+# possible encodings.
5341+# The default value is: UTF-8.
5342+
5343+INPUT_ENCODING = UTF-8
5344+
5345+# If the value of the INPUT tag contains directories, you can use the
5346+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
5347+# *.h) to filter out the source-files in the directories.
5348+#
5349+# Note that for custom extensions or not directly supported extensions you also
5350+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
5351+# read by doxygen.
5352+#
5353+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
5354+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
5355+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
5356+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
5357+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
5358+
5359+FILE_PATTERNS = *.c \
5360+ *.cc \
5361+ *.cxx \
5362+ *.cpp \
5363+ *.c++ \
5364+ *.java \
5365+ *.ii \
5366+ *.ixx \
5367+ *.ipp \
5368+ *.i++ \
5369+ *.inl \
5370+ *.idl \
5371+ *.ddl \
5372+ *.odl \
5373+ *.h \
5374+ *.hh \
5375+ *.hxx \
5376+ *.hpp \
5377+ *.h++ \
5378+ *.cs \
5379+ *.d \
5380+ *.php \
5381+ *.php4 \
5382+ *.php5 \
5383+ *.phtml \
5384+ *.inc \
5385+ *.m \
5386+ *.markdown \
5387+ *.md \
5388+ *.mm \
5389+ *.dox \
5390+ *.py \
5391+ *.pyw \
5392+ *.f90 \
5393+ *.f95 \
5394+ *.f03 \
5395+ *.f08 \
5396+ *.f \
5397+ *.for \
5398+ *.tcl \
5399+ *.vhd \
5400+ *.vhdl \
5401+ *.ucf \
5402+ *.qsf
5403+
5404+# The RECURSIVE tag can be used to specify whether or not subdirectories should
5405+# be searched for input files as well.
5406+# The default value is: NO.
5407+
5408+RECURSIVE = YES
5409+
5410+# The EXCLUDE tag can be used to specify files and/or directories that should be
5411+# excluded from the INPUT source files. This way you can easily exclude a
5412+# subdirectory from a directory tree whose root is specified with the INPUT tag.
5413+#
5414+# Note that relative paths are relative to the directory from which doxygen is
5415+# run.
5416+
5417+EXCLUDE = D:\OpenARK\SampleCode
5418+
5419+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
5420+# directories that are symbolic links (a Unix file system feature) are excluded
5421+# from the input.
5422+# The default value is: NO.
5423+
5424+EXCLUDE_SYMLINKS = NO
5425+
5426+# If the value of the INPUT tag contains directories, you can use the
5427+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
5428+# certain files from those directories.
5429+#
5430+# Note that the wildcards are matched against the file with absolute path, so to
5431+# exclude all test directories for example use the pattern */test/*
5432+
5433+EXCLUDE_PATTERNS =
5434+
5435+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
5436+# (namespaces, classes, functions, etc.) that should be excluded from the
5437+# output. The symbol name can be a fully qualified name, a word, or if the
5438+# wildcard * is used, a substring. Examples: ANamespace, AClass,
5439+# AClass::ANamespace, ANamespace::*Test
5440+#
5441+# Note that the wildcards are matched against the file with absolute path, so to
5442+# exclude all test directories use the pattern */test/*
5443+
5444+EXCLUDE_SYMBOLS =
5445+
5446+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
5447+# that contain example code fragments that are included (see the \include
5448+# command).
5449+
5450+EXAMPLE_PATH = D:\OpenARK\SampleCode
5451+
5452+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
5453+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
5454+# *.h) to filter out the source-files in the directories. If left blank all
5455+# files are included.
5456+
5457+EXAMPLE_PATTERNS = *
5458+
5459+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
5460+# searched for input files to be used with the \include or \dontinclude commands
5461+# irrespective of the value of the RECURSIVE tag.
5462+# The default value is: NO.
5463+
5464+EXAMPLE_RECURSIVE = YES
5465+
5466+# The IMAGE_PATH tag can be used to specify one or more files or directories
5467+# that contain images that are to be included in the documentation (see the
5468+# \image command).
5469+
5470+IMAGE_PATH =
5471+
5472+# The INPUT_FILTER tag can be used to specify a program that doxygen should
5473+# invoke to filter for each input file. Doxygen will invoke the filter program
5474+# by executing (via popen()) the command:
5475+#
5476+# <filter> <input-file>
5477+#
5478+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
5479+# name of an input file. Doxygen will then use the output that the filter
5480+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
5481+# will be ignored.
5482+#
5483+# Note that the filter must not add or remove lines; it is applied before the
5484+# code is scanned, but not when the output code is generated. If lines are added
5485+# or removed, the anchors will not be placed correctly.
5486+#
5487+# Note that for custom extensions or not directly supported extensions you also
5488+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
5489+# properly processed by doxygen.
5490+
5491+INPUT_FILTER =
5492+
5493+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
5494+# basis. Doxygen will compare the file name with each pattern and apply the
5495+# filter if there is a match. The filters are a list of the form: pattern=filter
5496+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
5497+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
5498+# patterns match the file name, INPUT_FILTER is applied.
5499+#
5500+# Note that for custom extensions or not directly supported extensions you also
5501+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
5502+# properly processed by doxygen.
5503+
5504+FILTER_PATTERNS =
5505+
5506+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
5507+# INPUT_FILTER) will also be used to filter the input files that are used for
5508+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
5509+# The default value is: NO.
5510+
5511+FILTER_SOURCE_FILES = NO
5512+
5513+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
5514+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
5515+# it is also possible to disable source filtering for a specific pattern using
5516+# *.ext= (so without naming a filter).
5517+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
5518+
5519+FILTER_SOURCE_PATTERNS =
5520+
5521+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
5522+# is part of the input, its contents will be placed on the main page
5523+# (index.html). This can be useful if you have a project on for instance GitHub
5524+# and want to reuse the introduction page also for the doxygen output.
5525+
5526+USE_MDFILE_AS_MAINPAGE =
5527+
5528+#---------------------------------------------------------------------------
5529+# Configuration options related to source browsing
5530+#---------------------------------------------------------------------------
5531+
5532+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
5533+# generated. Documented entities will be cross-referenced with these sources.
5534+#
5535+# Note: To get rid of all source code in the generated output, make sure that
5536+# also VERBATIM_HEADERS is set to NO.
5537+# The default value is: NO.
5538+
5539+SOURCE_BROWSER = NO
5540+
5541+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
5542+# classes and enums directly into the documentation.
5543+# The default value is: NO.
5544+
5545+INLINE_SOURCES = NO
5546+
5547+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
5548+# special comment blocks from generated source code fragments. Normal C, C++ and
5549+# Fortran comments will always remain visible.
5550+# The default value is: YES.
5551+
5552+STRIP_CODE_COMMENTS = YES
5553+
5554+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
5555+# function all documented functions referencing it will be listed.
5556+# The default value is: NO.
5557+
5558+REFERENCED_BY_RELATION = NO
5559+
5560+# If the REFERENCES_RELATION tag is set to YES then for each documented function
5561+# all documented entities called/used by that function will be listed.
5562+# The default value is: NO.
5563+
5564+REFERENCES_RELATION = NO
5565+
5566+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
5567+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
5568+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
5569+# link to the documentation.
5570+# The default value is: YES.
5571+
5572+REFERENCES_LINK_SOURCE = YES
5573+
5574+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
5575+# source code will show a tooltip with additional information such as prototype,
5576+# brief description and links to the definition and documentation. Since this
5577+# will make the HTML file larger and loading of large files a bit slower, you
5578+# can opt to disable this feature.
5579+# The default value is: YES.
5580+# This tag requires that the tag SOURCE_BROWSER is set to YES.
5581+
5582+SOURCE_TOOLTIPS = YES
5583+
5584+# If the USE_HTAGS tag is set to YES then the references to source code will
5585+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
5586+# source browser. The htags tool is part of GNU's global source tagging system
5587+# (see http://www.gnu.org/software/global/global.html). You will need version
5588+# 4.8.6 or higher.
5589+#
5590+# To use it do the following:
5591+# - Install the latest version of global
5592+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
5593+# - Make sure the INPUT points to the root of the source tree
5594+# - Run doxygen as normal
5595+#
5596+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
5597+# tools must be available from the command line (i.e. in the search path).
5598+#
5599+# The result: instead of the source browser generated by doxygen, the links to
5600+# source code will now point to the output of htags.
5601+# The default value is: NO.
5602+# This tag requires that the tag SOURCE_BROWSER is set to YES.
5603+
5604+USE_HTAGS = NO
5605+
5606+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
5607+# verbatim copy of the header file for each class for which an include is
5608+# specified. Set to NO to disable this.
5609+# See also: Section \class.
5610+# The default value is: YES.
5611+
5612+VERBATIM_HEADERS = YES
5613+
5614+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
5615+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
5616+# cost of reduced performance. This can be particularly helpful with template
5617+# rich C++ code for which doxygen's built-in parser lacks the necessary type
5618+# information.
5619+# Note: The availability of this option depends on whether or not doxygen was
5620+# generated with the -Duse-libclang=ON option for CMake.
5621+# The default value is: NO.
5622+
5623+CLANG_ASSISTED_PARSING = NO
5624+
5625+# If clang assisted parsing is enabled you can provide the compiler with command
5626+# line options that you would normally use when invoking the compiler. Note that
5627+# the include paths will already be set by doxygen for the files and directories
5628+# specified with INPUT and INCLUDE_PATH.
5629+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
5630+
5631+CLANG_OPTIONS =
5632+
5633+#---------------------------------------------------------------------------
5634+# Configuration options related to the alphabetical class index
5635+#---------------------------------------------------------------------------
5636+
5637+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
5638+# compounds will be generated. Enable this if the project contains a lot of
5639+# classes, structs, unions or interfaces.
5640+# The default value is: YES.
5641+
5642+ALPHABETICAL_INDEX = YES
5643+
5644+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
5645+# which the alphabetical index list will be split.
5646+# Minimum value: 1, maximum value: 20, default value: 5.
5647+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
5648+
5649+COLS_IN_ALPHA_INDEX = 5
5650+
5651+# In case all classes in a project start with a common prefix, all classes will
5652+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
5653+# can be used to specify a prefix (or a list of prefixes) that should be ignored
5654+# while generating the index headers.
5655+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
5656+
5657+IGNORE_PREFIX =
5658+
5659+#---------------------------------------------------------------------------
5660+# Configuration options related to the HTML output
5661+#---------------------------------------------------------------------------
5662+
5663+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
5664+# The default value is: YES.
5665+
5666+GENERATE_HTML = YES
5667+
5668+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
5669+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
5670+# it.
5671+# The default directory is: html.
5672+# This tag requires that the tag GENERATE_HTML is set to YES.
5673+
5674+HTML_OUTPUT = html
5675+
5676+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
5677+# generated HTML page (for example: .htm, .php, .asp).
5678+# The default value is: .html.
5679+# This tag requires that the tag GENERATE_HTML is set to YES.
5680+
5681+HTML_FILE_EXTENSION = .html
5682+
5683+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
5684+# each generated HTML page. If the tag is left blank doxygen will generate a
5685+# standard header.
5686+#
5687+# To get valid HTML the header file that includes any scripts and style sheets
5688+# that doxygen needs, which is dependent on the configuration options used (e.g.
5689+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
5690+# default header using
5691+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
5692+# YourConfigFile
5693+# and then modify the file new_header.html. See also section "Doxygen usage"
5694+# for information on how to generate the default header that doxygen normally
5695+# uses.
5696+# Note: The header is subject to change so you typically have to regenerate the
5697+# default header when upgrading to a newer version of doxygen. For a description
5698+# of the possible markers and block names see the documentation.
5699+# This tag requires that the tag GENERATE_HTML is set to YES.
5700+
5701+HTML_HEADER =
5702+
5703+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
5704+# generated HTML page. If the tag is left blank doxygen will generate a standard
5705+# footer. See HTML_HEADER for more information on how to generate a default
5706+# footer and what special commands can be used inside the footer. See also
5707+# section "Doxygen usage" for information on how to generate the default footer
5708+# that doxygen normally uses.
5709+# This tag requires that the tag GENERATE_HTML is set to YES.
5710+
5711+HTML_FOOTER =
5712+
5713+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
5714+# sheet that is used by each HTML page. It can be used to fine-tune the look of
5715+# the HTML output. If left blank doxygen will generate a default style sheet.
5716+# See also section "Doxygen usage" for information on how to generate the style
5717+# sheet that doxygen normally uses.
5718+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
5719+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
5720+# obsolete.
5721+# This tag requires that the tag GENERATE_HTML is set to YES.
5722+
5723+HTML_STYLESHEET =
5724+
5725+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
5726+# cascading style sheets that are included after the standard style sheets
5727+# created by doxygen. Using this option one can overrule certain style aspects.
5728+# This is preferred over using HTML_STYLESHEET since it does not replace the
5729+# standard style sheet and is therefore more robust against future updates.
5730+# Doxygen will copy the style sheet files to the output directory.
5731+# Note: The order of the extra style sheet files is of importance (e.g. the last
5732+# style sheet in the list overrules the setting of the previous ones in the
5733+# list). For an example see the documentation.
5734+# This tag requires that the tag GENERATE_HTML is set to YES.
5735+
5736+HTML_EXTRA_STYLESHEET =
5737+
5738+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
5739+# other source files which should be copied to the HTML output directory. Note
5740+# that these files will be copied to the base HTML output directory. Use the
5741+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
5742+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
5743+# files will be copied as-is; there are no commands or markers available.
5744+# This tag requires that the tag GENERATE_HTML is set to YES.
5745+
5746+HTML_EXTRA_FILES =
5747+
5748+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
5749+# will adjust the colors in the style sheet and background images according to
5750+# this color. Hue is specified as an angle on a colorwheel, see
5751+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
5752+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
5753+# purple, and 360 is red again.
5754+# Minimum value: 0, maximum value: 359, default value: 220.
5755+# This tag requires that the tag GENERATE_HTML is set to YES.
5756+
5757+HTML_COLORSTYLE_HUE = 220
5758+
5759+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
5760+# in the HTML output. For a value of 0 the output will use grayscales only. A
5761+# value of 255 will produce the most vivid colors.
5762+# Minimum value: 0, maximum value: 255, default value: 100.
5763+# This tag requires that the tag GENERATE_HTML is set to YES.
5764+
5765+HTML_COLORSTYLE_SAT = 100
5766+
5767+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
5768+# luminance component of the colors in the HTML output. Values below 100
5769+# gradually make the output lighter, whereas values above 100 make the output
5770+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
5771+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
5772+# change the gamma.
5773+# Minimum value: 40, maximum value: 240, default value: 80.
5774+# This tag requires that the tag GENERATE_HTML is set to YES.
5775+
5776+HTML_COLORSTYLE_GAMMA = 80
5777+
5778+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
5779+# page will contain the date and time when the page was generated. Setting this
5780+# to YES can help to show when doxygen was last run and thus if the
5781+# documentation is up to date.
5782+# The default value is: NO.
5783+# This tag requires that the tag GENERATE_HTML is set to YES.
5784+
5785+HTML_TIMESTAMP = NO
5786+
5787+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
5788+# documentation will contain sections that can be hidden and shown after the
5789+# page has loaded.
5790+# The default value is: NO.
5791+# This tag requires that the tag GENERATE_HTML is set to YES.
5792+
5793+HTML_DYNAMIC_SECTIONS = NO
5794+
5795+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
5796+# shown in the various tree structured indices initially; the user can expand
5797+# and collapse entries dynamically later on. Doxygen will expand the tree to
5798+# such a level that at most the specified number of entries are visible (unless
5799+# a fully collapsed tree already exceeds this amount). So setting the number of
5800+# entries 1 will produce a full collapsed tree by default. 0 is a special value
5801+# representing an infinite number of entries and will result in a full expanded
5802+# tree by default.
5803+# Minimum value: 0, maximum value: 9999, default value: 100.
5804+# This tag requires that the tag GENERATE_HTML is set to YES.
5805+
5806+HTML_INDEX_NUM_ENTRIES = 100
5807+
5808+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
5809+# generated that can be used as input for Apple's Xcode 3 integrated development
5810+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
5811+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
5812+# Makefile in the HTML output directory. Running make will produce the docset in
5813+# that directory and running make install will install the docset in
5814+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
5815+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
5816+# for more information.
5817+# The default value is: NO.
5818+# This tag requires that the tag GENERATE_HTML is set to YES.
5819+
5820+GENERATE_DOCSET = NO
5821+
5822+# This tag determines the name of the docset feed. A documentation feed provides
5823+# an umbrella under which multiple documentation sets from a single provider
5824+# (such as a company or product suite) can be grouped.
5825+# The default value is: Doxygen generated docs.
5826+# This tag requires that the tag GENERATE_DOCSET is set to YES.
5827+
5828+DOCSET_FEEDNAME = "Doxygen generated docs"
5829+
5830+# This tag specifies a string that should uniquely identify the documentation
5831+# set bundle. This should be a reverse domain-name style string, e.g.
5832+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
5833+# The default value is: org.doxygen.Project.
5834+# This tag requires that the tag GENERATE_DOCSET is set to YES.
5835+
5836+DOCSET_BUNDLE_ID = org.doxygen.Project
5837+
5838+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
5839+# the documentation publisher. This should be a reverse domain-name style
5840+# string, e.g. com.mycompany.MyDocSet.documentation.
5841+# The default value is: org.doxygen.Publisher.
5842+# This tag requires that the tag GENERATE_DOCSET is set to YES.
5843+
5844+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
5845+
5846+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
5847+# The default value is: Publisher.
5848+# This tag requires that the tag GENERATE_DOCSET is set to YES.
5849+
5850+DOCSET_PUBLISHER_NAME = Publisher
5851+
5852+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
5853+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
5854+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
5855+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
5856+# Windows.
5857+#
5858+# The HTML Help Workshop contains a compiler that can convert all HTML output
5859+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
5860+# files are now used as the Windows 98 help format, and will replace the old
5861+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
5862+# HTML files also contain an index, a table of contents, and you can search for
5863+# words in the documentation. The HTML workshop also contains a viewer for
5864+# compressed HTML files.
5865+# The default value is: NO.
5866+# This tag requires that the tag GENERATE_HTML is set to YES.
5867+
5868+GENERATE_HTMLHELP = NO
5869+
5870+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
5871+# file. You can add a path in front of the file if the result should not be
5872+# written to the html output directory.
5873+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
5874+
5875+CHM_FILE =
5876+
5877+# The HHC_LOCATION tag can be used to specify the location (absolute path
5878+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
5879+# doxygen will try to run the HTML help compiler on the generated index.hhp.
5880+# The file has to be specified with full path.
5881+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
5882+
5883+HHC_LOCATION =
5884+
5885+# The GENERATE_CHI flag controls if a separate .chi index file is generated
5886+# (YES) or that it should be included in the master .chm file (NO).
5887+# The default value is: NO.
5888+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
5889+
5890+GENERATE_CHI = NO
5891+
5892+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
5893+# and project file content.
5894+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
5895+
5896+CHM_INDEX_ENCODING =
5897+
5898+# The BINARY_TOC flag controls whether a binary table of contents is generated
5899+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
5900+# enables the Previous and Next buttons.
5901+# The default value is: NO.
5902+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
5903+
5904+BINARY_TOC = NO
5905+
5906+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
5907+# the table of contents of the HTML help documentation and to the tree view.
5908+# The default value is: NO.
5909+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
5910+
5911+TOC_EXPAND = NO
5912+
5913+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
5914+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
5915+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
5916+# (.qch) of the generated HTML documentation.
5917+# The default value is: NO.
5918+# This tag requires that the tag GENERATE_HTML is set to YES.
5919+
5920+GENERATE_QHP = NO
5921+
5922+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
5923+# the file name of the resulting .qch file. The path specified is relative to
5924+# the HTML output folder.
5925+# This tag requires that the tag GENERATE_QHP is set to YES.
5926+
5927+QCH_FILE =
5928+
5929+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
5930+# Project output. For more information please see Qt Help Project / Namespace
5931+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
5932+# The default value is: org.doxygen.Project.
5933+# This tag requires that the tag GENERATE_QHP is set to YES.
5934+
5935+QHP_NAMESPACE = org.doxygen.Project
5936+
5937+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
5938+# Help Project output. For more information please see Qt Help Project / Virtual
5939+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
5940+# folders).
5941+# The default value is: doc.
5942+# This tag requires that the tag GENERATE_QHP is set to YES.
5943+
5944+QHP_VIRTUAL_FOLDER = doc
5945+
5946+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
5947+# filter to add. For more information please see Qt Help Project / Custom
5948+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
5949+# filters).
5950+# This tag requires that the tag GENERATE_QHP is set to YES.
5951+
5952+QHP_CUST_FILTER_NAME =
5953+
5954+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
5955+# custom filter to add. For more information please see Qt Help Project / Custom
5956+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
5957+# filters).
5958+# This tag requires that the tag GENERATE_QHP is set to YES.
5959+
5960+QHP_CUST_FILTER_ATTRS =
5961+
5962+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
5963+# project's filter section matches. Qt Help Project / Filter Attributes (see:
5964+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
5965+# This tag requires that the tag GENERATE_QHP is set to YES.
5966+
5967+QHP_SECT_FILTER_ATTRS =
5968+
5969+# The QHG_LOCATION tag can be used to specify the location of Qt's
5970+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
5971+# generated .qhp file.
5972+# This tag requires that the tag GENERATE_QHP is set to YES.
5973+
5974+QHG_LOCATION =
5975+
5976+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
5977+# generated, together with the HTML files, they form an Eclipse help plugin. To
5978+# install this plugin and make it available under the help contents menu in
5979+# Eclipse, the contents of the directory containing the HTML and XML files needs
5980+# to be copied into the plugins directory of eclipse. The name of the directory
5981+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
5982+# After copying Eclipse needs to be restarted before the help appears.
5983+# The default value is: NO.
5984+# This tag requires that the tag GENERATE_HTML is set to YES.
5985+
5986+GENERATE_ECLIPSEHELP = NO
5987+
5988+# A unique identifier for the Eclipse help plugin. When installing the plugin
5989+# the directory name containing the HTML and XML files should also have this
5990+# name. Each documentation set should have its own identifier.
5991+# The default value is: org.doxygen.Project.
5992+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
5993+
5994+ECLIPSE_DOC_ID = org.doxygen.Project
5995+
5996+# If you want full control over the layout of the generated HTML pages it might
5997+# be necessary to disable the index and replace it with your own. The
5998+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
5999+# of each HTML page. A value of NO enables the index and the value YES disables
6000+# it. Since the tabs in the index contain the same information as the navigation
6001+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
6002+# The default value is: NO.
6003+# This tag requires that the tag GENERATE_HTML is set to YES.
6004+
6005+DISABLE_INDEX = NO
6006+
6007+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
6008+# structure should be generated to display hierarchical information. If the tag
6009+# value is set to YES, a side panel will be generated containing a tree-like
6010+# index structure (just like the one that is generated for HTML Help). For this
6011+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
6012+# (i.e. any modern browser). Windows users are probably better off using the
6013+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
6014+# further fine-tune the look of the index. As an example, the default style
6015+# sheet generated by doxygen has an example that shows how to put an image at
6016+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
6017+# the same information as the tab index, you could consider setting
6018+# DISABLE_INDEX to YES when enabling this option.
6019+# The default value is: NO.
6020+# This tag requires that the tag GENERATE_HTML is set to YES.
6021+
6022+GENERATE_TREEVIEW = YES
6023+
6024+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
6025+# doxygen will group on one line in the generated HTML documentation.
6026+#
6027+# Note that a value of 0 will completely suppress the enum values from appearing
6028+# in the overview section.
6029+# Minimum value: 0, maximum value: 20, default value: 4.
6030+# This tag requires that the tag GENERATE_HTML is set to YES.
6031+
6032+ENUM_VALUES_PER_LINE = 4
6033+
6034+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
6035+# to set the initial width (in pixels) of the frame in which the tree is shown.
6036+# Minimum value: 0, maximum value: 1500, default value: 250.
6037+# This tag requires that the tag GENERATE_HTML is set to YES.
6038+
6039+TREEVIEW_WIDTH = 250
6040+
6041+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
6042+# external symbols imported via tag files in a separate window.
6043+# The default value is: NO.
6044+# This tag requires that the tag GENERATE_HTML is set to YES.
6045+
6046+EXT_LINKS_IN_WINDOW = NO
6047+
6048+# Use this tag to change the font size of LaTeX formulas included as images in
6049+# the HTML documentation. When you change the font size after a successful
6050+# doxygen run you need to manually remove any form_*.png images from the HTML
6051+# output directory to force them to be regenerated.
6052+# Minimum value: 8, maximum value: 50, default value: 10.
6053+# This tag requires that the tag GENERATE_HTML is set to YES.
6054+
6055+FORMULA_FONTSIZE = 10
6056+
6057+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
6058+# generated for formulas are transparent PNGs. Transparent PNGs are not
6059+# supported properly for IE 6.0, but are supported on all modern browsers.
6060+#
6061+# Note that when changing this option you need to delete any form_*.png files in
6062+# the HTML output directory before the changes have effect.
6063+# The default value is: YES.
6064+# This tag requires that the tag GENERATE_HTML is set to YES.
6065+
6066+FORMULA_TRANSPARENT = YES
6067+
6068+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
6069+# http://www.mathjax.org) which uses client side Javascript for the rendering
6070+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
6071+# installed or if you want to formulas look prettier in the HTML output. When
6072+# enabled you may also need to install MathJax separately and configure the path
6073+# to it using the MATHJAX_RELPATH option.
6074+# The default value is: NO.
6075+# This tag requires that the tag GENERATE_HTML is set to YES.
6076+
6077+USE_MATHJAX = NO
6078+
6079+# When MathJax is enabled you can set the default output format to be used for
6080+# the MathJax output. See the MathJax site (see:
6081+# http://docs.mathjax.org/en/latest/output.html) for more details.
6082+# Possible values are: HTML-CSS (which is slower, but has the best
6083+# compatibility), NativeMML (i.e. MathML) and SVG.
6084+# The default value is: HTML-CSS.
6085+# This tag requires that the tag USE_MATHJAX is set to YES.
6086+
6087+MATHJAX_FORMAT = HTML-CSS
6088+
6089+# When MathJax is enabled you need to specify the location relative to the HTML
6090+# output directory using the MATHJAX_RELPATH option. The destination directory
6091+# should contain the MathJax.js script. For instance, if the mathjax directory
6092+# is located at the same level as the HTML output directory, then
6093+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
6094+# Content Delivery Network so you can quickly see the result without installing
6095+# MathJax. However, it is strongly recommended to install a local copy of
6096+# MathJax from http://www.mathjax.org before deployment.
6097+# The default value is: http://cdn.mathjax.org/mathjax/latest.
6098+# This tag requires that the tag USE_MATHJAX is set to YES.
6099+
6100+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
6101+
6102+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
6103+# extension names that should be enabled during MathJax rendering. For example
6104+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
6105+# This tag requires that the tag USE_MATHJAX is set to YES.
6106+
6107+MATHJAX_EXTENSIONS =
6108+
6109+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
6110+# of code that will be used on startup of the MathJax code. See the MathJax site
6111+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
6112+# example see the documentation.
6113+# This tag requires that the tag USE_MATHJAX is set to YES.
6114+
6115+MATHJAX_CODEFILE =
6116+
6117+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
6118+# the HTML output. The underlying search engine uses javascript and DHTML and
6119+# should work on any modern browser. Note that when using HTML help
6120+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
6121+# there is already a search function so this one should typically be disabled.
6122+# For large projects the javascript based search engine can be slow, then
6123+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
6124+# search using the keyboard; to jump to the search box use <access key> + S
6125+# (what the <access key> is depends on the OS and browser, but it is typically
6126+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
6127+# key> to jump into the search results window, the results can be navigated
6128+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
6129+# the search. The filter options can be selected when the cursor is inside the
6130+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
6131+# to select a filter and <Enter> or <escape> to activate or cancel the filter
6132+# option.
6133+# The default value is: YES.
6134+# This tag requires that the tag GENERATE_HTML is set to YES.
6135+
6136+SEARCHENGINE = YES
6137+
6138+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
6139+# implemented using a web server instead of a web client using Javascript. There
6140+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
6141+# setting. When disabled, doxygen will generate a PHP script for searching and
6142+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
6143+# and searching needs to be provided by external tools. See the section
6144+# "External Indexing and Searching" for details.
6145+# The default value is: NO.
6146+# This tag requires that the tag SEARCHENGINE is set to YES.
6147+
6148+SERVER_BASED_SEARCH = NO
6149+
6150+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
6151+# script for searching. Instead the search results are written to an XML file
6152+# which needs to be processed by an external indexer. Doxygen will invoke an
6153+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
6154+# search results.
6155+#
6156+# Doxygen ships with an example indexer (doxyindexer) and search engine
6157+# (doxysearch.cgi) which are based on the open source search engine library
6158+# Xapian (see: http://xapian.org/).
6159+#
6160+# See the section "External Indexing and Searching" for details.
6161+# The default value is: NO.
6162+# This tag requires that the tag SEARCHENGINE is set to YES.
6163+
6164+EXTERNAL_SEARCH = NO
6165+
6166+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
6167+# which will return the search results when EXTERNAL_SEARCH is enabled.
6168+#
6169+# Doxygen ships with an example indexer (doxyindexer) and search engine
6170+# (doxysearch.cgi) which are based on the open source search engine library
6171+# Xapian (see: http://xapian.org/). See the section "External Indexing and
6172+# Searching" for details.
6173+# This tag requires that the tag SEARCHENGINE is set to YES.
6174+
6175+SEARCHENGINE_URL =
6176+
6177+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
6178+# search data is written to a file for indexing by an external tool. With the
6179+# SEARCHDATA_FILE tag the name of this file can be specified.
6180+# The default file is: searchdata.xml.
6181+# This tag requires that the tag SEARCHENGINE is set to YES.
6182+
6183+SEARCHDATA_FILE = searchdata.xml
6184+
6185+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
6186+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
6187+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
6188+# projects and redirect the results back to the right project.
6189+# This tag requires that the tag SEARCHENGINE is set to YES.
6190+
6191+EXTERNAL_SEARCH_ID =
6192+
6193+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
6194+# projects other than the one defined by this configuration file, but that are
6195+# all added to the same external search index. Each project needs to have a
6196+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
6197+# to a relative location where the documentation can be found. The format is:
6198+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
6199+# This tag requires that the tag SEARCHENGINE is set to YES.
6200+
6201+EXTRA_SEARCH_MAPPINGS =
6202+
6203+#---------------------------------------------------------------------------
6204+# Configuration options related to the LaTeX output
6205+#---------------------------------------------------------------------------
6206+
6207+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
6208+# The default value is: YES.
6209+
6210+GENERATE_LATEX = YES
6211+
6212+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
6213+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
6214+# it.
6215+# The default directory is: latex.
6216+# This tag requires that the tag GENERATE_LATEX is set to YES.
6217+
6218+LATEX_OUTPUT = latex
6219+
6220+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
6221+# invoked.
6222+#
6223+# Note that when enabling USE_PDFLATEX this option is only used for generating
6224+# bitmaps for formulas in the HTML output, but not in the Makefile that is
6225+# written to the output directory.
6226+# The default file is: latex.
6227+# This tag requires that the tag GENERATE_LATEX is set to YES.
6228+
6229+LATEX_CMD_NAME = latex
6230+
6231+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
6232+# index for LaTeX.
6233+# The default file is: makeindex.
6234+# This tag requires that the tag GENERATE_LATEX is set to YES.
6235+
6236+MAKEINDEX_CMD_NAME = makeindex
6237+
6238+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
6239+# documents. This may be useful for small projects and may help to save some
6240+# trees in general.
6241+# The default value is: NO.
6242+# This tag requires that the tag GENERATE_LATEX is set to YES.
6243+
6244+COMPACT_LATEX = NO
6245+
6246+# The PAPER_TYPE tag can be used to set the paper type that is used by the
6247+# printer.
6248+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
6249+# 14 inches) and executive (7.25 x 10.5 inches).
6250+# The default value is: a4.
6251+# This tag requires that the tag GENERATE_LATEX is set to YES.
6252+
6253+PAPER_TYPE = a4
6254+
6255+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
6256+# that should be included in the LaTeX output. The package can be specified just
6257+# by its name or with the correct syntax as to be used with the LaTeX
6258+# \usepackage command. To get the times font for instance you can specify :
6259+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
6260+# To use the option intlimits with the amsmath package you can specify:
6261+# EXTRA_PACKAGES=[intlimits]{amsmath}
6262+# If left blank no extra packages will be included.
6263+# This tag requires that the tag GENERATE_LATEX is set to YES.
6264+
6265+EXTRA_PACKAGES =
6266+
6267+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
6268+# generated LaTeX document. The header should contain everything until the first
6269+# chapter. If it is left blank doxygen will generate a standard header. See
6270+# section "Doxygen usage" for information on how to let doxygen write the
6271+# default header to a separate file.
6272+#
6273+# Note: Only use a user-defined header if you know what you are doing! The
6274+# following commands have a special meaning inside the header: $title,
6275+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
6276+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
6277+# string, for the replacement values of the other commands the user is referred
6278+# to HTML_HEADER.
6279+# This tag requires that the tag GENERATE_LATEX is set to YES.
6280+
6281+LATEX_HEADER =
6282+
6283+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
6284+# generated LaTeX document. The footer should contain everything after the last
6285+# chapter. If it is left blank doxygen will generate a standard footer. See
6286+# LATEX_HEADER for more information on how to generate a default footer and what
6287+# special commands can be used inside the footer.
6288+#
6289+# Note: Only use a user-defined footer if you know what you are doing!
6290+# This tag requires that the tag GENERATE_LATEX is set to YES.
6291+
6292+LATEX_FOOTER =
6293+
6294+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
6295+# LaTeX style sheets that are included after the standard style sheets created
6296+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
6297+# will copy the style sheet files to the output directory.
6298+# Note: The order of the extra style sheet files is of importance (e.g. the last
6299+# style sheet in the list overrules the setting of the previous ones in the
6300+# list).
6301+# This tag requires that the tag GENERATE_LATEX is set to YES.
6302+
6303+LATEX_EXTRA_STYLESHEET =
6304+
6305+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
6306+# other source files which should be copied to the LATEX_OUTPUT output
6307+# directory. Note that the files will be copied as-is; there are no commands or
6308+# markers available.
6309+# This tag requires that the tag GENERATE_LATEX is set to YES.
6310+
6311+LATEX_EXTRA_FILES =
6312+
6313+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
6314+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
6315+# contain links (just like the HTML output) instead of page references. This
6316+# makes the output suitable for online browsing using a PDF viewer.
6317+# The default value is: YES.
6318+# This tag requires that the tag GENERATE_LATEX is set to YES.
6319+
6320+PDF_HYPERLINKS = YES
6321+
6322+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
6323+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
6324+# higher quality PDF documentation.
6325+# The default value is: YES.
6326+# This tag requires that the tag GENERATE_LATEX is set to YES.
6327+
6328+USE_PDFLATEX = YES
6329+
6330+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
6331+# command to the generated LaTeX files. This will instruct LaTeX to keep running
6332+# if errors occur, instead of asking the user for help. This option is also used
6333+# when generating formulas in HTML.
6334+# The default value is: NO.
6335+# This tag requires that the tag GENERATE_LATEX is set to YES.
6336+
6337+LATEX_BATCHMODE = NO
6338+
6339+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
6340+# index chapters (such as File Index, Compound Index, etc.) in the output.
6341+# The default value is: NO.
6342+# This tag requires that the tag GENERATE_LATEX is set to YES.
6343+
6344+LATEX_HIDE_INDICES = NO
6345+
6346+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
6347+# code with syntax highlighting in the LaTeX output.
6348+#
6349+# Note that which sources are shown also depends on other settings such as
6350+# SOURCE_BROWSER.
6351+# The default value is: NO.
6352+# This tag requires that the tag GENERATE_LATEX is set to YES.
6353+
6354+LATEX_SOURCE_CODE = NO
6355+
6356+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
6357+# bibliography, e.g. plainnat, or ieeetr. See
6358+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
6359+# The default value is: plain.
6360+# This tag requires that the tag GENERATE_LATEX is set to YES.
6361+
6362+LATEX_BIB_STYLE = plain
6363+
6364+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
6365+# page will contain the date and time when the page was generated. Setting this
6366+# to NO can help when comparing the output of multiple runs.
6367+# The default value is: NO.
6368+# This tag requires that the tag GENERATE_LATEX is set to YES.
6369+
6370+LATEX_TIMESTAMP = NO
6371+
6372+#---------------------------------------------------------------------------
6373+# Configuration options related to the RTF output
6374+#---------------------------------------------------------------------------
6375+
6376+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
6377+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
6378+# readers/editors.
6379+# The default value is: NO.
6380+
6381+GENERATE_RTF = NO
6382+
6383+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
6384+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
6385+# it.
6386+# The default directory is: rtf.
6387+# This tag requires that the tag GENERATE_RTF is set to YES.
6388+
6389+RTF_OUTPUT = rtf
6390+
6391+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
6392+# documents. This may be useful for small projects and may help to save some
6393+# trees in general.
6394+# The default value is: NO.
6395+# This tag requires that the tag GENERATE_RTF is set to YES.
6396+
6397+COMPACT_RTF = NO
6398+
6399+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
6400+# contain hyperlink fields. The RTF file will contain links (just like the HTML
6401+# output) instead of page references. This makes the output suitable for online
6402+# browsing using Word or some other Word compatible readers that support those
6403+# fields.
6404+#
6405+# Note: WordPad (write) and others do not support links.
6406+# The default value is: NO.
6407+# This tag requires that the tag GENERATE_RTF is set to YES.
6408+
6409+RTF_HYPERLINKS = NO
6410+
6411+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
6412+# file, i.e. a series of assignments. You only have to provide replacements,
6413+# missing definitions are set to their default value.
6414+#
6415+# See also section "Doxygen usage" for information on how to generate the
6416+# default style sheet that doxygen normally uses.
6417+# This tag requires that the tag GENERATE_RTF is set to YES.
6418+
6419+RTF_STYLESHEET_FILE =
6420+
6421+# Set optional variables used in the generation of an RTF document. Syntax is
6422+# similar to doxygen's config file. A template extensions file can be generated
6423+# using doxygen -e rtf extensionFile.
6424+# This tag requires that the tag GENERATE_RTF is set to YES.
6425+
6426+RTF_EXTENSIONS_FILE =
6427+
6428+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
6429+# with syntax highlighting in the RTF output.
6430+#
6431+# Note that which sources are shown also depends on other settings such as
6432+# SOURCE_BROWSER.
6433+# The default value is: NO.
6434+# This tag requires that the tag GENERATE_RTF is set to YES.
6435+
6436+RTF_SOURCE_CODE = NO
6437+
6438+#---------------------------------------------------------------------------
6439+# Configuration options related to the man page output
6440+#---------------------------------------------------------------------------
6441+
6442+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
6443+# classes and files.
6444+# The default value is: NO.
6445+
6446+GENERATE_MAN = NO
6447+
6448+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
6449+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
6450+# it. A directory man3 will be created inside the directory specified by
6451+# MAN_OUTPUT.
6452+# The default directory is: man.
6453+# This tag requires that the tag GENERATE_MAN is set to YES.
6454+
6455+MAN_OUTPUT = man
6456+
6457+# The MAN_EXTENSION tag determines the extension that is added to the generated
6458+# man pages. In case the manual section does not start with a number, the number
6459+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
6460+# optional.
6461+# The default value is: .3.
6462+# This tag requires that the tag GENERATE_MAN is set to YES.
6463+
6464+MAN_EXTENSION = .3
6465+
6466+# The MAN_SUBDIR tag determines the name of the directory created within
6467+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
6468+# MAN_EXTENSION with the initial . removed.
6469+# This tag requires that the tag GENERATE_MAN is set to YES.
6470+
6471+MAN_SUBDIR =
6472+
6473+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
6474+# will generate one additional man file for each entity documented in the real
6475+# man page(s). These additional files only source the real man page, but without
6476+# them the man command would be unable to find the correct page.
6477+# The default value is: NO.
6478+# This tag requires that the tag GENERATE_MAN is set to YES.
6479+
6480+MAN_LINKS = NO
6481+
6482+#---------------------------------------------------------------------------
6483+# Configuration options related to the XML output
6484+#---------------------------------------------------------------------------
6485+
6486+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
6487+# captures the structure of the code including all documentation.
6488+# The default value is: NO.
6489+
6490+GENERATE_XML = NO
6491+
6492+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
6493+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
6494+# it.
6495+# The default directory is: xml.
6496+# This tag requires that the tag GENERATE_XML is set to YES.
6497+
6498+XML_OUTPUT = xml
6499+
6500+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
6501+# listings (including syntax highlighting and cross-referencing information) to
6502+# the XML output. Note that enabling this will significantly increase the size
6503+# of the XML output.
6504+# The default value is: YES.
6505+# This tag requires that the tag GENERATE_XML is set to YES.
6506+
6507+XML_PROGRAMLISTING = YES
6508+
6509+#---------------------------------------------------------------------------
6510+# Configuration options related to the DOCBOOK output
6511+#---------------------------------------------------------------------------
6512+
6513+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
6514+# that can be used to generate PDF.
6515+# The default value is: NO.
6516+
6517+GENERATE_DOCBOOK = NO
6518+
6519+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
6520+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
6521+# front of it.
6522+# The default directory is: docbook.
6523+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
6524+
6525+DOCBOOK_OUTPUT = docbook
6526+
6527+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
6528+# program listings (including syntax highlighting and cross-referencing
6529+# information) to the DOCBOOK output. Note that enabling this will significantly
6530+# increase the size of the DOCBOOK output.
6531+# The default value is: NO.
6532+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
6533+
6534+DOCBOOK_PROGRAMLISTING = NO
6535+
6536+#---------------------------------------------------------------------------
6537+# Configuration options for the AutoGen Definitions output
6538+#---------------------------------------------------------------------------
6539+
6540+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
6541+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
6542+# structure of the code including all documentation. Note that this feature is
6543+# still experimental and incomplete at the moment.
6544+# The default value is: NO.
6545+
6546+GENERATE_AUTOGEN_DEF = NO
6547+
6548+#---------------------------------------------------------------------------
6549+# Configuration options related to the Perl module output
6550+#---------------------------------------------------------------------------
6551+
6552+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
6553+# file that captures the structure of the code including all documentation.
6554+#
6555+# Note that this feature is still experimental and incomplete at the moment.
6556+# The default value is: NO.
6557+
6558+GENERATE_PERLMOD = NO
6559+
6560+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
6561+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
6562+# output from the Perl module output.
6563+# The default value is: NO.
6564+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
6565+
6566+PERLMOD_LATEX = NO
6567+
6568+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
6569+# formatted so it can be parsed by a human reader. This is useful if you want to
6570+# understand what is going on. On the other hand, if this tag is set to NO, the
6571+# size of the Perl module output will be much smaller and Perl will parse it
6572+# just the same.
6573+# The default value is: YES.
6574+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
6575+
6576+PERLMOD_PRETTY = YES
6577+
6578+# The names of the make variables in the generated doxyrules.make file are
6579+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
6580+# so different doxyrules.make files included by the same Makefile don't
6581+# overwrite each other's variables.
6582+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
6583+
6584+PERLMOD_MAKEVAR_PREFIX =
6585+
6586+#---------------------------------------------------------------------------
6587+# Configuration options related to the preprocessor
6588+#---------------------------------------------------------------------------
6589+
6590+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
6591+# C-preprocessor directives found in the sources and include files.
6592+# The default value is: YES.
6593+
6594+ENABLE_PREPROCESSING = YES
6595+
6596+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
6597+# in the source code. If set to NO, only conditional compilation will be
6598+# performed. Macro expansion can be done in a controlled way by setting
6599+# EXPAND_ONLY_PREDEF to YES.
6600+# The default value is: NO.
6601+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6602+
6603+MACRO_EXPANSION = NO
6604+
6605+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
6606+# the macro expansion is limited to the macros specified with the PREDEFINED and
6607+# EXPAND_AS_DEFINED tags.
6608+# The default value is: NO.
6609+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6610+
6611+EXPAND_ONLY_PREDEF = NO
6612+
6613+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
6614+# INCLUDE_PATH will be searched if a #include is found.
6615+# The default value is: YES.
6616+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6617+
6618+SEARCH_INCLUDES = YES
6619+
6620+# The INCLUDE_PATH tag can be used to specify one or more directories that
6621+# contain include files that are not input files but should be processed by the
6622+# preprocessor.
6623+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
6624+
6625+INCLUDE_PATH =
6626+
6627+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
6628+# patterns (like *.h and *.hpp) to filter out the header-files in the
6629+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
6630+# used.
6631+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6632+
6633+INCLUDE_FILE_PATTERNS =
6634+
6635+# The PREDEFINED tag can be used to specify one or more macro names that are
6636+# defined before the preprocessor is started (similar to the -D option of e.g.
6637+# gcc). The argument of the tag is a list of macros of the form: name or
6638+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
6639+# is assumed. To prevent a macro definition from being undefined via #undef or
6640+# recursively expanded use the := operator instead of the = operator.
6641+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6642+
6643+PREDEFINED =
6644+
6645+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
6646+# tag can be used to specify a list of macro names that should be expanded. The
6647+# macro definition that is found in the sources will be used. Use the PREDEFINED
6648+# tag if you want to use a different macro definition that overrules the
6649+# definition found in the source code.
6650+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6651+
6652+EXPAND_AS_DEFINED =
6653+
6654+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
6655+# remove all references to function-like macros that are alone on a line, have
6656+# an all uppercase name, and do not end with a semicolon. Such function macros
6657+# are typically used for boiler-plate code, and will confuse the parser if not
6658+# removed.
6659+# The default value is: YES.
6660+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
6661+
6662+SKIP_FUNCTION_MACROS = YES
6663+
6664+#---------------------------------------------------------------------------
6665+# Configuration options related to external references
6666+#---------------------------------------------------------------------------
6667+
6668+# The TAGFILES tag can be used to specify one or more tag files. For each tag
6669+# file the location of the external documentation should be added. The format of
6670+# a tag file without this location is as follows:
6671+# TAGFILES = file1 file2 ...
6672+# Adding location for the tag files is done as follows:
6673+# TAGFILES = file1=loc1 "file2 = loc2" ...
6674+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
6675+# section "Linking to external documentation" for more information about the use
6676+# of tag files.
6677+# Note: Each tag file must have a unique name (where the name does NOT include
6678+# the path). If a tag file is not located in the directory in which doxygen is
6679+# run, you must also specify the path to the tagfile here.
6680+
6681+TAGFILES =
6682+
6683+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
6684+# tag file that is based on the input files it reads. See section "Linking to
6685+# external documentation" for more information about the usage of tag files.
6686+
6687+GENERATE_TAGFILE =
6688+
6689+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
6690+# the class index. If set to NO, only the inherited external classes will be
6691+# listed.
6692+# The default value is: NO.
6693+
6694+ALLEXTERNALS = NO
6695+
6696+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
6697+# in the modules index. If set to NO, only the current project's groups will be
6698+# listed.
6699+# The default value is: YES.
6700+
6701+EXTERNAL_GROUPS = YES
6702+
6703+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
6704+# the related pages index. If set to NO, only the current project's pages will
6705+# be listed.
6706+# The default value is: YES.
6707+
6708+EXTERNAL_PAGES = YES
6709+
6710+# The PERL_PATH should be the absolute path and name of the perl script
6711+# interpreter (i.e. the result of 'which perl').
6712+# The default file (with absolute path) is: /usr/bin/perl.
6713+
6714+PERL_PATH = /usr/bin/perl
6715+
6716+#---------------------------------------------------------------------------
6717+# Configuration options related to the dot tool
6718+#---------------------------------------------------------------------------
6719+
6720+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
6721+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
6722+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
6723+# disabled, but it is recommended to install and use dot, since it yields more
6724+# powerful graphs.
6725+# The default value is: YES.
6726+
6727+CLASS_DIAGRAMS = YES
6728+
6729+# You can define message sequence charts within doxygen comments using the \msc
6730+# command. Doxygen will then run the mscgen tool (see:
6731+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
6732+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
6733+# the mscgen tool resides. If left empty the tool is assumed to be found in the
6734+# default search path.
6735+
6736+MSCGEN_PATH =
6737+
6738+# You can include diagrams made with dia in doxygen documentation. Doxygen will
6739+# then run dia to produce the diagram and insert it in the documentation. The
6740+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
6741+# If left empty dia is assumed to be found in the default search path.
6742+
6743+DIA_PATH =
6744+
6745+# If set to YES the inheritance and collaboration graphs will hide inheritance
6746+# and usage relations if the target is undocumented or is not a class.
6747+# The default value is: YES.
6748+
6749+HIDE_UNDOC_RELATIONS = YES
6750+
6751+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
6752+# available from the path. This tool is part of Graphviz (see:
6753+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
6754+# Bell Labs. The other options in this section have no effect if this option is
6755+# set to NO
6756+# The default value is: NO.
6757+
6758+HAVE_DOT = NO
6759+
6760+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
6761+# to run in parallel. When set to 0 doxygen will base this on the number of
6762+# processors available in the system. You can set it explicitly to a value
6763+# larger than 0 to get control over the balance between CPU load and processing
6764+# speed.
6765+# Minimum value: 0, maximum value: 32, default value: 0.
6766+# This tag requires that the tag HAVE_DOT is set to YES.
6767+
6768+DOT_NUM_THREADS = 0
6769+
6770+# When you want a differently looking font in the dot files that doxygen
6771+# generates you can specify the font name using DOT_FONTNAME. You need to make
6772+# sure dot is able to find the font, which can be done by putting it in a
6773+# standard location or by setting the DOTFONTPATH environment variable or by
6774+# setting DOT_FONTPATH to the directory containing the font.
6775+# The default value is: Helvetica.
6776+# This tag requires that the tag HAVE_DOT is set to YES.
6777+
6778+DOT_FONTNAME = Helvetica
6779+
6780+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
6781+# dot graphs.
6782+# Minimum value: 4, maximum value: 24, default value: 10.
6783+# This tag requires that the tag HAVE_DOT is set to YES.
6784+
6785+DOT_FONTSIZE = 10
6786+
6787+# By default doxygen will tell dot to use the default font as specified with
6788+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
6789+# the path where dot can find it using this tag.
6790+# This tag requires that the tag HAVE_DOT is set to YES.
6791+
6792+DOT_FONTPATH =
6793+
6794+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
6795+# each documented class showing the direct and indirect inheritance relations.
6796+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
6797+# The default value is: YES.
6798+# This tag requires that the tag HAVE_DOT is set to YES.
6799+
6800+CLASS_GRAPH = YES
6801+
6802+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
6803+# graph for each documented class showing the direct and indirect implementation
6804+# dependencies (inheritance, containment, and class references variables) of the
6805+# class with other documented classes.
6806+# The default value is: YES.
6807+# This tag requires that the tag HAVE_DOT is set to YES.
6808+
6809+COLLABORATION_GRAPH = YES
6810+
6811+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
6812+# groups, showing the direct groups dependencies.
6813+# The default value is: YES.
6814+# This tag requires that the tag HAVE_DOT is set to YES.
6815+
6816+GROUP_GRAPHS = YES
6817+
6818+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
6819+# collaboration diagrams in a style similar to the OMG's Unified Modeling
6820+# Language.
6821+# The default value is: NO.
6822+# This tag requires that the tag HAVE_DOT is set to YES.
6823+
6824+UML_LOOK = NO
6825+
6826+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
6827+# class node. If there are many fields or methods and many nodes the graph may
6828+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
6829+# number of items for each type to make the size more manageable. Set this to 0
6830+# for no limit. Note that the threshold may be exceeded by 50% before the limit
6831+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
6832+# but if the number exceeds 15, the total amount of fields shown is limited to
6833+# 10.
6834+# Minimum value: 0, maximum value: 100, default value: 10.
6835+# This tag requires that the tag HAVE_DOT is set to YES.
6836+
6837+UML_LIMIT_NUM_FIELDS = 10
6838+
6839+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
6840+# collaboration graphs will show the relations between templates and their
6841+# instances.
6842+# The default value is: NO.
6843+# This tag requires that the tag HAVE_DOT is set to YES.
6844+
6845+TEMPLATE_RELATIONS = NO
6846+
6847+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
6848+# YES then doxygen will generate a graph for each documented file showing the
6849+# direct and indirect include dependencies of the file with other documented
6850+# files.
6851+# The default value is: YES.
6852+# This tag requires that the tag HAVE_DOT is set to YES.
6853+
6854+INCLUDE_GRAPH = YES
6855+
6856+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
6857+# set to YES then doxygen will generate a graph for each documented file showing
6858+# the direct and indirect include dependencies of the file with other documented
6859+# files.
6860+# The default value is: YES.
6861+# This tag requires that the tag HAVE_DOT is set to YES.
6862+
6863+INCLUDED_BY_GRAPH = YES
6864+
6865+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
6866+# dependency graph for every global function or class method.
6867+#
6868+# Note that enabling this option will significantly increase the time of a run.
6869+# So in most cases it will be better to enable call graphs for selected
6870+# functions only using the \callgraph command. Disabling a call graph can be
6871+# accomplished by means of the command \hidecallgraph.
6872+# The default value is: NO.
6873+# This tag requires that the tag HAVE_DOT is set to YES.
6874+
6875+CALL_GRAPH = NO
6876+
6877+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
6878+# dependency graph for every global function or class method.
6879+#
6880+# Note that enabling this option will significantly increase the time of a run.
6881+# So in most cases it will be better to enable caller graphs for selected
6882+# functions only using the \callergraph command. Disabling a caller graph can be
6883+# accomplished by means of the command \hidecallergraph.
6884+# The default value is: NO.
6885+# This tag requires that the tag HAVE_DOT is set to YES.
6886+
6887+CALLER_GRAPH = NO
6888+
6889+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
6890+# hierarchy of all classes instead of a textual one.
6891+# The default value is: YES.
6892+# This tag requires that the tag HAVE_DOT is set to YES.
6893+
6894+GRAPHICAL_HIERARCHY = YES
6895+
6896+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
6897+# dependencies a directory has on other directories in a graphical way. The
6898+# dependency relations are determined by the #include relations between the
6899+# files in the directories.
6900+# The default value is: YES.
6901+# This tag requires that the tag HAVE_DOT is set to YES.
6902+
6903+DIRECTORY_GRAPH = YES
6904+
6905+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
6906+# generated by dot. For an explanation of the image formats see the section
6907+# output formats in the documentation of the dot tool (Graphviz (see:
6908+# http://www.graphviz.org/)).
6909+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
6910+# to make the SVG files visible in IE 9+ (other browsers do not have this
6911+# requirement).
6912+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
6913+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
6914+# png:gdiplus:gdiplus.
6915+# The default value is: png.
6916+# This tag requires that the tag HAVE_DOT is set to YES.
6917+
6918+DOT_IMAGE_FORMAT = png
6919+
6920+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
6921+# enable generation of interactive SVG images that allow zooming and panning.
6922+#
6923+# Note that this requires a modern browser other than Internet Explorer. Tested
6924+# and working are Firefox, Chrome, Safari, and Opera.
6925+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
6926+# the SVG files visible. Older versions of IE do not have SVG support.
6927+# The default value is: NO.
6928+# This tag requires that the tag HAVE_DOT is set to YES.
6929+
6930+INTERACTIVE_SVG = NO
6931+
6932+# The DOT_PATH tag can be used to specify the path where the dot tool can be
6933+# found. If left blank, it is assumed the dot tool can be found in the path.
6934+# This tag requires that the tag HAVE_DOT is set to YES.
6935+
6936+DOT_PATH =
6937+
6938+# The DOTFILE_DIRS tag can be used to specify one or more directories that
6939+# contain dot files that are included in the documentation (see the \dotfile
6940+# command).
6941+# This tag requires that the tag HAVE_DOT is set to YES.
6942+
6943+DOTFILE_DIRS =
6944+
6945+# The MSCFILE_DIRS tag can be used to specify one or more directories that
6946+# contain msc files that are included in the documentation (see the \mscfile
6947+# command).
6948+
6949+MSCFILE_DIRS =
6950+
6951+# The DIAFILE_DIRS tag can be used to specify one or more directories that
6952+# contain dia files that are included in the documentation (see the \diafile
6953+# command).
6954+
6955+DIAFILE_DIRS =
6956+
6957+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
6958+# path where java can find the plantuml.jar file. If left blank, it is assumed
6959+# PlantUML is not used or called during a preprocessing step. Doxygen will
6960+# generate a warning when it encounters a \startuml command in this case and
6961+# will not generate output for the diagram.
6962+
6963+PLANTUML_JAR_PATH =
6964+
6965+# When using plantuml, the specified paths are searched for files specified by
6966+# the !include statement in a plantuml block.
6967+
6968+PLANTUML_INCLUDE_PATH =
6969+
6970+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
6971+# that will be shown in the graph. If the number of nodes in a graph becomes
6972+# larger than this value, doxygen will truncate the graph, which is visualized
6973+# by representing a node as a red box. Note that doxygen if the number of direct
6974+# children of the root node in a graph is already larger than
6975+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
6976+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
6977+# Minimum value: 0, maximum value: 10000, default value: 50.
6978+# This tag requires that the tag HAVE_DOT is set to YES.
6979+
6980+DOT_GRAPH_MAX_NODES = 50
6981+
6982+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
6983+# generated by dot. A depth value of 3 means that only nodes reachable from the
6984+# root by following a path via at most 3 edges will be shown. Nodes that lay
6985+# further from the root node will be omitted. Note that setting this option to 1
6986+# or 2 may greatly reduce the computation time needed for large code bases. Also
6987+# note that the size of a graph can be further restricted by
6988+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
6989+# Minimum value: 0, maximum value: 1000, default value: 0.
6990+# This tag requires that the tag HAVE_DOT is set to YES.
6991+
6992+MAX_DOT_GRAPH_DEPTH = 0
6993+
6994+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
6995+# background. This is disabled by default, because dot on Windows does not seem
6996+# to support this out of the box.
6997+#
6998+# Warning: Depending on the platform used, enabling this option may lead to
6999+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
7000+# read).
7001+# The default value is: NO.
7002+# This tag requires that the tag HAVE_DOT is set to YES.
7003+
7004+DOT_TRANSPARENT = NO
7005+
7006+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
7007+# files in one run (i.e. multiple -o and -T options on the command line). This
7008+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
7009+# this, this feature is disabled by default.
7010+# The default value is: NO.
7011+# This tag requires that the tag HAVE_DOT is set to YES.
7012+
7013+DOT_MULTI_TARGETS = NO
7014+
7015+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
7016+# explaining the meaning of the various boxes and arrows in the dot generated
7017+# graphs.
7018+# The default value is: YES.
7019+# This tag requires that the tag HAVE_DOT is set to YES.
7020+
7021+GENERATE_LEGEND = YES
7022+
7023+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
7024+# files that are used to generate the various graphs.
7025+# The default value is: YES.
7026+# This tag requires that the tag HAVE_DOT is set to YES.
7027+
7028+DOT_CLEANUP = YES
7029diff --git a/Hand.cpp b/Hand.cpp
7030index 214c78a..732a664 100644
7031--- a/Hand.cpp
7032+++ b/Hand.cpp
7033@@ -1,299 +1,289 @@
7034-#include "Hand.h"
7035-#include "Util.h"
7036-#include "Visualizer.h"
7037-#include "global.h"
7038-
7039-Hand::Hand()
7040-{
7041-
7042-}
7043-
7044-Hand::Hand(cv::Mat xyzMap, float angle_threshhold, int cluster_thresh)
7045-{
7046- CLUSTER_THRESHOLD = cluster_thresh;
7047- ANGLE_THRESHHOLD = angle_threshhold;
7048- analyzeHand(xyzMap);
7049-}
7050-
7051-Hand::~Hand()
7052-{
7053-
7054-}
7055-
7056-void Hand::analyzeHand(cv::Mat xyzMap)
7057-{
7058-
7059- cv::Mat normalizedDepthMap;
7060- cv::Mat channel[3];
7061- cv::split(xyzMap, channel);
7062- cv::normalize(channel[2], normalizedDepthMap, 0, 255, cv::NORM_MINMAX, CV_8UC1);
7063-
7064- // Resize input
7065- cv::Mat input;
7066- cv::pyrUp(normalizedDepthMap, input, cv::Size(normalizedDepthMap.cols * 2, normalizedDepthMap.rows * 2));
7067-
7068- cv::pyrUp(input, input, cv::Size(input.cols * 2, input.rows * 2));
7069- cv::Mat threshold_output;
7070- std::vector< std::vector<cv::Point> > contours;
7071- std::vector<cv::Vec4i> hierarchy;
7072-
7073- // Find contours
7074-
7075- cv::threshold(input, threshold_output, 100, 255, cv::THRESH_BINARY);
7076- cv::findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
7077-
7078- // Find contour polygon
7079-
7080- std::vector< std::vector< cv::Point> > contours_poly(contours.size());
7081- for (int i = 0; i < contours.size(); i++) {
7082- cv::approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 3, true);
7083- }
7084-
7085- // Find largest contour
7086- std::vector<cv::Point> contour = Hand::findComplexContour(contours);
7087-
7088- // Find approximated convex hull
7089-
7090- std::vector<cv::Point> hull;
7091- std::vector<cv::Point> completeHull;
7092- std::vector<int> indexHull;
7093- if (contour.size() > 1) {
7094- cv::convexHull(contour, completeHull, 0, 1);
7095- cv::convexHull(contour, indexHull, 0, 0);
7096- hull = Hand::clusterConvexHull(completeHull, Hand::CLUSTER_THRESHOLD);
7097- }
7098-
7099- // Find convexityDefects
7100-
7101- std::vector<cv::Vec4i> defects;
7102- if (indexHull.size() > 3) {
7103- cv::convexityDefects(contour, indexHull, defects);
7104- }
7105-
7106- // Find max and min distances
7107- double minVal, maxVal;
7108- cv::Point minLoc, maxLoc;
7109- cv::minMaxLoc(channel[2], &minVal, &maxVal, &minLoc, &maxLoc);
7110-
7111- // Find center of contour
7112-
7113- cv::Point center = Hand::findCenter(contour);
7114- centroid_xyz = xyzMap.at<cv::Vec3f>(center.y / 4, center.x / 4);
7115- centroid_ij = cv::Point2i(center.x, center.y); // SCALING
7116-
7117- // Generate visual
7118- cv::Mat img = cv::Mat::zeros(input.rows, input.cols, CV_8UC3);
7119- cv::Scalar color = cv::Scalar(0, 255, 0);
7120-
7121- // Draw contours
7122- cv::circle(img, center, 5, cv::Scalar(255, 0, 0), 2);
7123-
7124- for (int i = 0; i < contours.size(); i++) {
7125- cv::drawContours(img, contours_poly, i, color, 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());
7126- }
7127-
7128- // Draw hull
7129-
7130- cv::Point index;
7131- cv::Point index_right;
7132- cv::Point index_left;
7133- double farthest = 0;
7134-
7135- if (hull.size() > 1) {
7136- for (int i = 0; i < hull.size(); i++) {
7137- cv::Point p1 = hull[i];
7138- cv::Point p2 = hull[(i + 1) % hull.size()];
7139- //cv::line(img, p1, p2, cv::Scalar(255, 0, 0), 1);
7140-
7141- if (p1.y < centroid_ij.y && Util::euclideanDistance2D(p1, centroid_ij) > farthest) {
7142- farthest = Util::euclideanDistance2D(p1, centroid_ij);
7143- index = p1;
7144- index_right = hull[(i + 1) % hull.size()];
7145- index_left = hull[(i - 1) % hull.size()];
7146- }
7147- }
7148- }
7149-
7150- // Draw defects (filter)
7151-
7152- std::vector<cv::Point> endpoints;
7153- std::vector<cv::Point> fingerDefects;
7154- cv::Point lastStart;
7155- int found = -1;
7156- for (int i = 0; i < defects.size(); i++) {
7157- cv::Vec4i defect = defects[i];
7158- cv::Point start = contour[defect[0]];
7159- cv::Point end = contour[defect[1]];
7160- cv::Point farPt = contour[defect[2]];
7161- // Depth from edge of contour
7162- // std::cout << "Depth: " << depth << "\tThreshold: " << cv::norm(maxLoc - center) << "\t";
7163- // Defect conditions: depth is sufficient, inside contour, y value is above center
7164- int depth = defect[3];
7165-
7166- // maxLoc largest depth
7167- // first condition replace with meters distance from the edge
7168- // second test if inside the hull (no change)
7169- // above the center (no change)
7170- if (cv::norm(maxLoc - center) * 15 < depth && cv::pointPolygonTest(hull, farPt, false) > 0 && farPt.y < center.y) {
7171- cv::Vec3f pt1 = xyzMap.at<cv::Vec3f>(farPt.y / 4, farPt.x / 4);
7172- if (Util::euclidianDistance3D(pt1, centroid_xyz) > 0.05) {
7173- endpoints.push_back(start);
7174- endpoints.push_back(end);
7175- fingerDefects.push_back(farPt);
7176- }
7177- }
7178- }
7179-
7180- // Cluster fingertip locations
7181-
7182- endpoints = Hand::clusterConvexHull(endpoints, Hand::CLUSTER_THRESHOLD);
7183- for (int i = 0; i < endpoints.size(); i++) {
7184- cv::Point endpoint = endpoints[i];
7185-
7186- cv::Point closestDefect;
7187- int minDefectDistance = 1 << 29;
7188- for (int i = 0; i < fingerDefects.size(); i++) {
7189- if (cv::norm(endpoint - fingerDefects[i]) < minDefectDistance) {
7190- minDefectDistance = cv::norm(endpoint - fingerDefects[i]);
7191- closestDefect = fingerDefects[i];
7192- }
7193- }
7194- cv::Vec3f endPoint_xyz = Util::averageAroundPoint(xyzMap, cv::Point2i(endpoint.x / 4, endpoint.y / 4), 10);
7195- cv::Vec3f closestDefect_xyz = Util::averageAroundPoint(xyzMap, cv::Point2i(closestDefect.x / 4, closestDefect.y / 4), 10);
7196- double finger_length = Util::euclidianDistance3D(endPoint_xyz, closestDefect_xyz);
7197- if (finger_length < 0.08 && finger_length > 0.025 && endpoint.y < closestDefect.y) {
7198- fingers_xyz.push_back(endPoint_xyz);
7199- fingers_ij.push_back(cv::Point2i(endpoint.x, endpoint.y)); // SCALING
7200-
7201- defects_xyz.push_back(Util::averageAroundPoint(xyzMap, cv::Point2i(closestDefect.x / 4, closestDefect.y / 4), 5));
7202- defects_ij.push_back(cv::Point2i(closestDefect.x, closestDefect.y)); // SCALING
7203- }
7204- }
7205- if ((float)cv::countNonZero(channel[2]) / (xyzMap.rows*xyzMap.cols) > 0.3) {
7206- return;
7207- }
7208-
7209- // If there is one or less visible fingers
7210- if (fingers_xyz.size() <= 1)
7211- {
7212- fingers_xyz.clear();
7213- fingers_ij.clear();
7214-
7215- cv::Vec3f indexFinger = Util::averageAroundPoint(xyzMap, cv::Point2i(index.x / 4, index.y / 4), 10);
7216- fingers_xyz.push_back(indexFinger);
7217- fingers_ij.push_back(cv::Point2i(index.x, index.y)); // SCALING
7218-
7219- double angle = Util::TriangleAngleCalculation(index_left.x, index_left.y, index.x, index.y, index_right.x, index_right.y);
7220- if (defects_ij.size() != 0) {
7221- for (int i = 0; i < fingers_xyz.size(); i++) {
7222- cv::circle(img, fingers_ij[i], 5, cv::Scalar(0, 0, 255), 3);
7223- cv::line(img, defects_ij[i], fingers_ij[i], cv::Scalar(255, 0, 255), 2);
7224- cv::circle(img, defects_ij[i], 5, cv::Scalar(0, 255, 255), 2);
7225- cv::line(img, defects_ij[i], centroid_ij, cv::Scalar(255, 0, 255), 2);
7226- }
7227- }
7228- else if (angle > ANGLE_THRESHHOLD) {
7229- cv::circle(img, fingers_ij[0], 5, cv::Scalar(0, 0, 255), 3);
7230- cv::line(img, fingers_ij[0], centroid_ij, cv::Scalar(255, 0, 255), 2);
7231- }
7232-
7233- }
7234- else {
7235- for (int i = 0; i < fingers_xyz.size(); i++) {
7236- cv::circle(img, fingers_ij[i], 5, cv::Scalar(0, 0, 255), 3);
7237- cv::line(img, defects_ij[i], fingers_ij[i], cv::Scalar(255, 0, 255), 2);
7238- cv::circle(img, defects_ij[i], 3, cv::Scalar(0, 255, 255), 2);
7239- cv::line(img, defects_ij[i], centroid_ij, cv::Scalar(255, 0, 255), 2);
7240- }
7241- }
7242-
7243- if (camera_name == "sr300") {
7244- cv::Mat img_dst;
7245- cv::resize(img, img_dst, cv::Size(640, 489), 0, 0, cv::INTER_AREA);
7246- cv::namedWindow("Contours", CV_WINDOW_AUTOSIZE);
7247- cv::imshow("Contours", img_dst);
7248- }
7249- else {
7250- cv::namedWindow("Contours", CV_WINDOW_AUTOSIZE);
7251- cv::imshow("Contours", img);
7252- }
7253-
7254-}
7255-
7256-std::vector<cv::Point> Hand::findComplexContour(std::vector< std::vector<cv::Point> > contours) {
7257- std::vector<cv::Point> contour;
7258- int maxPoints = 0;
7259- for (int i = 0; i < contours.size(); i++) {
7260- if (contours[i].size() > maxPoints) {
7261- maxPoints = contours[i].size();
7262- contour = contours[i];
7263- }
7264- }
7265- return contour;
7266-}
7267-
7268-std::vector<cv::Point> Hand::clusterConvexHull(std::vector<cv::Point> convexHull, int threshold) {
7269- std::vector<cv::Point> clusterHull;
7270- int i = 0;
7271- while (i < convexHull.size()) {
7272- // Select a point from cluster
7273- std::vector<cv::Point> cluster;
7274- cv::Point hullPoint = convexHull[i];
7275- cluster.push_back(hullPoint);
7276- i++;
7277- while (i < convexHull.size()) {
7278- cv::Point clusterPoint = convexHull[i];
7279- double distance = cv::norm(hullPoint - clusterPoint);
7280- if (distance < threshold) {
7281- cluster.push_back(clusterPoint);
7282- i++;
7283- }
7284- else {
7285- break;
7286- }
7287- }
7288- hullPoint = cluster[cluster.size() / 2];
7289- cv::Point center = findCenter(convexHull);
7290- int maxDist = cv::norm(hullPoint - center);
7291- for (int i = 0; i < cluster.size(); i++) {
7292- if (cv::norm(cluster[i] - center) > maxDist) {
7293- maxDist = cv::norm(cluster[i] - center);
7294- hullPoint = cluster[i];
7295- }
7296- }
7297- clusterHull.push_back(hullPoint);
7298- }
7299- return clusterHull;
7300-}
7301-
7302-cv::Point Hand::findCenter(std::vector<cv::Point> contour) {
7303- cv::Point center;
7304- cv::Moments M = cv::moments(contour, false);
7305- center = cv::Point((int)M.m10 / M.m00, (int)M.m01 / M.m00);
7306- return center;
7307-}
7308-
7309-bool Hand::touchObject(std::vector<double> &equation, const double threshold)
7310-{
7311- if (equation.size() == 0) {
7312- return false;
7313- }
7314-
7315- for (int i = 0; i < fingers_xyz.size(); i++) {
7316- double x = fingers_xyz[i][0];
7317- double y = fingers_xyz[i][1];
7318- double z = fingers_xyz[i][2];
7319- if (z == 0) {
7320- return false;
7321- }
7322-
7323- double z_hat = equation[0] * x + equation[1] * y + equation[2];
7324- double r_squared = (z - z_hat) * (z - z_hat);
7325-
7326- if (r_squared < threshold) {
7327- return true;
7328- }
7329- }
7330-
7331- return false;
7332+#include "Hand.h"
7333+#include "Util.h"
7334+#include "Visualizer.h"
7335+
7336+Hand::Hand()
7337+{
7338+
7339+}
7340+
7341+Hand::Hand(cv::Mat xyzMap, float angle_threshhold, int cluster_thresh)
7342+{
7343+ CLUSTER_THRESHOLD = cluster_thresh;
7344+ ANGLE_THRESHHOLD = angle_threshhold;
7345+ analyzeHand(xyzMap);
7346+}
7347+
7348+Hand::~Hand()
7349+{
7350+
7351+}
7352+
7353+void Hand::analyzeHand(cv::Mat xyzMap)
7354+{
7355+
7356+ cv::Mat normalizedDepthMap;
7357+ cv::Mat channel[3];
7358+ cv::split(xyzMap, channel);
7359+ cv::normalize(channel[2], normalizedDepthMap, 0, 255, cv::NORM_MINMAX, CV_8UC1);
7360+
7361+ // Resize input
7362+ cv::Mat input;
7363+ cv::pyrUp(normalizedDepthMap, input, cv::Size(normalizedDepthMap.cols * 2, normalizedDepthMap.rows * 2));
7364+ cv::pyrUp(input, input, cv::Size(input.cols * 2, input.rows * 2));
7365+
7366+ cv::Mat threshold_output;
7367+ std::vector< std::vector<cv::Point> > contours;
7368+ std::vector<cv::Vec4i> hierarchy;
7369+
7370+ // Find contours
7371+
7372+ cv::threshold(input, threshold_output, 100, 255, cv::THRESH_BINARY);
7373+ cv::findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
7374+
7375+ // Find contour polygon
7376+
7377+ std::vector< std::vector< cv::Point> > contours_poly(contours.size());
7378+ for (int i = 0; i < contours.size(); i++) {
7379+ cv::approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 3, true);
7380+ }
7381+
7382+ // Find largest contour
7383+ std::vector<cv::Point> contour = Hand::findComplexContour(contours);
7384+
7385+ // Find approximated convex hull
7386+
7387+ std::vector<cv::Point> hull;
7388+ std::vector<cv::Point> completeHull;
7389+ std::vector<int> indexHull;
7390+ if (contour.size() > 1) {
7391+ cv::convexHull(contour, completeHull, 0, 1);
7392+ cv::convexHull(contour, indexHull, 0, 0);
7393+ hull = Hand::clusterConvexHull(completeHull, Hand::CLUSTER_THRESHOLD);
7394+ }
7395+
7396+ // Find convexityDefects
7397+
7398+ std::vector<cv::Vec4i> defects;
7399+ if (indexHull.size() > 3) {
7400+ cv::convexityDefects(contour, indexHull, defects);
7401+ }
7402+
7403+ // Find max and min distances
7404+ double minVal, maxVal;
7405+ cv::Point minLoc, maxLoc;
7406+ cv::minMaxLoc(channel[2], &minVal, &maxVal, &minLoc, &maxLoc);
7407+
7408+ // Find center of contour
7409+
7410+ cv::Point center = Hand::findCenter(contour);
7411+ centroid_xyz = xyzMap.at<cv::Vec3f>(center.y / 4, center.x / 4);
7412+ centroid_ij = cv::Point2i(center.x, center.y); // SCALING
7413+
7414+ // Generate visual
7415+ cv::Mat img = cv::Mat::zeros(input.rows, input.cols, CV_8UC3);
7416+ cv::Scalar color = cv::Scalar(0, 255, 0);
7417+
7418+ // Draw contours
7419+ cv::circle(img, center, 5, cv::Scalar(255, 0, 0), 2);
7420+
7421+ for (int i = 0; i < contours.size(); i++) {
7422+ cv::drawContours(img, contours_poly, i, color, 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());
7423+ }
7424+
7425+ // Draw hull
7426+
7427+ cv::Point index;
7428+ cv::Point index_right;
7429+ cv::Point index_left;
7430+ double farthest = 0;
7431+
7432+ if (hull.size() > 1) {
7433+ for (int i = 0; i < hull.size(); i++) {
7434+ cv::Point p1 = hull[i];
7435+ cv::Point p2 = hull[(i + 1) % hull.size()];
7436+ //cv::line(img, p1, p2, cv::Scalar(255, 0, 0), 1);
7437+
7438+ if (p1.y < centroid_ij.y && Util::euclideanDistance2D(p1, centroid_ij) > farthest) {
7439+ farthest = Util::euclideanDistance2D(p1, centroid_ij);
7440+ index = p1;
7441+ index_right = hull[(i + 1) % hull.size()];
7442+ index_left = hull[(i - 1) % hull.size()];
7443+ }
7444+ }
7445+ }
7446+
7447+ // Draw defects (filter)
7448+
7449+ std::vector<cv::Point> endpoints;
7450+ std::vector<cv::Point> fingerDefects;
7451+ cv::Point lastStart;
7452+ int found = -1;
7453+ for (int i = 0; i < defects.size(); i++) {
7454+ cv::Vec4i defect = defects[i];
7455+ cv::Point start = contour[defect[0]];
7456+ cv::Point end = contour[defect[1]];
7457+ cv::Point farPt = contour[defect[2]];
7458+ // Depth from edge of contour
7459+ // std::cout << "Depth: " << depth << "\tThreshold: " << cv::norm(maxLoc - center) << "\t";
7460+ // Defect conditions: depth is sufficient, inside contour, y value is above center
7461+ int depth = defect[3];
7462+
7463+ // maxLoc largest depth
7464+ // first condition replace with meters distance from the edge
7465+ // second test if inside the hull (no change)
7466+ // above the center (no change)
7467+ if (cv::norm(maxLoc - center) * 15 < depth && cv::pointPolygonTest(hull, farPt, false) > 0 && farPt.y < center.y) {
7468+ cv::Vec3f pt1 = xyzMap.at<cv::Vec3f>(farPt.y / 4, farPt.x / 4);
7469+ if (Util::euclidianDistance3D(pt1, centroid_xyz) > 0.05) {
7470+ endpoints.push_back(start);
7471+ endpoints.push_back(end);
7472+ fingerDefects.push_back(farPt);
7473+ }
7474+ }
7475+ }
7476+
7477+ // Cluster fingertip locations
7478+
7479+ endpoints = Hand::clusterConvexHull(endpoints, Hand::CLUSTER_THRESHOLD);
7480+ for (int i = 0; i < endpoints.size(); i++) {
7481+ cv::Point endpoint = endpoints[i];
7482+
7483+ cv::Point closestDefect;
7484+ int minDefectDistance = 1 << 29;
7485+ for (int i = 0; i < fingerDefects.size(); i++) {
7486+ if (cv::norm(endpoint - fingerDefects[i]) < minDefectDistance) {
7487+ minDefectDistance = cv::norm(endpoint - fingerDefects[i]);
7488+ closestDefect = fingerDefects[i];
7489+ }
7490+ }
7491+ cv::Vec3f endPoint_xyz = Util::averageAroundPoint(xyzMap, cv::Point2i(endpoint.x / 4, endpoint.y / 4), 10);
7492+ cv::Vec3f closestDefect_xyz = Util::averageAroundPoint(xyzMap, cv::Point2i(closestDefect.x / 4, closestDefect.y / 4), 10);
7493+ double finger_length = Util::euclidianDistance3D(endPoint_xyz, closestDefect_xyz);
7494+ if (finger_length < 0.08 && finger_length > 0.025 && endpoint.y < closestDefect.y) {
7495+ fingers_xyz.push_back(endPoint_xyz);
7496+ fingers_ij.push_back(cv::Point2i(endpoint.x, endpoint.y)); // SCALING
7497+
7498+ defects_xyz.push_back(Util::averageAroundPoint(xyzMap, cv::Point2i(closestDefect.x / 4, closestDefect.y / 4), 5));
7499+ defects_ij.push_back(cv::Point2i(closestDefect.x, closestDefect.y)); // SCALING
7500+ }
7501+ }
7502+ if ((float)cv::countNonZero(channel[2]) / (xyzMap.rows*xyzMap.cols) > 0.3) {
7503+ return;
7504+ }
7505+
7506+ // If there is one or less visible fingers
7507+ if (fingers_xyz.size() <= 1)
7508+ {
7509+ fingers_xyz.clear();
7510+ fingers_ij.clear();
7511+
7512+ cv::Vec3f indexFinger = Util::averageAroundPoint(xyzMap, cv::Point2i(index.x / 4, index.y / 4), 10);
7513+ fingers_xyz.push_back(indexFinger);
7514+ fingers_ij.push_back(cv::Point2i(index.x, index.y)); // SCALING
7515+
7516+ double angle = Util::TriangleAngleCalculation(index_left.x, index_left.y, index.x, index.y, index_right.x, index_right.y);
7517+ if (defects_ij.size() != 0) {
7518+ for (int i = 0; i < fingers_xyz.size(); i++) {
7519+ cv::circle(img, fingers_ij[i], 5, cv::Scalar(0, 0, 255), 3);
7520+ cv::line(img, defects_ij[i], fingers_ij[i], cv::Scalar(255, 0, 255), 2);
7521+ cv::circle(img, defects_ij[i], 5, cv::Scalar(0, 255, 255), 2);
7522+ cv::line(img, defects_ij[i], centroid_ij, cv::Scalar(255, 0, 255), 2);
7523+ }
7524+ }
7525+ else if (angle > ANGLE_THRESHHOLD) {
7526+ cv::circle(img, fingers_ij[0], 5, cv::Scalar(0, 0, 255), 3);
7527+ cv::line(img, fingers_ij[0], centroid_ij, cv::Scalar(255, 0, 255), 2);
7528+ }
7529+
7530+ }
7531+ else {
7532+ for (int i = 0; i < fingers_xyz.size(); i++) {
7533+ cv::circle(img, fingers_ij[i], 5, cv::Scalar(0, 0, 255), 3);
7534+ cv::line(img, defects_ij[i], fingers_ij[i], cv::Scalar(255, 0, 255), 2);
7535+ cv::circle(img, defects_ij[i], 3, cv::Scalar(0, 255, 255), 2);
7536+ cv::line(img, defects_ij[i], centroid_ij, cv::Scalar(255, 0, 255), 2);
7537+ }
7538+ }
7539+ cv::imshow("Contours", img);
7540+
7541+
7542+}
7543+
7544+std::vector<cv::Point> Hand::findComplexContour(std::vector< std::vector<cv::Point> > contours) {
7545+ std::vector<cv::Point> contour;
7546+ int maxPoints = 0;
7547+ for (int i = 0; i < contours.size(); i++) {
7548+ if (contours[i].size() > maxPoints) {
7549+ maxPoints = contours[i].size();
7550+ contour = contours[i];
7551+ }
7552+ }
7553+ return contour;
7554+}
7555+
7556+std::vector<cv::Point> Hand::clusterConvexHull(std::vector<cv::Point> convexHull, int threshold) {
7557+ std::vector<cv::Point> clusterHull;
7558+ int i = 0;
7559+ while (i < convexHull.size()) {
7560+ // Select a point from cluster
7561+ std::vector<cv::Point> cluster;
7562+ cv::Point hullPoint = convexHull[i];
7563+ cluster.push_back(hullPoint);
7564+ i++;
7565+ while (i < convexHull.size()) {
7566+ cv::Point clusterPoint = convexHull[i];
7567+ double distance = cv::norm(hullPoint - clusterPoint);
7568+ if (distance < threshold) {
7569+ cluster.push_back(clusterPoint);
7570+ i++;
7571+ }
7572+ else {
7573+ break;
7574+ }
7575+ }
7576+ hullPoint = cluster[cluster.size() / 2];
7577+ cv::Point center = findCenter(convexHull);
7578+ int maxDist = cv::norm(hullPoint - center);
7579+ for (int i = 0; i < cluster.size(); i++) {
7580+ if (cv::norm(cluster[i] - center) > maxDist) {
7581+ maxDist = cv::norm(cluster[i] - center);
7582+ hullPoint = cluster[i];
7583+ }
7584+ }
7585+ clusterHull.push_back(hullPoint);
7586+ }
7587+ return clusterHull;
7588+}
7589+
7590+cv::Point Hand::findCenter(std::vector<cv::Point> contour) {
7591+ cv::Point center;
7592+ cv::Moments M = cv::moments(contour, false);
7593+ center = cv::Point((int)M.m10 / M.m00, (int)M.m01 / M.m00);
7594+ return center;
7595+}
7596+
7597+bool Hand::touchObject(std::vector<double> &equation, const double threshold)
7598+{
7599+ if (equation.size() == 0) {
7600+ return false;
7601+ }
7602+
7603+ for (int i = 0; i < fingers_xyz.size(); i++) {
7604+ double x = fingers_xyz[i][0];
7605+ double y = fingers_xyz[i][1];
7606+ double z = fingers_xyz[i][2];
7607+ if (z == 0) {
7608+ return false;
7609+ }
7610+
7611+ double z_hat = equation[0] * x + equation[1] * y + equation[2];
7612+ double r_squared = (z - z_hat) * (z - z_hat);
7613+
7614+ if (r_squared < threshold) {
7615+ return true;
7616+ }
7617+ }
7618+
7619+ return false;
7620 }
7621\ No newline at end of file
7622diff --git a/Hand.h b/Hand.h
7623index 345bf47..62e57d7 100644
7624--- a/Hand.h
7625+++ b/Hand.h
7626@@ -1,107 +1,105 @@
7627-#pragma once
7628-// C++ Libraries
7629-#include <iostream>
7630-#include <vector>
7631-#include <cmath>
7632-
7633-// OpenCV Libraries
7634-#include <opencv2/core/core.hpp>
7635-#include <opencv2/core.hpp>
7636-#include <opencv2/highgui/highgui.hpp>
7637-#include <opencv2/highgui.hpp>
7638-#include <opencv2/imgproc.hpp>
7639-#include <opencv2/imgcodecs.hpp>
7640-
7641-class Hand {
7642-public:
7643-
7644-
7645- // Public constructors
7646- /**
7647- * Default constructor for a hand object
7648- */
7649- Hand();
7650-
7651- /**
7652- * Constructs a hand object based on point cloud and constraints.
7653- * @param xyzMap Input point cloud containing only the hand (nothing else can be in this point cluod)
7654- * @param angle_treshhold Sharpest allowable angle formed by finger tip and neighboring defects
7655- * @param cluster_thresh Maximum allowable distance between two finger tips
7656- */
7657- Hand(cv::Mat xyzMap, float angle_treshhold, int cluster_thresh = 30);
7658-
7659- /**
7660- * Deconstructor for the hand object
7661- */
7662- ~Hand();
7663-
7664- // Public variables
7665-
7666- /**
7667- * Maximum allowable distance between adjacent finger tips
7668- */
7669- int CLUSTER_THRESHOLD;
7670-
7671- /**
7672- * (x,y,z) position of all detected finger tips
7673- */
7674- std::vector<cv::Vec3f> fingers_xyz;
7675-
7676- /**
7677- * (i,j) coordinates of all detected finger tips
7678- */
7679- std::vector<cv::Point2i> fingers_ij;
7680-
7681- /**
7682- * (x,y,z) position of hand centroid
7683- */
7684- cv::Vec3f centroid_xyz;
7685-
7686- /**
7687- * (i,j) coordinates of hand centroid
7688- */
7689- cv::Point2i centroid_ij;
7690-
7691- /**
7692- * (x,y,z) position of detected defects
7693- */
7694- std::vector<cv::Vec3f> defects_xyz;
7695-
7696- /**
7697- * (i,j) position of detected defects
7698- */
7699- std::vector<cv::Point2i> defects_ij;
7700-
7701- // Public functions
7702-
7703- /**
7704- * Determine whether one of the fingers is in contact with a tracked object.
7705- * @param equation Regression equation of the object
7706- * @param threshold Thickness of the plane modeled by the regression equation
7707- * @return TRUE if hand is contacting a tracked object. FALSE otherwise
7708- */
7709- bool touchObject(std::vector<double> &equation, const double threshold);
7710-
7711-private:
7712- // Private constructors
7713- /**
7714- * Find the contour with max number of vertices.
7715- **/
7716- std::vector<cv::Point> findComplexContour(std::vector< std::vector<cv::Point> > contours);
7717-
7718- /**
7719- * Groups vertices within a threshold and selects the median of each group.
7720- **/
7721- std::vector<cv::Point> clusterConvexHull(std::vector<cv::Point> convexHull, int threshold);
7722-
7723- /**
7724- * Find the centroid of contour using 0th and 1st degree moments
7725- **/
7726- cv::Point findCenter(std::vector<cv::Point> contour);
7727-
7728- // Private variables
7729- float ANGLE_THRESHHOLD;
7730-
7731- // Private functions
7732- void analyzeHand(cv::Mat xyzMap);
7733-};
7734+#pragma once
7735+// C++ Libraries
7736+#include <iostream>
7737+#include <vector>
7738+#include <cmath>
7739+
7740+// OpenCV Libraries
7741+#include <opencv2/core/core.hpp>
7742+#include <opencv2/core.hpp>
7743+#include <opencv2/highgui/highgui.hpp>
7744+#include <opencv2/highgui.hpp>
7745+#include <opencv2/imgproc.hpp>
7746+#include <opencv2/imgcodecs.hpp>
7747+
7748+class Hand {
7749+public:
7750+ // Public constructors
7751+ /**
7752+ * Default constructor for a hand object
7753+ */
7754+ Hand();
7755+
7756+ /**
7757+ * Constructs a hand object based on point cloud and constraints.
7758+ * @param xyzMap Input point cloud containing only the hand (nothing else can be in this point cluod)
7759+ * @param angle_treshhold Sharpest allowable angle formed by finger tip and neighboring defects
7760+ * @param cluster_thresh Maximum allowable distance between two finger tips
7761+ */
7762+ Hand(cv::Mat xyzMap, float angle_treshhold, int cluster_thresh = 30);
7763+
7764+ /**
7765+ * Deconstructor for the hand object
7766+ */
7767+ ~Hand();
7768+
7769+ // Public variables
7770+
7771+ /**
7772+ * Maximum allowable distance between adjacent finger tips
7773+ */
7774+ int CLUSTER_THRESHOLD;
7775+
7776+ /**
7777+ * (x,y,z) position of all detected finger tips
7778+ */
7779+ std::vector<cv::Vec3f> fingers_xyz;
7780+
7781+ /**
7782+ * (i,j) coordinates of all detected finger tips
7783+ */
7784+ std::vector<cv::Point2i> fingers_ij;
7785+
7786+ /**
7787+ * (x,y,z) position of hand centroid
7788+ */
7789+ cv::Vec3f centroid_xyz;
7790+
7791+ /**
7792+ * (i,j) coordinates of hand centroid
7793+ */
7794+ cv::Point2i centroid_ij;
7795+
7796+ /**
7797+ * (x,y,z) position of detected defects
7798+ */
7799+ std::vector<cv::Vec3f> defects_xyz;
7800+
7801+ /**
7802+ * (i,j) position of detected defects
7803+ */
7804+ std::vector<cv::Point2i> defects_ij;
7805+
7806+ // Public functions
7807+
7808+ /**
7809+ * Determine whether one of the fingers is in contact with a tracked object.
7810+ * @param equation Regression equation of the object
7811+ * @param threshold Thickness of the plane modeled by the regression equation
7812+ * @return TRUE if hand is contacting a tracked object. FALSE otherwise
7813+ */
7814+ bool touchObject(std::vector<double> &equation, const double threshold);
7815+
7816+private:
7817+ // Private constructors
7818+ /**
7819+ * Find the contour with max number of vertices.
7820+ **/
7821+ std::vector<cv::Point> findComplexContour(std::vector< std::vector<cv::Point> > contours);
7822+
7823+ /**
7824+ * Groups vertices within a threshold and selects the median of each group.
7825+ **/
7826+ std::vector<cv::Point> clusterConvexHull(std::vector<cv::Point> convexHull, int threshold);
7827+
7828+ /**
7829+ * Find the centroid of contour using 0th and 1st degree moments
7830+ **/
7831+ cv::Point findCenter(std::vector<cv::Point> contour);
7832+
7833+ // Private variables
7834+ float ANGLE_THRESHHOLD;
7835+
7836+ // Private functions
7837+ void analyzeHand(cv::Mat xyzMap);
7838+};
7839diff --git a/LICENSE.md b/LICENSE.md
7840index e787980..4053413 100644
7841--- a/LICENSE.md
7842+++ b/LICENSE.md
7843@@ -1,201 +1,201 @@
7844- Apache License
7845- Version 2.0, January 2004
7846- http://www.apache.org/licenses/
7847-
7848- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7849-
7850- 1. Definitions.
7851-
7852- "License" shall mean the terms and conditions for use, reproduction,
7853- and distribution as defined by Sections 1 through 9 of this document.
7854-
7855- "Licensor" shall mean the copyright owner or entity authorized by
7856- the copyright owner that is granting the License.
7857-
7858- "Legal Entity" shall mean the union of the acting entity and all
7859- other entities that control, are controlled by, or are under common
7860- control with that entity. For the purposes of this definition,
7861- "control" means (i) the power, direct or indirect, to cause the
7862- direction or management of such entity, whether by contract or
7863- otherwise, or (ii) ownership of fifty percent (50%) or more of the
7864- outstanding shares, or (iii) beneficial ownership of such entity.
7865-
7866- "You" (or "Your") shall mean an individual or Legal Entity
7867- exercising permissions granted by this License.
7868-
7869- "Source" form shall mean the preferred form for making modifications,
7870- including but not limited to software source code, documentation
7871- source, and configuration files.
7872-
7873- "Object" form shall mean any form resulting from mechanical
7874- transformation or translation of a Source form, including but
7875- not limited to compiled object code, generated documentation,
7876- and conversions to other media types.
7877-
7878- "Work" shall mean the work of authorship, whether in Source or
7879- Object form, made available under the License, as indicated by a
7880- copyright notice that is included in or attached to the work
7881- (an example is provided in the Appendix below).
7882-
7883- "Derivative Works" shall mean any work, whether in Source or Object
7884- form, that is based on (or derived from) the Work and for which the
7885- editorial revisions, annotations, elaborations, or other modifications
7886- represent, as a whole, an original work of authorship. For the purposes
7887- of this License, Derivative Works shall not include works that remain
7888- separable from, or merely link (or bind by name) to the interfaces of,
7889- the Work and Derivative Works thereof.
7890-
7891- "Contribution" shall mean any work of authorship, including
7892- the original version of the Work and any modifications or additions
7893- to that Work or Derivative Works thereof, that is intentionally
7894- submitted to Licensor for inclusion in the Work by the copyright owner
7895- or by an individual or Legal Entity authorized to submit on behalf of
7896- the copyright owner. For the purposes of this definition, "submitted"
7897- means any form of electronic, verbal, or written communication sent
7898- to the Licensor or its representatives, including but not limited to
7899- communication on electronic mailing lists, source code control systems,
7900- and issue tracking systems that are managed by, or on behalf of, the
7901- Licensor for the purpose of discussing and improving the Work, but
7902- excluding communication that is conspicuously marked or otherwise
7903- designated in writing by the copyright owner as "Not a Contribution."
7904-
7905- "Contributor" shall mean Licensor and any individual or Legal Entity
7906- on behalf of whom a Contribution has been received by Licensor and
7907- subsequently incorporated within the Work.
7908-
7909- 2. Grant of Copyright License. Subject to the terms and conditions of
7910- this License, each Contributor hereby grants to You a perpetual,
7911- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
7912- copyright license to reproduce, prepare Derivative Works of,
7913- publicly display, publicly perform, sublicense, and distribute the
7914- Work and such Derivative Works in Source or Object form.
7915-
7916- 3. Grant of Patent License. Subject to the terms and conditions of
7917- this License, each Contributor hereby grants to You a perpetual,
7918- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
7919- (except as stated in this section) patent license to make, have made,
7920- use, offer to sell, sell, import, and otherwise transfer the Work,
7921- where such license applies only to those patent claims licensable
7922- by such Contributor that are necessarily infringed by their
7923- Contribution(s) alone or by combination of their Contribution(s)
7924- with the Work to which such Contribution(s) was submitted. If You
7925- institute patent litigation against any entity (including a
7926- cross-claim or counterclaim in a lawsuit) alleging that the Work
7927- or a Contribution incorporated within the Work constitutes direct
7928- or contributory patent infringement, then any patent licenses
7929- granted to You under this License for that Work shall terminate
7930- as of the date such litigation is filed.
7931-
7932- 4. Redistribution. You may reproduce and distribute copies of the
7933- Work or Derivative Works thereof in any medium, with or without
7934- modifications, and in Source or Object form, provided that You
7935- meet the following conditions:
7936-
7937- (a) You must give any other recipients of the Work or
7938- Derivative Works a copy of this License; and
7939-
7940- (b) You must cause any modified files to carry prominent notices
7941- stating that You changed the files; and
7942-
7943- (c) You must retain, in the Source form of any Derivative Works
7944- that You distribute, all copyright, patent, trademark, and
7945- attribution notices from the Source form of the Work,
7946- excluding those notices that do not pertain to any part of
7947- the Derivative Works; and
7948-
7949- (d) If the Work includes a "NOTICE" text file as part of its
7950- distribution, then any Derivative Works that You distribute must
7951- include a readable copy of the attribution notices contained
7952- within such NOTICE file, excluding those notices that do not
7953- pertain to any part of the Derivative Works, in at least one
7954- of the following places: within a NOTICE text file distributed
7955- as part of the Derivative Works; within the Source form or
7956- documentation, if provided along with the Derivative Works; or,
7957- within a display generated by the Derivative Works, if and
7958- wherever such third-party notices normally appear. The contents
7959- of the NOTICE file are for informational purposes only and
7960- do not modify the License. You may add Your own attribution
7961- notices within Derivative Works that You distribute, alongside
7962- or as an addendum to the NOTICE text from the Work, provided
7963- that such additional attribution notices cannot be construed
7964- as modifying the License.
7965-
7966- You may add Your own copyright statement to Your modifications and
7967- may provide additional or different license terms and conditions
7968- for use, reproduction, or distribution of Your modifications, or
7969- for any such Derivative Works as a whole, provided Your use,
7970- reproduction, and distribution of the Work otherwise complies with
7971- the conditions stated in this License.
7972-
7973- 5. Submission of Contributions. Unless You explicitly state otherwise,
7974- any Contribution intentionally submitted for inclusion in the Work
7975- by You to the Licensor shall be under the terms and conditions of
7976- this License, without any additional terms or conditions.
7977- Notwithstanding the above, nothing herein shall supersede or modify
7978- the terms of any separate license agreement you may have executed
7979- with Licensor regarding such Contributions.
7980-
7981- 6. Trademarks. This License does not grant permission to use the trade
7982- names, trademarks, service marks, or product names of the Licensor,
7983- except as required for reasonable and customary use in describing the
7984- origin of the Work and reproducing the content of the NOTICE file.
7985-
7986- 7. Disclaimer of Warranty. Unless required by applicable law or
7987- agreed to in writing, Licensor provides the Work (and each
7988- Contributor provides its Contributions) on an "AS IS" BASIS,
7989- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
7990- implied, including, without limitation, any warranties or conditions
7991- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
7992- PARTICULAR PURPOSE. You are solely responsible for determining the
7993- appropriateness of using or redistributing the Work and assume any
7994- risks associated with Your exercise of permissions under this License.
7995-
7996- 8. Limitation of Liability. In no event and under no legal theory,
7997- whether in tort (including negligence), contract, or otherwise,
7998- unless required by applicable law (such as deliberate and grossly
7999- negligent acts) or agreed to in writing, shall any Contributor be
8000- liable to You for damages, including any direct, indirect, special,
8001- incidental, or consequential damages of any character arising as a
8002- result of this License or out of the use or inability to use the
8003- Work (including but not limited to damages for loss of goodwill,
8004- work stoppage, computer failure or malfunction, or any and all
8005- other commercial damages or losses), even if such Contributor
8006- has been advised of the possibility of such damages.
8007-
8008- 9. Accepting Warranty or Additional Liability. While redistributing
8009- the Work or Derivative Works thereof, You may choose to offer,
8010- and charge a fee for, acceptance of support, warranty, indemnity,
8011- or other liability obligations and/or rights consistent with this
8012- License. However, in accepting such obligations, You may act only
8013- on Your own behalf and on Your sole responsibility, not on behalf
8014- of any other Contributor, and only if You agree to indemnify,
8015- defend, and hold each Contributor harmless for any liability
8016- incurred by, or claims asserted against, such Contributor by reason
8017- of your accepting any such warranty or additional liability.
8018-
8019- END OF TERMS AND CONDITIONS
8020-
8021- APPENDIX: How to apply the Apache License to your work.
8022-
8023- To apply the Apache License to your work, attach the following
8024- boilerplate notice, with the fields enclosed by brackets "{}"
8025- replaced with your own identifying information. (Don't include
8026- the brackets!) The text should be enclosed in the appropriate
8027- comment syntax for the file format. We also recommend that a
8028- file or class name and description of purpose be included on the
8029- same "printed page" as the copyright notice for easier
8030- identification within third-party archives.
8031-
8032- Copyright {2017} {UC Berkeley}
8033-
8034- Licensed under the Apache License, Version 2.0 (the "License");
8035- you may not use this file except in compliance with the License.
8036- You may obtain a copy of the License at
8037-
8038- http://www.apache.org/licenses/LICENSE-2.0
8039-
8040- Unless required by applicable law or agreed to in writing, software
8041- distributed under the License is distributed on an "AS IS" BASIS,
8042- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8043- See the License for the specific language governing permissions and
8044- limitations under the License.
8045+ Apache License
8046+ Version 2.0, January 2004
8047+ http://www.apache.org/licenses/
8048+
8049+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8050+
8051+ 1. Definitions.
8052+
8053+ "License" shall mean the terms and conditions for use, reproduction,
8054+ and distribution as defined by Sections 1 through 9 of this document.
8055+
8056+ "Licensor" shall mean the copyright owner or entity authorized by
8057+ the copyright owner that is granting the License.
8058+
8059+ "Legal Entity" shall mean the union of the acting entity and all
8060+ other entities that control, are controlled by, or are under common
8061+ control with that entity. For the purposes of this definition,
8062+ "control" means (i) the power, direct or indirect, to cause the
8063+ direction or management of such entity, whether by contract or
8064+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
8065+ outstanding shares, or (iii) beneficial ownership of such entity.
8066+
8067+ "You" (or "Your") shall mean an individual or Legal Entity
8068+ exercising permissions granted by this License.
8069+
8070+ "Source" form shall mean the preferred form for making modifications,
8071+ including but not limited to software source code, documentation
8072+ source, and configuration files.
8073+
8074+ "Object" form shall mean any form resulting from mechanical
8075+ transformation or translation of a Source form, including but
8076+ not limited to compiled object code, generated documentation,
8077+ and conversions to other media types.
8078+
8079+ "Work" shall mean the work of authorship, whether in Source or
8080+ Object form, made available under the License, as indicated by a
8081+ copyright notice that is included in or attached to the work
8082+ (an example is provided in the Appendix below).
8083+
8084+ "Derivative Works" shall mean any work, whether in Source or Object
8085+ form, that is based on (or derived from) the Work and for which the
8086+ editorial revisions, annotations, elaborations, or other modifications
8087+ represent, as a whole, an original work of authorship. For the purposes
8088+ of this License, Derivative Works shall not include works that remain
8089+ separable from, or merely link (or bind by name) to the interfaces of,
8090+ the Work and Derivative Works thereof.
8091+
8092+ "Contribution" shall mean any work of authorship, including
8093+ the original version of the Work and any modifications or additions
8094+ to that Work or Derivative Works thereof, that is intentionally
8095+ submitted to Licensor for inclusion in the Work by the copyright owner
8096+ or by an individual or Legal Entity authorized to submit on behalf of
8097+ the copyright owner. For the purposes of this definition, "submitted"
8098+ means any form of electronic, verbal, or written communication sent
8099+ to the Licensor or its representatives, including but not limited to
8100+ communication on electronic mailing lists, source code control systems,
8101+ and issue tracking systems that are managed by, or on behalf of, the
8102+ Licensor for the purpose of discussing and improving the Work, but
8103+ excluding communication that is conspicuously marked or otherwise
8104+ designated in writing by the copyright owner as "Not a Contribution."
8105+
8106+ "Contributor" shall mean Licensor and any individual or Legal Entity
8107+ on behalf of whom a Contribution has been received by Licensor and
8108+ subsequently incorporated within the Work.
8109+
8110+ 2. Grant of Copyright License. Subject to the terms and conditions of
8111+ this License, each Contributor hereby grants to You a perpetual,
8112+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
8113+ copyright license to reproduce, prepare Derivative Works of,
8114+ publicly display, publicly perform, sublicense, and distribute the
8115+ Work and such Derivative Works in Source or Object form.
8116+
8117+ 3. Grant of Patent License. Subject to the terms and conditions of
8118+ this License, each Contributor hereby grants to You a perpetual,
8119+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
8120+ (except as stated in this section) patent license to make, have made,
8121+ use, offer to sell, sell, import, and otherwise transfer the Work,
8122+ where such license applies only to those patent claims licensable
8123+ by such Contributor that are necessarily infringed by their
8124+ Contribution(s) alone or by combination of their Contribution(s)
8125+ with the Work to which such Contribution(s) was submitted. If You
8126+ institute patent litigation against any entity (including a
8127+ cross-claim or counterclaim in a lawsuit) alleging that the Work
8128+ or a Contribution incorporated within the Work constitutes direct
8129+ or contributory patent infringement, then any patent licenses
8130+ granted to You under this License for that Work shall terminate
8131+ as of the date such litigation is filed.
8132+
8133+ 4. Redistribution. You may reproduce and distribute copies of the
8134+ Work or Derivative Works thereof in any medium, with or without
8135+ modifications, and in Source or Object form, provided that You
8136+ meet the following conditions:
8137+
8138+ (a) You must give any other recipients of the Work or
8139+ Derivative Works a copy of this License; and
8140+
8141+ (b) You must cause any modified files to carry prominent notices
8142+ stating that You changed the files; and
8143+
8144+ (c) You must retain, in the Source form of any Derivative Works
8145+ that You distribute, all copyright, patent, trademark, and
8146+ attribution notices from the Source form of the Work,
8147+ excluding those notices that do not pertain to any part of
8148+ the Derivative Works; and
8149+
8150+ (d) If the Work includes a "NOTICE" text file as part of its
8151+ distribution, then any Derivative Works that You distribute must
8152+ include a readable copy of the attribution notices contained
8153+ within such NOTICE file, excluding those notices that do not
8154+ pertain to any part of the Derivative Works, in at least one
8155+ of the following places: within a NOTICE text file distributed
8156+ as part of the Derivative Works; within the Source form or
8157+ documentation, if provided along with the Derivative Works; or,
8158+ within a display generated by the Derivative Works, if and
8159+ wherever such third-party notices normally appear. The contents
8160+ of the NOTICE file are for informational purposes only and
8161+ do not modify the License. You may add Your own attribution
8162+ notices within Derivative Works that You distribute, alongside
8163+ or as an addendum to the NOTICE text from the Work, provided
8164+ that such additional attribution notices cannot be construed
8165+ as modifying the License.
8166+
8167+ You may add Your own copyright statement to Your modifications and
8168+ may provide additional or different license terms and conditions
8169+ for use, reproduction, or distribution of Your modifications, or
8170+ for any such Derivative Works as a whole, provided Your use,
8171+ reproduction, and distribution of the Work otherwise complies with
8172+ the conditions stated in this License.
8173+
8174+ 5. Submission of Contributions. Unless You explicitly state otherwise,
8175+ any Contribution intentionally submitted for inclusion in the Work
8176+ by You to the Licensor shall be under the terms and conditions of
8177+ this License, without any additional terms or conditions.
8178+ Notwithstanding the above, nothing herein shall supersede or modify
8179+ the terms of any separate license agreement you may have executed
8180+ with Licensor regarding such Contributions.
8181+
8182+ 6. Trademarks. This License does not grant permission to use the trade
8183+ names, trademarks, service marks, or product names of the Licensor,
8184+ except as required for reasonable and customary use in describing the
8185+ origin of the Work and reproducing the content of the NOTICE file.
8186+
8187+ 7. Disclaimer of Warranty. Unless required by applicable law or
8188+ agreed to in writing, Licensor provides the Work (and each
8189+ Contributor provides its Contributions) on an "AS IS" BASIS,
8190+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
8191+ implied, including, without limitation, any warranties or conditions
8192+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
8193+ PARTICULAR PURPOSE. You are solely responsible for determining the
8194+ appropriateness of using or redistributing the Work and assume any
8195+ risks associated with Your exercise of permissions under this License.
8196+
8197+ 8. Limitation of Liability. In no event and under no legal theory,
8198+ whether in tort (including negligence), contract, or otherwise,
8199+ unless required by applicable law (such as deliberate and grossly
8200+ negligent acts) or agreed to in writing, shall any Contributor be
8201+ liable to You for damages, including any direct, indirect, special,
8202+ incidental, or consequential damages of any character arising as a
8203+ result of this License or out of the use or inability to use the
8204+ Work (including but not limited to damages for loss of goodwill,
8205+ work stoppage, computer failure or malfunction, or any and all
8206+ other commercial damages or losses), even if such Contributor
8207+ has been advised of the possibility of such damages.
8208+
8209+ 9. Accepting Warranty or Additional Liability. While redistributing
8210+ the Work or Derivative Works thereof, You may choose to offer,
8211+ and charge a fee for, acceptance of support, warranty, indemnity,
8212+ or other liability obligations and/or rights consistent with this
8213+ License. However, in accepting such obligations, You may act only
8214+ on Your own behalf and on Your sole responsibility, not on behalf
8215+ of any other Contributor, and only if You agree to indemnify,
8216+ defend, and hold each Contributor harmless for any liability
8217+ incurred by, or claims asserted against, such Contributor by reason
8218+ of your accepting any such warranty or additional liability.
8219+
8220+ END OF TERMS AND CONDITIONS
8221+
8222+ APPENDIX: How to apply the Apache License to your work.
8223+
8224+ To apply the Apache License to your work, attach the following
8225+ boilerplate notice, with the fields enclosed by brackets "{}"
8226+ replaced with your own identifying information. (Don't include
8227+ the brackets!) The text should be enclosed in the appropriate
8228+ comment syntax for the file format. We also recommend that a
8229+ file or class name and description of purpose be included on the
8230+ same "printed page" as the copyright notice for easier
8231+ identification within third-party archives.
8232+
8233+ Copyright {2017} {UC Berkeley}
8234+
8235+ Licensed under the Apache License, Version 2.0 (the "License");
8236+ you may not use this file except in compliance with the License.
8237+ You may obtain a copy of the License at
8238+
8239+ http://www.apache.org/licenses/LICENSE-2.0
8240+
8241+ Unless required by applicable law or agreed to in writing, software
8242+ distributed under the License is distributed on an "AS IS" BASIS,
8243+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8244+ See the License for the specific language governing permissions and
8245+ limitations under the License.
8246diff --git a/LightVis - Shortcut.lnk b/LightVis - Shortcut.lnk
8247deleted file mode 100644
8248index 049ee43..0000000
8249Binary files a/LightVis - Shortcut.lnk and /dev/null differ
8250diff --git a/Object3D.cpp b/Object3D.cpp
8251index e87caba..99fcbb3 100644
8252--- a/Object3D.cpp
8253+++ b/Object3D.cpp
8254@@ -1,174 +1,174 @@
8255-#include "Object3D.h"
8256-#include "Visualizer.h"
8257-#include "Util.h"
8258-
8259-Object3D::Object3D()
8260-{
8261-
8262-}
8263-
8264-Object3D::Object3D(cv::Mat cluster) {
8265- // Step 1: Initialize variables
8266- rightEdgeConnected = false;
8267- leftEdgeConnected = false;
8268- hasHand = false;
8269- hasPlane = false;
8270- hasShape = false;
8271-
8272- // Step 1: determine whether cluster is hand
8273-
8274- if (checkForHand(cluster, 0.005, 0.25)) {
8275- hand = Hand(cluster, 50);
8276- hasHand = true;
8277- return;
8278- }
8279-
8280-
8281- // Step 2: determine whether there is a plane
8282-
8283- plane = new Plane(cluster);
8284- // Step 2.1 If there is plane, remove plane and look for hand
8285- std::vector<cv::Point2i> points = plane->getPlaneIndicies();
8286- if (points.size() != 0) {
8287- hasPlane = true;
8288- for (int i = 0; i < points.size();i++) {
8289- int x = points[i].x;
8290- int y = points[i].y;
8291- cluster.at<cv::Vec3f>(y, x)[0] = 0;
8292- cluster.at<cv::Vec3f>(y, x)[1] = 0;
8293- cluster.at<cv::Vec3f>(y, x)[2] = 0;
8294- }
8295-
8296- cv::Point center = Util::findCentroid(cluster);
8297-
8298- cv::Mat hand_cluster = cv::Mat::zeros(cluster.rows, cluster.cols, cluster.type());
8299- Util::floodFill(center.x, center.y, cluster, hand_cluster, 0.02);
8300-
8301- if (checkForHand(hand_cluster, -0.99, 0.2)) {
8302- hand = Hand(hand_cluster, 30);
8303- double finger_length = Util::euclidianDistance3D(hand.fingers_xyz[0], hand.centroid_xyz);
8304- if (finger_length > 0.03 && finger_length < 0.2) {
8305- hasHand = true;
8306- return;
8307- }
8308- }
8309- }
8310-
8311-
8312- // Step 2.1.1 If there is plane, no hand, then the rest of points are shape
8313- shape = cluster;
8314- hasShape = true;
8315-}
8316-
8317-Hand Object3D::getHand() {
8318- return hand;
8319-}
8320-
8321-Plane Object3D::getPlane() {
8322- return *plane;
8323-}
8324-
8325-cv::Mat Object3D::getShape() {
8326- return shape;
8327-}
8328-
8329-double Object3D::centroidCircleSweep(cv::Mat cluster, double distance)
8330-{
8331- cv::Mat channels[3];
8332- cv::split(cluster, channels);
8333- cv::Mat show_img = Visualizer::visualizeXYZMap(cluster);
8334-
8335- // Step 1: Find the center
8336- cv::Moments m = cv::moments(channels[2], false);
8337- cv::Point center(m.m10 / m.m00, m.m01 / m.m00);
8338- cv::circle(show_img, center, 2, cv::Scalar(255, 0, 0),2);
8339-
8340- // Step 2: Find the radius (pixels) that correspond to distance (meters)
8341- double distancePerPixel = Util::euclideanDistancePerPixel(cluster, center, 5);
8342- int radius = distance / distancePerPixel;
8343- if (radius <= 0 || radius > cluster.cols / 4) {
8344- return -1;
8345- }
8346-
8347- // Step 3: Extract all pixels within distance
8348- cv::Mat binary_img;
8349- cv::normalize(channels[2], binary_img, 0, 255, cv::NORM_MINMAX, CV_8UC1);
8350- cv::Mat mask = cv::Mat::zeros(binary_img.size(), binary_img.type());
8351- cv::Mat dstImg = cv::Mat::zeros(binary_img.size(), binary_img.type());
8352- cv::circle(mask, center, radius, cv::Scalar(255, 255, 255));
8353- binary_img.copyTo(dstImg, mask);
8354-
8355-
8356- int covered = 0;
8357- for (int r = center.y; r > 0; r--) {
8358- for (int c = 0; c < dstImg.cols; c++) {
8359- if (dstImg.at<uchar>(r, c) != 0) {
8360- covered++;
8361- }
8362- }
8363- }
8364-
8365- double coverage = (double) covered / cv::countNonZero(mask);
8366- return coverage;
8367-}
8368-
8369-bool Object3D::checkForHand(cv::Mat cluster, double min_coverage, double max_coverage, double pointer_finger_distance)
8370-{
8371- checkEdgeConnected(cluster);
8372- if ((rightEdgeConnected && !leftEdgeConnected) || (leftEdgeConnected && rightEdgeConnected)) {
8373- double coverage = centroidCircleSweep(cluster, pointer_finger_distance);
8374- if (coverage < max_coverage && coverage > min_coverage) {
8375- return true;
8376- }
8377- }
8378-
8379- return false;
8380-}
8381-
8382-void Object3D::checkEdgeConnected(cv::Mat cluster) {
8383- int cols = cluster.cols;
8384- int rows = cluster.rows;
8385-
8386- // Bottom Sweep
8387- int r = (int)(rows * 0.9);
8388- for (int c = 0; c < cols / 4 ; c++) {
8389- if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8390- leftEdgeConnected = true;
8391- break;
8392- }
8393- }
8394-
8395- // Left Side Sweep
8396- int c = (int)(cols * 0.2);
8397- for (int r = 0; r < rows; r++) {
8398- if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8399- leftEdgeConnected = true;
8400- break;
8401- }
8402- }
8403-
8404- // Bottom Sweep
8405- r = (int)(rows * 0.9);
8406- for (int c = cols / 4; c < cols; c++) {
8407- if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8408- rightEdgeConnected = true;
8409- break;
8410- }
8411- }
8412-
8413- // Right Side Sweep
8414- c = (int)(cols * 0.8);
8415- for (int r = rows / 2; r < rows; r++) {
8416- if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8417- rightEdgeConnected = true;
8418- break;
8419- }
8420- }
8421-
8422-}
8423-
8424-
8425-Object3D::~Object3D()
8426-{
8427-
8428+#include "Object3D.h"
8429+#include "Visualizer.h"
8430+#include "Util.h"
8431+
8432+Object3D::Object3D()
8433+{
8434+
8435+}
8436+
8437+Object3D::Object3D(cv::Mat cluster) {
8438+ // Step 1: Initialize variables
8439+ rightEdgeConnected = false;
8440+ leftEdgeConnected = false;
8441+ hasHand = false;
8442+ hasPlane = false;
8443+ hasShape = false;
8444+
8445+ // Step 1: determine whether cluster is hand
8446+
8447+ if (checkForHand(cluster, 0.005, 0.25)) {
8448+ hand = Hand(cluster, 50);
8449+ hasHand = true;
8450+ return;
8451+ }
8452+
8453+
8454+ // Step 2: determine whether there is a plane
8455+
8456+ plane = new Plane(cluster);
8457+ // Step 2.1 If there is plane, remove plane and look for hand
8458+ std::vector<cv::Point2i> points = plane->getPlaneIndicies();
8459+ if (points.size() != 0) {
8460+ hasPlane = true;
8461+ for (int i = 0; i < points.size();i++) {
8462+ int x = points[i].x;
8463+ int y = points[i].y;
8464+ cluster.at<cv::Vec3f>(y, x)[0] = 0;
8465+ cluster.at<cv::Vec3f>(y, x)[1] = 0;
8466+ cluster.at<cv::Vec3f>(y, x)[2] = 0;
8467+ }
8468+
8469+ cv::Point center = Util::findCentroid(cluster);
8470+
8471+ cv::Mat hand_cluster = cv::Mat::zeros(cluster.rows, cluster.cols, cluster.type());
8472+ Util::floodFill(center.x, center.y, cluster, hand_cluster, 0.02);
8473+
8474+ if (checkForHand(hand_cluster, -0.99, 0.2)) {
8475+ hand = Hand(hand_cluster, 30);
8476+ double finger_length = Util::euclidianDistance3D(hand.fingers_xyz[0], hand.centroid_xyz);
8477+ if (finger_length > 0.03 && finger_length < 0.2) {
8478+ hasHand = true;
8479+ return;
8480+ }
8481+ }
8482+ }
8483+
8484+
8485+ // Step 2.1.1 If there is plane, no hand, then the rest of points are shape
8486+ shape = cluster;
8487+ hasShape = true;
8488+}
8489+
8490+Hand Object3D::getHand() {
8491+ return hand;
8492+}
8493+
8494+Plane Object3D::getPlane() {
8495+ return *plane;
8496+}
8497+
8498+cv::Mat Object3D::getShape() {
8499+ return shape;
8500+}
8501+
8502+double Object3D::centroidCircleSweep(cv::Mat cluster, double distance)
8503+{
8504+ cv::Mat channels[3];
8505+ cv::split(cluster, channels);
8506+ cv::Mat show_img = Visualizer::visualizeXYZMap(cluster);
8507+
8508+ // Step 1: Find the center
8509+ cv::Moments m = cv::moments(channels[2], false);
8510+ cv::Point center(m.m10 / m.m00, m.m01 / m.m00);
8511+ cv::circle(show_img, center, 2, cv::Scalar(255, 0, 0),2);
8512+
8513+ // Step 2: Find the radius (pixels) that correspond to distance (meters)
8514+ double distancePerPixel = Util::euclideanDistancePerPixel(cluster, center, 5);
8515+ int radius = distance / distancePerPixel;
8516+ if (radius <= 0 || radius > cluster.cols / 4) {
8517+ return -1;
8518+ }
8519+
8520+ // Step 3: Extract all pixels within distance
8521+ cv::Mat binary_img;
8522+ cv::normalize(channels[2], binary_img, 0, 255, cv::NORM_MINMAX, CV_8UC1);
8523+ cv::Mat mask = cv::Mat::zeros(binary_img.size(), binary_img.type());
8524+ cv::Mat dstImg = cv::Mat::zeros(binary_img.size(), binary_img.type());
8525+ cv::circle(mask, center, radius, cv::Scalar(255, 255, 255));
8526+ binary_img.copyTo(dstImg, mask);
8527+
8528+
8529+ int covered = 0;
8530+ for (int r = center.y; r > 0; r--) {
8531+ for (int c = 0; c < dstImg.cols; c++) {
8532+ if (dstImg.at<uchar>(r, c) != 0) {
8533+ covered++;
8534+ }
8535+ }
8536+ }
8537+
8538+ double coverage = (double) covered / cv::countNonZero(mask);
8539+ return coverage;
8540+}
8541+
8542+bool Object3D::checkForHand(cv::Mat cluster, double min_coverage, double max_coverage, double pointer_finger_distance)
8543+{
8544+ checkEdgeConnected(cluster);
8545+ if ((rightEdgeConnected && !leftEdgeConnected) || (leftEdgeConnected && rightEdgeConnected)) {
8546+ double coverage = centroidCircleSweep(cluster, pointer_finger_distance);
8547+ if (coverage < max_coverage && coverage > min_coverage) {
8548+ return true;
8549+ }
8550+ }
8551+
8552+ return false;
8553+}
8554+
8555+void Object3D::checkEdgeConnected(cv::Mat cluster) {
8556+ int cols = cluster.cols;
8557+ int rows = cluster.rows;
8558+
8559+ // Bottom Sweep
8560+ int r = (int)(rows * 0.9);
8561+ for (int c = 0; c < cols / 4 ; c++) {
8562+ if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8563+ leftEdgeConnected = true;
8564+ break;
8565+ }
8566+ }
8567+
8568+ // Left Side Sweep
8569+ int c = (int)(cols * 0.2);
8570+ for (int r = 0; r < rows; r++) {
8571+ if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8572+ leftEdgeConnected = true;
8573+ break;
8574+ }
8575+ }
8576+
8577+ // Bottom Sweep
8578+ r = (int)(rows * 0.9);
8579+ for (int c = cols / 4; c < cols; c++) {
8580+ if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8581+ rightEdgeConnected = true;
8582+ break;
8583+ }
8584+ }
8585+
8586+ // Right Side Sweep
8587+ c = (int)(cols * 0.8);
8588+ for (int r = rows / 2; r < rows; r++) {
8589+ if (cluster.at<cv::Vec3f>(r, c)[2] != 0) {
8590+ rightEdgeConnected = true;
8591+ break;
8592+ }
8593+ }
8594+
8595+}
8596+
8597+
8598+Object3D::~Object3D()
8599+{
8600+
8601 }
8602\ No newline at end of file
8603diff --git a/Object3D.h b/Object3D.h
8604index 115e91b..cf3f61b 100644
8605--- a/Object3D.h
8606+++ b/Object3D.h
8607@@ -1,110 +1,111 @@
8608-#pragma once
8609-// OpenARK Libraries
8610-#include "Hand.h"
8611-#include "Plane.h"
8612-
8613-class Object3D
8614-{
8615-public:
8616- /**
8617- * Whether the object is attached to the right edge of the frame.
8618- * Edge connected implies that object is likely connected to the user's body (hand, arm, etc)
8619- */
8620- bool rightEdgeConnected;
8621-
8622- /**
8623- * Whether the object is attached to the left edge of the frame.
8624- * Edge connected implies that object is likely connected to the user's body (hand, arm, etc)
8625- */
8626- bool leftEdgeConnected;
8627-
8628- /**
8629- * Constructs a empty instance of a Object3D.
8630- */
8631- Object3D();
8632-
8633- /**
8634- * Constructs a instance of Object3D based on a point cloud.
8635- * @param cluster point cloud representatino of the object
8636- */
8637- Object3D(cv::Mat cluster);
8638-
8639- /**
8640- * Deconstructs a Object3D instance.
8641- */
8642- ~Object3D();
8643-
8644- /**
8645- * Whether the object contains a hand.
8646- */
8647- bool hasHand;
8648-
8649- /**
8650- * Whether the object contains a plane.
8651- */
8652- bool hasPlane;
8653-
8654- /**
8655- * Whether the object contains a shape.
8656- * A shape is defined by anything that is not a plane or a hand
8657- */
8658- bool hasShape;
8659-
8660- /**
8661- * Gets instance of hand object if a hand is found.
8662- * @return instance of hand object
8663- */
8664- Hand getHand();
8665-
8666- /**
8667- * Gets instance of plane object is plane is found.
8668- * @return instance of plane object
8669- */
8670- Plane getPlane();
8671-
8672- /**
8673- * Gets instance of shape object.
8674- * @return instance of shape object
8675- */
8676- cv::Mat getShape();
8677-
8678-private:
8679- /**
8680- * Reference to the hand instance.
8681- */
8682- Hand hand;
8683-
8684- /**
8685- * Reference to the plane instance.
8686- */
8687- Plane *plane;
8688-
8689- /**
8690- * Reference to the shape instance.
8691- */
8692- cv::Mat shape;
8693-
8694- /**
8695- * Determine whether the object is connected to an edge.
8696- * @param cluster point cloud of the object
8697- */
8698- void checkEdgeConnected(cv::Mat cluster);
8699-
8700- /**
8701- * Check whether the object is a hand
8702- * @param cluster the input point cloud
8703- * @param min_coverage the smallest allowable coverage for the index finger
8704- * @param max_coverage the maximum allowable coverage for the index finger
8705- * @param pointer_finger_distance the length of the pointer finger (meters)
8706- * @return whether the cluster is a hand
8707- */
8708- bool checkForHand(cv::Mat cluster, double min_coverage, double max_coverage, double pointer_finger_distance = 0.08);
8709-
8710- /**
8711- * Returns all points within a radius of a centroid
8712- * @param cluster the input point cloud
8713- * @param distance the radius (meters)
8714- * @return the percentage of points in the cluster that is "distance" away from the centroid
8715- */
8716- double centroidCircleSweep(cv::Mat cluster, double distance);
8717+#pragma once
8718+
8719+// OpenARK Libraries
8720+#include "Hand.h"
8721+#include "Plane.h"
8722+
8723+class Object3D
8724+{
8725+public:
8726+ /**
8727+ * Whether the object is attached to the right edge of the frame.
8728+ * Edge connected implies that object is likely connected to the user's body (hand, arm, etc)
8729+ */
8730+ bool rightEdgeConnected;
8731+
8732+ /**
8733+ * Whether the object is attached to the left edge of the frame.
8734+ * Edge connected implies that object is likely connected to the user's body (hand, arm, etc)
8735+ */
8736+ bool leftEdgeConnected;
8737+
8738+ /**
8739+ * Constructs a empty instance of a Object3D.
8740+ */
8741+ Object3D();
8742+
8743+ /**
8744+ * Constructs a instance of Object3D based on a point cloud.
8745+ * @param cluster point cloud representatino of the object
8746+ */
8747+ Object3D(cv::Mat cluster);
8748+
8749+ /**
8750+ * Deconstructs a Object3D instance.
8751+ */
8752+ ~Object3D();
8753+
8754+ /**
8755+ * Whether the object contains a hand.
8756+ */
8757+ bool hasHand;
8758+
8759+ /**
8760+ * Whether the object contains a plane.
8761+ */
8762+ bool hasPlane;
8763+
8764+ /**
8765+ * Whether the object contains a shape.
8766+ * A shape is defined by anything that is not a plane or a hand
8767+ */
8768+ bool hasShape;
8769+
8770+ /**
8771+ * Gets instance of hand object if a hand is found.
8772+ * @return instance of hand object
8773+ */
8774+ Hand getHand();
8775+
8776+ /**
8777+ * Gets instance of plane object is plane is found.
8778+ * @return instance of plane object
8779+ */
8780+ Plane getPlane();
8781+
8782+ /**
8783+ * Gets instance of shape object.
8784+ * @return instance of shape object
8785+ */
8786+ cv::Mat getShape();
8787+
8788+private:
8789+ /**
8790+ * Reference to the hand instance.
8791+ */
8792+ Hand hand;
8793+
8794+ /**
8795+ * Reference to the plane instance.
8796+ */
8797+ Plane *plane;
8798+
8799+ /**
8800+ * Reference to the shape instance.
8801+ */
8802+ cv::Mat shape;
8803+
8804+ /**
8805+ * Determine whether the object is connected to an edge.
8806+ * @param cluster point cloud of the object
8807+ */
8808+ void checkEdgeConnected(cv::Mat cluster);
8809+
8810+ /**
8811+ * Check whether the object is a hand
8812+ * @param cluster the input point cloud
8813+ * @param min_coverage the smallest allowable coverage for the index finger
8814+ * @param max_coverage the maximum allowable coverage for the index finger
8815+ * @param pointer_finger_distance the length of the pointer finger (meters)
8816+ * @return whether the cluster is a hand
8817+ */
8818+ bool checkForHand(cv::Mat cluster, double min_coverage, double max_coverage, double pointer_finger_distance = 0.08);
8819+
8820+ /**
8821+ * Returns all points within a radius of a centroid
8822+ * @param cluster the input point cloud
8823+ * @param distance the radius (meters)
8824+ * @return the percentage of points in the cluster that is "distance" away from the centroid
8825+ */
8826+ double centroidCircleSweep(cv::Mat cluster, double distance);
8827 };
8828\ No newline at end of file
8829diff --git a/OpenARK-SDK.sln b/OpenARK-SDK.sln
8830index c7657ec..9a96a38 100644
8831--- a/OpenARK-SDK.sln
8832+++ b/OpenARK-SDK.sln
8833@@ -1,28 +1,28 @@
8834-
8835-Microsoft Visual Studio Solution File, Format Version 12.00
8836-# Visual Studio 14
8837-VisualStudioVersion = 14.0.25123.0
8838-MinimumVisualStudioVersion = 10.0.40219.1
8839-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenARK-SDK", "OpenARK-SDK\OpenARK-SDK.vcxproj", "{3625C413-17C5-47C4-8878-B43FADFD79E2}"
8840-EndProject
8841-Global
8842- GlobalSection(SolutionConfigurationPlatforms) = preSolution
8843- Debug|x64 = Debug|x64
8844- Debug|x86 = Debug|x86
8845- Release|x64 = Release|x64
8846- Release|x86 = Release|x86
8847- EndGlobalSection
8848- GlobalSection(ProjectConfigurationPlatforms) = postSolution
8849- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x64.ActiveCfg = Debug|x64
8850- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x64.Build.0 = Debug|x64
8851- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x86.ActiveCfg = Debug|Win32
8852- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x86.Build.0 = Debug|Win32
8853- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x64.ActiveCfg = Release|x64
8854- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x64.Build.0 = Release|x64
8855- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x86.ActiveCfg = Release|Win32
8856- {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x86.Build.0 = Release|Win32
8857- EndGlobalSection
8858- GlobalSection(SolutionProperties) = preSolution
8859- HideSolutionNode = FALSE
8860- EndGlobalSection
8861-EndGlobal
8862+
8863+Microsoft Visual Studio Solution File, Format Version 12.00
8864+# Visual Studio 14
8865+VisualStudioVersion = 14.0.25123.0
8866+MinimumVisualStudioVersion = 10.0.40219.1
8867+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenARK-SDK", "OpenARK-SDK\OpenARK-SDK.vcxproj", "{3625C413-17C5-47C4-8878-B43FADFD79E2}"
8868+EndProject
8869+Global
8870+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
8871+ Debug|x64 = Debug|x64
8872+ Debug|x86 = Debug|x86
8873+ Release|x64 = Release|x64
8874+ Release|x86 = Release|x86
8875+ EndGlobalSection
8876+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
8877+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x64.ActiveCfg = Debug|x64
8878+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x64.Build.0 = Debug|x64
8879+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x86.ActiveCfg = Debug|Win32
8880+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Debug|x86.Build.0 = Debug|Win32
8881+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x64.ActiveCfg = Release|x64
8882+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x64.Build.0 = Release|x64
8883+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x86.ActiveCfg = Release|Win32
8884+ {3625C413-17C5-47C4-8878-B43FADFD79E2}.Release|x86.Build.0 = Release|Win32
8885+ EndGlobalSection
8886+ GlobalSection(SolutionProperties) = preSolution
8887+ HideSolutionNode = FALSE
8888+ EndGlobalSection
8889+EndGlobal
8890diff --git a/OpenARK-SDK/CMakeFindPackage.tx b/OpenARK-SDK/CMakeFindPackage.tx
8891index 316e9bc..1d69a0a 100644
8892--- a/OpenARK-SDK/CMakeFindPackage.tx
8893+++ b/OpenARK-SDK/CMakeFindPackage.tx
8894@@ -1,6 +1,6 @@
8895-FIND_PACKAGE([%package%] REQUIRED)
8896-IF ([%package%]_FOUND)
8897- INCLUDE_DIRECTORIES(${[%package%]_INCLUDE_DIR})
8898- ADD_DEFINITIONS( "-DHAS_[%package_upcase%]" )
8899-ENDIF()
8900+FIND_PACKAGE([%package%] REQUIRED)
8901+IF ([%package%]_FOUND)
8902+ INCLUDE_DIRECTORIES(${[%package%]_INCLUDE_DIR})
8903+ ADD_DEFINITIONS( "-DHAS_[%package_upcase%]" )
8904+ENDIF()
8905
8906\ No newline at end of file
8907diff --git a/OpenARK-SDK/CMakeLists.tx b/OpenARK-SDK/CMakeLists.tx
8908index 2ca3e1e..12eacbd 100644
8909--- a/OpenARK-SDK/CMakeLists.tx
8910+++ b/OpenARK-SDK/CMakeLists.tx
8911@@ -1,88 +1,88 @@
8912-cmake_minimum_required(VERSION 2.8)
8913-
8914-## section: Macro
8915-MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
8916- IF(MSVC)
8917- GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
8918- SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
8919- SET(Sources ${${SourcesVar}})
8920-
8921- SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
8922- PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
8923- OBJECT_OUTPUTS "${PrecompiledBinary}")
8924- SET_SOURCE_FILES_PROPERTIES(${Sources}
8925- PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
8926- OBJECT_DEPENDS "${PrecompiledBinary}")
8927- # Add precompiled header to SourcesVar
8928- LIST(APPEND ${SourcesVar} ${PrecompiledSource})
8929- ENDIF(MSVC)
8930-ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
8931-
8932-## start setting
8933-SET (this_target [% $target %])
8934-PROJECT(${this_target})
8935-
8936-[% IF charset == 'Unicode' %]
8937-add_definitions(-DUNICODE -D_UNICODE)
8938-[% END %]
8939-
8940-## section: include directory
8941-INCLUDE_DIRECTORIES(
8942- [% $include %]
8943- )
8944-
8945-## section: source files
8946-# Add your source files here (one file per line), please SORT in alphabetical order for future maintenance
8947-SET (${this_target}_SOURCE_FILES
8948- [% $src %]
8949- )
8950-
8951-## section: header files
8952-# Add your header files here(one file per line), please SORT in alphabetical order for future maintenance!
8953-SET(${this_target}_HEADER_FILES
8954- [% $header %]
8955- )
8956-
8957-[% source_groups %]
8958-
8959-## section: precompiled header
8960-#ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
8961-#ADD_LIBRARY(MyLibrary ${MySources})
8962-
8963-SET_SOURCE_FILES_PROPERTIES(${this_target}_HEADER_FILES
8964- PROPERTIES HEADER_FILE_ONLY TRUE)
8965-LIST(APPEND ${this_target}_SOURCE_FILES ${${this_target}_HEADER_FILES})
8966-
8967-## section: add definitions
8968-# add prefix -D. example> -DSHP
8969-# - DO NOT add the following definitions(already defined in ${OSP_DEFINITIONS}:
8970-# -DSHP, -DWIN32, -D_WINDOWS, -D_DEBUG, -D_USRDLL, -D_CRT_SECURE_NO_DEPRECATE
8971-ADD_DEFINITIONS(
8972- [% $def %]
8973- )
8974-
8975-## section: add target
8976-[% SWITCH type %]
8977-[% CASE 'Application' %]
8978-ADD_EXECUTABLE(${this_target} ${${this_target}_SOURCE_FILES})
8979-[% CASE 'DynamicLibrary' %]
8980-ADD_LIBRARY(${this_target} SHARED ${${this_target}_SOURCE_FILES} )
8981-[% CASE 'StaticLibrary' %]
8982-ADD_LIBRARY(${this_target} STATIC ${${this_target}_SOURCE_FILES} )
8983-[% CASE 'Module' %]
8984-ADD_LIBRARY(${this_target} MODULE ${${this_target}_SOURCE_FILES} )
8985-[% END %]
8986-
8987-[%- IF lib -%]
8988-## section: add dependency
8989-# dependency determines overall build order.
8990-ADD_DEPENDENCIES(${this_target}
8991- [% $lib %]
8992- )
8993-
8994-## section: set link libraries
8995-TARGET_LINK_LIBRARIES( ${this_target}
8996- [% $lib %]
8997- )
8998-[%- END -%]
8999-
9000+cmake_minimum_required(VERSION 2.8)
9001+
9002+## section: Macro
9003+MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
9004+ IF(MSVC)
9005+ GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
9006+ SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
9007+ SET(Sources ${${SourcesVar}})
9008+
9009+ SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
9010+ PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
9011+ OBJECT_OUTPUTS "${PrecompiledBinary}")
9012+ SET_SOURCE_FILES_PROPERTIES(${Sources}
9013+ PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
9014+ OBJECT_DEPENDS "${PrecompiledBinary}")
9015+ # Add precompiled header to SourcesVar
9016+ LIST(APPEND ${SourcesVar} ${PrecompiledSource})
9017+ ENDIF(MSVC)
9018+ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
9019+
9020+## start setting
9021+SET (this_target [% $target %])
9022+PROJECT(${this_target})
9023+
9024+[% IF charset == 'Unicode' %]
9025+add_definitions(-DUNICODE -D_UNICODE)
9026+[% END %]
9027+
9028+## section: include directory
9029+INCLUDE_DIRECTORIES(
9030+ [% $include %]
9031+ )
9032+
9033+## section: source files
9034+# Add your source files here (one file per line), please SORT in alphabetical order for future maintenance
9035+SET (${this_target}_SOURCE_FILES
9036+ [% $src %]
9037+ )
9038+
9039+## section: header files
9040+# Add your header files here(one file per line), please SORT in alphabetical order for future maintenance!
9041+SET(${this_target}_HEADER_FILES
9042+ [% $header %]
9043+ )
9044+
9045+[% source_groups %]
9046+
9047+## section: precompiled header
9048+#ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
9049+#ADD_LIBRARY(MyLibrary ${MySources})
9050+
9051+SET_SOURCE_FILES_PROPERTIES(${this_target}_HEADER_FILES
9052+ PROPERTIES HEADER_FILE_ONLY TRUE)
9053+LIST(APPEND ${this_target}_SOURCE_FILES ${${this_target}_HEADER_FILES})
9054+
9055+## section: add definitions
9056+# add prefix -D. example> -DSHP
9057+# - DO NOT add the following definitions(already defined in ${OSP_DEFINITIONS}:
9058+# -DSHP, -DWIN32, -D_WINDOWS, -D_DEBUG, -D_USRDLL, -D_CRT_SECURE_NO_DEPRECATE
9059+ADD_DEFINITIONS(
9060+ [% $def %]
9061+ )
9062+
9063+## section: add target
9064+[% SWITCH type %]
9065+[% CASE 'Application' %]
9066+ADD_EXECUTABLE(${this_target} ${${this_target}_SOURCE_FILES})
9067+[% CASE 'DynamicLibrary' %]
9068+ADD_LIBRARY(${this_target} SHARED ${${this_target}_SOURCE_FILES} )
9069+[% CASE 'StaticLibrary' %]
9070+ADD_LIBRARY(${this_target} STATIC ${${this_target}_SOURCE_FILES} )
9071+[% CASE 'Module' %]
9072+ADD_LIBRARY(${this_target} MODULE ${${this_target}_SOURCE_FILES} )
9073+[% END %]
9074+
9075+[%- IF lib -%]
9076+## section: add dependency
9077+# dependency determines overall build order.
9078+ADD_DEPENDENCIES(${this_target}
9079+ [% $lib %]
9080+ )
9081+
9082+## section: set link libraries
9083+TARGET_LINK_LIBRARIES( ${this_target}
9084+ [% $lib %]
9085+ )
9086+[%- END -%]
9087+
9088diff --git a/OpenARK-SDK/CMakeLists.txt b/OpenARK-SDK/CMakeLists.txt
9089index ec076ba..0fe91e2 100644
9090--- a/OpenARK-SDK/CMakeLists.txt
9091+++ b/OpenARK-SDK/CMakeLists.txt
9092@@ -1,101 +1,101 @@
9093-cmake_minimum_required(VERSION 2.8)
9094-
9095-## section: Macro
9096-MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
9097- IF(MSVC)
9098- GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
9099- SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
9100- SET(Sources ${${SourcesVar}})
9101-
9102- SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
9103- PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
9104- OBJECT_OUTPUTS "${PrecompiledBinary}")
9105- SET_SOURCE_FILES_PROPERTIES(${Sources}
9106- PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
9107- OBJECT_DEPENDS "${PrecompiledBinary}")
9108- # Add precompiled header to SourcesVar
9109- LIST(APPEND ${SourcesVar} ${PrecompiledSource})
9110- ENDIF(MSVC)
9111-ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
9112-
9113-## start setting
9114-SET (this_target OpenARKSDK)
9115-PROJECT(${this_target})
9116-
9117-
9118-
9119-## section: include directory
9120-INCLUDE_DIRECTORIES(
9121-
9122- )
9123-
9124-## section: source files
9125-# Add your source files here (one file per line), please SORT in alphabetical order for future maintenance
9126-SET (${this_target}_SOURCE_FILES
9127- ..\Clustering.cpp
9128- ..\DepthSensor.cpp
9129- ..\main.cpp
9130- ..\PMDSensor.cpp
9131- ..\RGBSensor.cpp
9132- ..\Visualizer.cpp
9133- ..\Sensor.cpp
9134- ..\Webcam.cpp
9135- )
9136-
9137-## section: header files
9138-# Add your header files here(one file per line), please SORT in alphabetical order for future maintenance!
9139-SET(${this_target}_HEADER_FILES
9140- ..\Clustering.h
9141- ..\DepthSensor.h
9142- ..\Hand.h
9143- ..\PMDSensor.h
9144- ..\RGBSensor.h
9145- ..\Sensor.h
9146- ..\Visualizer.h
9147- ..\Webcam.h
9148- )
9149-
9150-SOURCE_GROUP("Source Files" FILES
9151- ..\main.cpp
9152- ..\Sensor.cpp
9153- ..\DepthSensor.cpp
9154- ..\PMDSensor.cpp
9155- ..\Visualizer.cpp
9156- ..\RGBSensor.cpp
9157- ..\Webcam.cpp
9158- ..\Clustering.cpp
9159- )
9160-SOURCE_GROUP("Header Files" FILES
9161- ..\Sensor.h
9162- ..\DepthSensor.h
9163- ..\PMDSensor.h
9164- ..\Visualizer.h
9165- ..\RGBSensor.h
9166- ..\Webcam.h
9167- ..\Clustering.h
9168- ..\Hand.h
9169- )
9170-SOURCE_GROUP("Resource Files" FILES
9171-
9172- )
9173-
9174-
9175-## section: precompiled header
9176-#ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
9177-#ADD_LIBRARY(MyLibrary ${MySources})
9178-
9179-SET_SOURCE_FILES_PROPERTIES(${this_target}_HEADER_FILES
9180- PROPERTIES HEADER_FILE_ONLY TRUE)
9181-LIST(APPEND ${this_target}_SOURCE_FILES ${${this_target}_HEADER_FILES})
9182-
9183-## section: add definitions
9184-# add prefix -D. example> -DSHP
9185-# - DO NOT add the following definitions(already defined in ${OSP_DEFINITIONS}:
9186-# -DSHP, -DWIN32, -D_WINDOWS, -D_DEBUG, -D_USRDLL, -D_CRT_SECURE_NO_DEPRECATE
9187-ADD_DEFINITIONS(
9188-
9189- )
9190-
9191-## section: add target
9192-
9193-
9194+cmake_minimum_required(VERSION 2.8)
9195+
9196+## section: Macro
9197+MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
9198+ IF(MSVC)
9199+ GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
9200+ SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
9201+ SET(Sources ${${SourcesVar}})
9202+
9203+ SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
9204+ PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
9205+ OBJECT_OUTPUTS "${PrecompiledBinary}")
9206+ SET_SOURCE_FILES_PROPERTIES(${Sources}
9207+ PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
9208+ OBJECT_DEPENDS "${PrecompiledBinary}")
9209+ # Add precompiled header to SourcesVar
9210+ LIST(APPEND ${SourcesVar} ${PrecompiledSource})
9211+ ENDIF(MSVC)
9212+ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
9213+
9214+## start setting
9215+SET (this_target OpenARKSDK)
9216+PROJECT(${this_target})
9217+
9218+
9219+
9220+## section: include directory
9221+INCLUDE_DIRECTORIES(
9222+
9223+ )
9224+
9225+## section: source files
9226+# Add your source files here (one file per line), please SORT in alphabetical order for future maintenance
9227+SET (${this_target}_SOURCE_FILES
9228+ ..\Clustering.cpp
9229+ ..\DepthSensor.cpp
9230+ ..\main.cpp
9231+ ..\PMDSensor.cpp
9232+ ..\RGBSensor.cpp
9233+ ..\Visualizer.cpp
9234+ ..\Sensor.cpp
9235+ ..\Webcam.cpp
9236+ )
9237+
9238+## section: header files
9239+# Add your header files here(one file per line), please SORT in alphabetical order for future maintenance!
9240+SET(${this_target}_HEADER_FILES
9241+ ..\Clustering.h
9242+ ..\DepthSensor.h
9243+ ..\Hand.h
9244+ ..\PMDSensor.h
9245+ ..\RGBSensor.h
9246+ ..\Sensor.h
9247+ ..\Visualizer.h
9248+ ..\Webcam.h
9249+ )
9250+
9251+SOURCE_GROUP("Source Files" FILES
9252+ ..\main.cpp
9253+ ..\Sensor.cpp
9254+ ..\DepthSensor.cpp
9255+ ..\PMDSensor.cpp
9256+ ..\Visualizer.cpp
9257+ ..\RGBSensor.cpp
9258+ ..\Webcam.cpp
9259+ ..\Clustering.cpp
9260+ )
9261+SOURCE_GROUP("Header Files" FILES
9262+ ..\Sensor.h
9263+ ..\DepthSensor.h
9264+ ..\PMDSensor.h
9265+ ..\Visualizer.h
9266+ ..\RGBSensor.h
9267+ ..\Webcam.h
9268+ ..\Clustering.h
9269+ ..\Hand.h
9270+ )
9271+SOURCE_GROUP("Resource Files" FILES
9272+
9273+ )
9274+
9275+
9276+## section: precompiled header
9277+#ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
9278+#ADD_LIBRARY(MyLibrary ${MySources})
9279+
9280+SET_SOURCE_FILES_PROPERTIES(${this_target}_HEADER_FILES
9281+ PROPERTIES HEADER_FILE_ONLY TRUE)
9282+LIST(APPEND ${this_target}_SOURCE_FILES ${${this_target}_HEADER_FILES})
9283+
9284+## section: add definitions
9285+# add prefix -D. example> -DSHP
9286+# - DO NOT add the following definitions(already defined in ${OSP_DEFINITIONS}:
9287+# -DSHP, -DWIN32, -D_WINDOWS, -D_DEBUG, -D_USRDLL, -D_CRT_SECURE_NO_DEPRECATE
9288+ADD_DEFINITIONS(
9289+
9290+ )
9291+
9292+## section: add target
9293+
9294+
9295diff --git a/OpenARK-SDK/CMakeSourceGroup.tx b/OpenARK-SDK/CMakeSourceGroup.tx
9296index 599285d..935387d 100644
9297--- a/OpenARK-SDK/CMakeSourceGroup.tx
9298+++ b/OpenARK-SDK/CMakeSourceGroup.tx
9299@@ -1,3 +1,3 @@
9300-SOURCE_GROUP("[% flter %]" FILES
9301- [% files %]
9302- )
9303+SOURCE_GROUP("[% flter %]" FILES
9304+ [% files %]
9305+ )
9306diff --git a/OpenARK-SDK/OpenARK-SDK.vcxproj b/OpenARK-SDK/OpenARK-SDK.vcxproj
9307index 2f48d4c..8124c1c 100644
9308--- a/OpenARK-SDK/OpenARK-SDK.vcxproj
9309+++ b/OpenARK-SDK/OpenARK-SDK.vcxproj
9310@@ -1,160 +1,148 @@
9311-<?xml version="1.0" encoding="utf-8"?>
9312-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
9313- <ItemGroup Label="ProjectConfigurations">
9314- <ProjectConfiguration Include="Debug|Win32">
9315- <Configuration>Debug</Configuration>
9316- <Platform>Win32</Platform>
9317- </ProjectConfiguration>
9318- <ProjectConfiguration Include="Release|Win32">
9319- <Configuration>Release</Configuration>
9320- <Platform>Win32</Platform>
9321- </ProjectConfiguration>
9322- <ProjectConfiguration Include="Debug|x64">
9323- <Configuration>Debug</Configuration>
9324- <Platform>x64</Platform>
9325- </ProjectConfiguration>
9326- <ProjectConfiguration Include="Release|x64">
9327- <Configuration>Release</Configuration>
9328- <Platform>x64</Platform>
9329- </ProjectConfiguration>
9330- </ItemGroup>
9331- <PropertyGroup Label="Globals">
9332- <ProjectGuid>{3625C413-17C5-47C4-8878-B43FADFD79E2}</ProjectGuid>
9333- <RootNamespace>OpenARKSDK</RootNamespace>
9334- <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
9335- </PropertyGroup>
9336- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
9337- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
9338- <ConfigurationType>Application</ConfigurationType>
9339- <UseDebugLibraries>true</UseDebugLibraries>
9340- <PlatformToolset>v140</PlatformToolset>
9341- <CharacterSet>MultiByte</CharacterSet>
9342- </PropertyGroup>
9343- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
9344- <ConfigurationType>Application</ConfigurationType>
9345- <UseDebugLibraries>false</UseDebugLibraries>
9346- <PlatformToolset>v140</PlatformToolset>
9347- <WholeProgramOptimization>true</WholeProgramOptimization>
9348- <CharacterSet>MultiByte</CharacterSet>
9349- </PropertyGroup>
9350- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
9351- <ConfigurationType>Application</ConfigurationType>
9352- <UseDebugLibraries>true</UseDebugLibraries>
9353- <PlatformToolset>v140</PlatformToolset>
9354- <CharacterSet>MultiByte</CharacterSet>
9355- </PropertyGroup>
9356- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
9357- <ConfigurationType>Application</ConfigurationType>
9358- <UseDebugLibraries>false</UseDebugLibraries>
9359- <PlatformToolset>v140</PlatformToolset>
9360- <WholeProgramOptimization>true</WholeProgramOptimization>
9361- <CharacterSet>MultiByte</CharacterSet>
9362- </PropertyGroup>
9363- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
9364- <ImportGroup Label="ExtensionSettings">
9365- </ImportGroup>
9366- <ImportGroup Label="Shared">
9367- </ImportGroup>
9368- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9369- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9370- <Import Project="..\..\Program Files (x86)\Intel\RSSDK\props\VS2012-15.Integration.MD.props" />
9371- </ImportGroup>
9372- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
9373- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9374- <Import Project="..\..\Program Files (x86)\Intel\RSSDK\props\VS2012-15.Integration.MD.props" />
9375- </ImportGroup>
9376- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
9377- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9378- <Import Project="..\..\Program Files (x86)\Intel\RSSDK\props\VS2012-15.Integration.MD.props" />
9379- </ImportGroup>
9380- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
9381- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9382- <Import Project="..\..\Program Files (x86)\Intel\RSSDK\props\VS2012-15.Integration.MD.props" />
9383- </ImportGroup>
9384- <PropertyGroup Label="UserMacros" />
9385- <PropertyGroup />
9386- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9387- <ClCompile>
9388- <WarningLevel>Level3</WarningLevel>
9389- <Optimization>Disabled</Optimization>
9390- <SDLCheck>true</SDLCheck>
9391- </ClCompile>
9392- </ItemDefinitionGroup>
9393- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
9394- <ClCompile>
9395- <WarningLevel>Level3</WarningLevel>
9396- <Optimization>Disabled</Optimization>
9397- <SDLCheck>true</SDLCheck>
9398- </ClCompile>
9399- </ItemDefinitionGroup>
9400- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
9401- <ClCompile>
9402- <WarningLevel>Level3</WarningLevel>
9403- <Optimization>MaxSpeed</Optimization>
9404- <FunctionLevelLinking>true</FunctionLevelLinking>
9405- <IntrinsicFunctions>true</IntrinsicFunctions>
9406- <SDLCheck>true</SDLCheck>
9407- </ClCompile>
9408- <Link>
9409- <EnableCOMDATFolding>true</EnableCOMDATFolding>
9410- <OptimizeReferences>true</OptimizeReferences>
9411- </Link>
9412- </ItemDefinitionGroup>
9413- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
9414- <ClCompile>
9415- <WarningLevel>Level3</WarningLevel>
9416- <Optimization>MaxSpeed</Optimization>
9417- <FunctionLevelLinking>true</FunctionLevelLinking>
9418- <IntrinsicFunctions>true</IntrinsicFunctions>
9419- <SDLCheck>true</SDLCheck>
9420- <AdditionalIncludeDirectories>C:\Program Files\PCL 1.8.0\3rdParty\VTK\include\vtk-7.0;C:\Program Files\PCL 1.8.0\include\pcl-1.8;C:\Program Files\PCL 1.8.0\3rdParty\Eigen\eigen3;C:\Program Files\PCL 1.8.0\3rdParty\Boost\include\boost-1_61;C:\Program Files\PCL 1.8.0\3rdParty\Qhull\include;C:\Program Files\PCL 1.8.0\3rdParty\FLANN\include;C:\Program Files\PCL 1.8.0\3rdParty\Boost;C:\Program Files\OpenNI\Include;C:\Program Files\OpenNI2\Include;C:\opencv\build\include\opencv2;C:\opencv\build\include;C:\pmdsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
9421- <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9422- </ClCompile>
9423- <Link>
9424- <EnableCOMDATFolding>true</EnableCOMDATFolding>
9425- <OptimizeReferences>true</OptimizeReferences>
9426- <AdditionalLibraryDirectories>C:\Program Files\PCL 1.8.0\lib;C:\Program Files\PCL 1.8.0\lib\$(Configuration);C:\opencv\build\x64\vc14\lib;C:\pmd\PMDSDK\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
9427- <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_system-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_filesystem-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_thread-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_date_time-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_iostreams-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_serialization-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_chrono-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_atomic-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_regex-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\lib\pcl_common_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_octree_release.lib;C:\Program Files\OpenNI\Lib64\openNI64.lib;C:\Program Files\OpenNI2\Lib\OpenNI2.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkalglib-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkChartsCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonColor-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonDataModel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonMath-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtksys-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonMisc-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonSystem-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonTransforms-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInfovisCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersExtraction-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonExecutionModel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeneral-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonComputationalGeometry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersStatistics-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingFourier-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingContext2D-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeometry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSources-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingFreeType-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkfreetype-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkzlib-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkDICOMParser-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkDomainsChemistry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOXML-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOGeometry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOXMLParser-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkexpat-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkexoIIc-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkNetCDF-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkNetCDF_cxx-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkhdf5_hl-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkhdf5-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersAMR-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkParallelCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOLegacy-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersFlowPaths-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeneric-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersHybrid-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingSources-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersHyperTree-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersImaging-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingGeneral-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersModeling-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersParallel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersParallelImaging-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersProgrammable-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSelection-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSMP-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersTexture-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersVerdict-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkverdict-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkGeovisCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInfovisLayout-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingHybrid-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOImage-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkmetaio-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkjpeg-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkpng-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtktiff-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionStyle-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionWidgets-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingAnnotation-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingColor-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingVolume-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkproj4-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkgl2ps-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingMath-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingMorphological-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingStatistics-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingStencil-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionImage-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOAMR-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOEnSight-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOExodus-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOExport-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingGL2PS-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingContextOpenGL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingOpenGL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLabel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOImport-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOInfovis-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtklibxml2-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOLSDyna-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOMINC-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOMovie-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkoggtheora-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIONetCDF-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOParallel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkjsoncpp-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOParallelXML-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOPLY-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOSQL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtksqlite-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOVideo-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingImage-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLIC-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLOD-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingVolumeOpenGL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsContext2D-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsInfovis-7.0.lib;C:\Program Files\PCL 1.8.0\lib\pcl_io_release.lib;C:\Program Files\PCL 1.8.0\3rdParty\FLANN\lib\flann_cpp_s.lib;C:\Program Files\PCL 1.8.0\lib\pcl_kdtree_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_search_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_sample_consensus_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_filters_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_features_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_ml_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_segmentation_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_visualization_release.lib;C:\Program Files\PCL 1.8.0\3rdParty\Qhull\lib\qhullstatic.lib;C:\Program Files\PCL 1.8.0\lib\pcl_surface_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_registration_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_keypoints_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_tracking_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_recognition_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_stereo_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_outofcore_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_people_release.lib;opencv_world320.lib;vfw32.lib;glu32.lib;opengl32.lib;comctl32.lib;wsock32.lib;ws2_32.lib;Psapi.lib;pmdaccess2.lib;%(AdditionalDependencies)</AdditionalDependencies>
9428- <StackReserveSize>20000000</StackReserveSize>
9429- <StackCommitSize>20000000</StackCommitSize>
9430- </Link>
9431- </ItemDefinitionGroup>
9432- <ItemGroup>
9433- <ClCompile Include="..\Calibration.cpp" />
9434- <ClCompile Include="..\Converter.cpp" />
9435- <ClCompile Include="..\DepthCamera.cpp" />
9436- <ClCompile Include="..\global.cpp" />
9437- <ClCompile Include="..\Hand.cpp" />
9438- <ClCompile Include="..\main.cpp" />
9439- <ClCompile Include="..\Object3D.cpp" />
9440- <ClCompile Include="..\Plane.cpp" />
9441- <ClCompile Include="..\PMDCamera.cpp" />
9442- <ClCompile Include="..\RGBCamera.cpp" />
9443- <ClCompile Include="..\SR300Camera.cpp" />
9444- <ClCompile Include="..\StreamingAverager.cpp" />
9445- <ClCompile Include="..\UDPSender.cpp" />
9446- <ClCompile Include="..\Util.cpp" />
9447- <ClCompile Include="..\Visualizer.cpp" />
9448- <ClCompile Include="..\Webcam.cpp" />
9449- </ItemGroup>
9450- <ItemGroup>
9451- <ClInclude Include="..\Calibration.h" />
9452- <ClInclude Include="..\Converter.h" />
9453- <ClInclude Include="..\DepthCamera.h" />
9454- <ClInclude Include="..\global.h" />
9455- <ClInclude Include="..\Hand.h" />
9456- <ClInclude Include="..\Object3D.h" />
9457- <ClInclude Include="..\Plane.h" />
9458- <ClInclude Include="..\PMDCamera.h" />
9459- <ClInclude Include="..\RGBCamera.h" />
9460- <ClInclude Include="..\SR300Camera.h" />
9461- <ClInclude Include="..\StreamingAverager.h" />
9462- <ClInclude Include="..\UDPSender.h" />
9463- <ClInclude Include="..\Util.h" />
9464- <ClInclude Include="..\Visualizer.h" />
9465- <ClInclude Include="..\Webcam.h" />
9466- </ItemGroup>
9467- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
9468- <ImportGroup Label="ExtensionTargets">
9469- </ImportGroup>
9470+<?xml version="1.0" encoding="utf-8"?>
9471+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
9472+ <ItemGroup Label="ProjectConfigurations">
9473+ <ProjectConfiguration Include="Debug|Win32">
9474+ <Configuration>Debug</Configuration>
9475+ <Platform>Win32</Platform>
9476+ </ProjectConfiguration>
9477+ <ProjectConfiguration Include="Release|Win32">
9478+ <Configuration>Release</Configuration>
9479+ <Platform>Win32</Platform>
9480+ </ProjectConfiguration>
9481+ <ProjectConfiguration Include="Debug|x64">
9482+ <Configuration>Debug</Configuration>
9483+ <Platform>x64</Platform>
9484+ </ProjectConfiguration>
9485+ <ProjectConfiguration Include="Release|x64">
9486+ <Configuration>Release</Configuration>
9487+ <Platform>x64</Platform>
9488+ </ProjectConfiguration>
9489+ </ItemGroup>
9490+ <PropertyGroup Label="Globals">
9491+ <ProjectGuid>{3625C413-17C5-47C4-8878-B43FADFD79E2}</ProjectGuid>
9492+ <RootNamespace>OpenARKSDK</RootNamespace>
9493+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
9494+ </PropertyGroup>
9495+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
9496+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
9497+ <ConfigurationType>Application</ConfigurationType>
9498+ <UseDebugLibraries>true</UseDebugLibraries>
9499+ <PlatformToolset>v140</PlatformToolset>
9500+ <CharacterSet>MultiByte</CharacterSet>
9501+ </PropertyGroup>
9502+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
9503+ <ConfigurationType>Application</ConfigurationType>
9504+ <UseDebugLibraries>false</UseDebugLibraries>
9505+ <PlatformToolset>v140</PlatformToolset>
9506+ <WholeProgramOptimization>true</WholeProgramOptimization>
9507+ <CharacterSet>MultiByte</CharacterSet>
9508+ </PropertyGroup>
9509+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
9510+ <ConfigurationType>Application</ConfigurationType>
9511+ <UseDebugLibraries>true</UseDebugLibraries>
9512+ <PlatformToolset>v140</PlatformToolset>
9513+ <CharacterSet>MultiByte</CharacterSet>
9514+ </PropertyGroup>
9515+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
9516+ <ConfigurationType>Application</ConfigurationType>
9517+ <UseDebugLibraries>false</UseDebugLibraries>
9518+ <PlatformToolset>v140</PlatformToolset>
9519+ <WholeProgramOptimization>true</WholeProgramOptimization>
9520+ <CharacterSet>MultiByte</CharacterSet>
9521+ </PropertyGroup>
9522+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
9523+ <ImportGroup Label="ExtensionSettings">
9524+ </ImportGroup>
9525+ <ImportGroup Label="Shared">
9526+ </ImportGroup>
9527+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9528+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9529+ </ImportGroup>
9530+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
9531+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9532+ </ImportGroup>
9533+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
9534+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9535+ </ImportGroup>
9536+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
9537+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
9538+ </ImportGroup>
9539+ <PropertyGroup Label="UserMacros" />
9540+ <PropertyGroup />
9541+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9542+ <ClCompile>
9543+ <WarningLevel>Level3</WarningLevel>
9544+ <Optimization>Disabled</Optimization>
9545+ <SDLCheck>true</SDLCheck>
9546+ </ClCompile>
9547+ </ItemDefinitionGroup>
9548+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
9549+ <ClCompile>
9550+ <WarningLevel>Level3</WarningLevel>
9551+ <Optimization>Disabled</Optimization>
9552+ <SDLCheck>true</SDLCheck>
9553+ </ClCompile>
9554+ </ItemDefinitionGroup>
9555+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
9556+ <ClCompile>
9557+ <WarningLevel>Level3</WarningLevel>
9558+ <Optimization>MaxSpeed</Optimization>
9559+ <FunctionLevelLinking>true</FunctionLevelLinking>
9560+ <IntrinsicFunctions>true</IntrinsicFunctions>
9561+ <SDLCheck>true</SDLCheck>
9562+ </ClCompile>
9563+ <Link>
9564+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
9565+ <OptimizeReferences>true</OptimizeReferences>
9566+ </Link>
9567+ </ItemDefinitionGroup>
9568+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
9569+ <ClCompile>
9570+ <WarningLevel>Level3</WarningLevel>
9571+ <Optimization>MaxSpeed</Optimization>
9572+ <FunctionLevelLinking>true</FunctionLevelLinking>
9573+ <IntrinsicFunctions>true</IntrinsicFunctions>
9574+ <SDLCheck>true</SDLCheck>
9575+ <AdditionalIncludeDirectories>C:\Program Files\PCL 1.8.0\3rdParty\VTK\include\vtk-7.0;C:\Program Files\PCL 1.8.0\include\pcl-1.8;C:\Program Files\PCL 1.8.0\3rdParty\Eigen\eigen3;C:\Program Files\PCL 1.8.0\3rdParty\Boost\include\boost-1_61;C:\Program Files\OpenNI\Include;C:\Program Files\OpenNI2\Include;C:\Program Files\PCL 1.8.0\3rdParty\FLANN\include;C:\Program Files\PCL 1.8.0\3rdParty\Qhull\include;D:\PCL 1.8.0\3rdParty\VTK\include;$(OPENCV_DIR)\..\..\include;C:\dev\PMDDrivers\Windows\Windows64bit\PMDSDK\include;C:\Program Files\PCL 1.8.0\3rdParty\Boost;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
9576+ <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9577+ </ClCompile>
9578+ <Link>
9579+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
9580+ <OptimizeReferences>true</OptimizeReferences>
9581+ <AdditionalLibraryDirectories>C:\Program Files\PCL 1.8.0\lib;C:\Program Files\PCL 1.8.0\lib\$(Configuration);$(OPENCV_DIR)\lib;C:\dev\PMDDrivers\Windows\Windows64bit\PMDSDK\bin;$(OPENCV_DIR)\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
9582+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_system-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_filesystem-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_thread-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_date_time-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_iostreams-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_serialization-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_chrono-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_atomic-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\3rdParty\Boost\lib\libboost_regex-vc140-mt-1_61.lib;C:\Program Files\PCL 1.8.0\lib\pcl_common_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_octree_release.lib;C:\Program Files\OpenNI\Lib64\openNI64.lib;C:\Program Files\OpenNI2\Lib\OpenNI2.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkalglib-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkChartsCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonColor-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonDataModel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonMath-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtksys-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonMisc-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonSystem-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonTransforms-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInfovisCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersExtraction-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonExecutionModel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeneral-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkCommonComputationalGeometry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersStatistics-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingFourier-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingContext2D-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeometry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSources-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingFreeType-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkfreetype-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkzlib-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkDICOMParser-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkDomainsChemistry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOXML-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOGeometry-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOXMLParser-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkexpat-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkexoIIc-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkNetCDF-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkNetCDF_cxx-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkhdf5_hl-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkhdf5-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersAMR-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkParallelCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOLegacy-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersFlowPaths-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersGeneric-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersHybrid-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingSources-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersHyperTree-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersImaging-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingGeneral-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersModeling-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersParallel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersParallelImaging-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersProgrammable-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSelection-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersSMP-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersTexture-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkFiltersVerdict-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkverdict-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkGeovisCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInfovisLayout-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingHybrid-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOImage-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkmetaio-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkjpeg-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkpng-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtktiff-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionStyle-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionWidgets-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingAnnotation-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingColor-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingVolume-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsCore-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkproj4-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkgl2ps-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingMath-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingMorphological-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingStatistics-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkImagingStencil-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkInteractionImage-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOAMR-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOEnSight-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOExodus-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOExport-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingGL2PS-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingContextOpenGL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingOpenGL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLabel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOImport-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOInfovis-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtklibxml2-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOLSDyna-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOMINC-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOMovie-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkoggtheora-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIONetCDF-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOParallel-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkjsoncpp-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOParallelXML-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOPLY-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOSQL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtksqlite-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkIOVideo-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingImage-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLIC-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingLOD-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkRenderingVolumeOpenGL-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsContext2D-7.0.lib;C:\Program Files\PCL 1.8.0\3rdParty\VTK\lib\vtkViewsInfovis-7.0.lib;C:\Program Files\PCL 1.8.0\lib\pcl_io_release.lib;C:\Program Files\PCL 1.8.0\3rdParty\FLANN\lib\flann_cpp_s.lib;C:\Program Files\PCL 1.8.0\lib\pcl_kdtree_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_search_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_sample_consensus_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_filters_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_features_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_ml_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_segmentation_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_visualization_release.lib;C:\Program Files\PCL 1.8.0\3rdParty\Qhull\lib\qhullstatic.lib;C:\Program Files\PCL 1.8.0\lib\pcl_surface_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_registration_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_keypoints_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_tracking_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_recognition_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_stereo_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_outofcore_release.lib;C:\Program Files\PCL 1.8.0\lib\pcl_people_release.lib;cv2.lib;opencv_imgcodecs300.lib;opencv_superres300.lib;opencv_calib3d300.lib;opencv_imgproc300.lib;opencv_ts300.lib;opencv_core300.lib;opencv_ml300.lib;opencv_video300.lib;opencv_features2d300.lib;opencv_objdetect300.lib;opencv_videoio300.lib;opencv_flann300.lib;opencv_photo300.lib;opencv_videostab300.lib;opencv_hal300.lib;opencv_shape300.lib;opencv_highgui300.lib;opencv_stitching300.lib;vfw32.lib;glu32.lib;opengl32.lib;comctl32.lib;wsock32.lib;ws2_32.lib;Psapi.lib;pmdaccess2.lib;%(AdditionalDependencies)</AdditionalDependencies>
9583+ </Link>
9584+ </ItemDefinitionGroup>
9585+ <ItemGroup>
9586+ <ClCompile Include="..\Calibration.cpp" />
9587+ <ClCompile Include="..\DepthCamera.cpp" />
9588+ <ClCompile Include="..\Hand.cpp" />
9589+ <ClCompile Include="..\main.cpp" />
9590+ <ClCompile Include="..\Object3D.cpp" />
9591+ <ClCompile Include="..\Plane.cpp" />
9592+ <ClCompile Include="..\PMDCamera.cpp" />
9593+ <ClCompile Include="..\RGBCamera.cpp" />
9594+ <ClCompile Include="..\StreamingAverager.cpp" />
9595+ <ClCompile Include="..\UDPSender.cpp" />
9596+ <ClCompile Include="..\Util.cpp" />
9597+ <ClCompile Include="..\Visualizer.cpp" />
9598+ <ClCompile Include="..\Webcam.cpp" />
9599+ </ItemGroup>
9600+ <ItemGroup>
9601+ <ClInclude Include="..\Calibration.h" />
9602+ <ClInclude Include="..\DepthCamera.h" />
9603+ <ClInclude Include="..\Hand.h" />
9604+ <ClInclude Include="..\Object3D.h" />
9605+ <ClInclude Include="..\Plane.h" />
9606+ <ClInclude Include="..\PMDCamera.h" />
9607+ <ClInclude Include="..\RGBCamera.h" />
9608+ <ClInclude Include="..\StreamingAverager.h" />
9609+ <ClInclude Include="..\UDPSender.h" />
9610+ <ClInclude Include="..\Util.h" />
9611+ <ClInclude Include="..\Visualizer.h" />
9612+ <ClInclude Include="..\Webcam.h" />
9613+ </ItemGroup>
9614+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
9615+ <ImportGroup Label="ExtensionTargets">
9616+ </ImportGroup>
9617 </Project>
9618\ No newline at end of file
9619diff --git a/OpenARK-SDK/OpenARK-SDK.vcxproj.filters b/OpenARK-SDK/OpenARK-SDK.vcxproj.filters
9620index 71e2bf3..b3ef614 100644
9621--- a/OpenARK-SDK/OpenARK-SDK.vcxproj.filters
9622+++ b/OpenARK-SDK/OpenARK-SDK.vcxproj.filters
9623@@ -1,114 +1,96 @@
9624-<?xml version="1.0" encoding="utf-8"?>
9625-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
9626- <ItemGroup>
9627- <Filter Include="Source Files">
9628- <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
9629- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
9630- </Filter>
9631- <Filter Include="Header Files">
9632- <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
9633- <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
9634- </Filter>
9635- <Filter Include="Resource Files">
9636- <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
9637- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
9638- </Filter>
9639- </ItemGroup>
9640- <ItemGroup>
9641- <ClCompile Include="..\main.cpp">
9642- <Filter>Source Files</Filter>
9643- </ClCompile>
9644- <ClCompile Include="..\Visualizer.cpp">
9645- <Filter>Source Files</Filter>
9646- </ClCompile>
9647- <ClCompile Include="..\Webcam.cpp">
9648- <Filter>Source Files</Filter>
9649- </ClCompile>
9650- <ClCompile Include="..\Hand.cpp">
9651- <Filter>Source Files</Filter>
9652- </ClCompile>
9653- <ClCompile Include="..\Util.cpp">
9654- <Filter>Source Files</Filter>
9655- </ClCompile>
9656- <ClCompile Include="..\DepthCamera.cpp">
9657- <Filter>Source Files</Filter>
9658- </ClCompile>
9659- <ClCompile Include="..\PMDCamera.cpp">
9660- <Filter>Source Files</Filter>
9661- </ClCompile>
9662- <ClCompile Include="..\RGBCamera.cpp">
9663- <Filter>Source Files</Filter>
9664- </ClCompile>
9665- <ClCompile Include="..\Plane.cpp">
9666- <Filter>Source Files</Filter>
9667- </ClCompile>
9668- <ClCompile Include="..\Calibration.cpp">
9669- <Filter>Source Files</Filter>
9670- </ClCompile>
9671- <ClCompile Include="..\UDPSender.cpp">
9672- <Filter>Source Files</Filter>
9673- </ClCompile>
9674- <ClCompile Include="..\Object3D.cpp">
9675- <Filter>Source Files</Filter>
9676- </ClCompile>
9677- <ClCompile Include="..\StreamingAverager.cpp">
9678- <Filter>Source Files</Filter>
9679- </ClCompile>
9680- <ClCompile Include="..\Converter.cpp">
9681- <Filter>Source Files</Filter>
9682- </ClCompile>
9683- <ClCompile Include="..\SR300Camera.cpp">
9684- <Filter>Source Files</Filter>
9685- </ClCompile>
9686- <ClCompile Include="..\global.cpp">
9687- <Filter>Source Files</Filter>
9688- </ClCompile>
9689- </ItemGroup>
9690- <ItemGroup>
9691- <ClInclude Include="..\Visualizer.h">
9692- <Filter>Header Files</Filter>
9693- </ClInclude>
9694- <ClInclude Include="..\Webcam.h">
9695- <Filter>Header Files</Filter>
9696- </ClInclude>
9697- <ClInclude Include="..\Hand.h">
9698- <Filter>Header Files</Filter>
9699- </ClInclude>
9700- <ClInclude Include="..\Util.h">
9701- <Filter>Header Files</Filter>
9702- </ClInclude>
9703- <ClInclude Include="..\DepthCamera.h">
9704- <Filter>Header Files</Filter>
9705- </ClInclude>
9706- <ClInclude Include="..\PMDCamera.h">
9707- <Filter>Header Files</Filter>
9708- </ClInclude>
9709- <ClInclude Include="..\RGBCamera.h">
9710- <Filter>Header Files</Filter>
9711- </ClInclude>
9712- <ClInclude Include="..\Plane.h">
9713- <Filter>Header Files</Filter>
9714- </ClInclude>
9715- <ClInclude Include="..\Calibration.h">
9716- <Filter>Header Files</Filter>
9717- </ClInclude>
9718- <ClInclude Include="..\UDPSender.h">
9719- <Filter>Header Files</Filter>
9720- </ClInclude>
9721- <ClInclude Include="..\Object3D.h">
9722- <Filter>Header Files</Filter>
9723- </ClInclude>
9724- <ClInclude Include="..\StreamingAverager.h">
9725- <Filter>Header Files</Filter>
9726- </ClInclude>
9727- <ClInclude Include="..\Converter.h">
9728- <Filter>Header Files</Filter>
9729- </ClInclude>
9730- <ClInclude Include="..\SR300Camera.h">
9731- <Filter>Header Files</Filter>
9732- </ClInclude>
9733- <ClInclude Include="..\global.h">
9734- <Filter>Header Files</Filter>
9735- </ClInclude>
9736- </ItemGroup>
9737+<?xml version="1.0" encoding="utf-8"?>
9738+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
9739+ <ItemGroup>
9740+ <Filter Include="Source Files">
9741+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
9742+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
9743+ </Filter>
9744+ <Filter Include="Header Files">
9745+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
9746+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
9747+ </Filter>
9748+ <Filter Include="Resource Files">
9749+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
9750+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
9751+ </Filter>
9752+ </ItemGroup>
9753+ <ItemGroup>
9754+ <ClCompile Include="..\main.cpp">
9755+ <Filter>Source Files</Filter>
9756+ </ClCompile>
9757+ <ClCompile Include="..\Visualizer.cpp">
9758+ <Filter>Source Files</Filter>
9759+ </ClCompile>
9760+ <ClCompile Include="..\Webcam.cpp">
9761+ <Filter>Source Files</Filter>
9762+ </ClCompile>
9763+ <ClCompile Include="..\Hand.cpp">
9764+ <Filter>Source Files</Filter>
9765+ </ClCompile>
9766+ <ClCompile Include="..\Util.cpp">
9767+ <Filter>Source Files</Filter>
9768+ </ClCompile>
9769+ <ClCompile Include="..\DepthCamera.cpp">
9770+ <Filter>Source Files</Filter>
9771+ </ClCompile>
9772+ <ClCompile Include="..\PMDCamera.cpp">
9773+ <Filter>Source Files</Filter>
9774+ </ClCompile>
9775+ <ClCompile Include="..\RGBCamera.cpp">
9776+ <Filter>Source Files</Filter>
9777+ </ClCompile>
9778+ <ClCompile Include="..\Plane.cpp">
9779+ <Filter>Source Files</Filter>
9780+ </ClCompile>
9781+ <ClCompile Include="..\Calibration.cpp">
9782+ <Filter>Source Files</Filter>
9783+ </ClCompile>
9784+ <ClCompile Include="..\UDPSender.cpp">
9785+ <Filter>Source Files</Filter>
9786+ </ClCompile>
9787+ <ClCompile Include="..\Object3D.cpp">
9788+ <Filter>Source Files</Filter>
9789+ </ClCompile>
9790+ <ClCompile Include="..\StreamingAverager.cpp">
9791+ <Filter>Source Files</Filter>
9792+ </ClCompile>
9793+ </ItemGroup>
9794+ <ItemGroup>
9795+ <ClInclude Include="..\Visualizer.h">
9796+ <Filter>Header Files</Filter>
9797+ </ClInclude>
9798+ <ClInclude Include="..\Webcam.h">
9799+ <Filter>Header Files</Filter>
9800+ </ClInclude>
9801+ <ClInclude Include="..\Hand.h">
9802+ <Filter>Header Files</Filter>
9803+ </ClInclude>
9804+ <ClInclude Include="..\Util.h">
9805+ <Filter>Header Files</Filter>
9806+ </ClInclude>
9807+ <ClInclude Include="..\DepthCamera.h">
9808+ <Filter>Header Files</Filter>
9809+ </ClInclude>
9810+ <ClInclude Include="..\PMDCamera.h">
9811+ <Filter>Header Files</Filter>
9812+ </ClInclude>
9813+ <ClInclude Include="..\RGBCamera.h">
9814+ <Filter>Header Files</Filter>
9815+ </ClInclude>
9816+ <ClInclude Include="..\Plane.h">
9817+ <Filter>Header Files</Filter>
9818+ </ClInclude>
9819+ <ClInclude Include="..\Calibration.h">
9820+ <Filter>Header Files</Filter>
9821+ </ClInclude>
9822+ <ClInclude Include="..\UDPSender.h">
9823+ <Filter>Header Files</Filter>
9824+ </ClInclude>
9825+ <ClInclude Include="..\Object3D.h">
9826+ <Filter>Header Files</Filter>
9827+ </ClInclude>
9828+ <ClInclude Include="..\StreamingAverager.h">
9829+ <Filter>Header Files</Filter>
9830+ </ClInclude>
9831+ </ItemGroup>
9832 </Project>
9833\ No newline at end of file
9834diff --git a/OpenARK-SDK/README.md b/OpenARK-SDK/README.md
9835index e11aceb..e57a3a8 100644
9836--- a/OpenARK-SDK/README.md
9837+++ b/OpenARK-SDK/README.md
9838@@ -1,11 +1,11 @@
9839-## Required modules:
9840-* Try::Tiny;
9841-* XML::TreePP;
9842-* XML::TreePP::XMLPath;
9843-* Text::Xslate;
9844-* Readonly
9845-* autobox::Core
9846-
9847-## Usage
9848-
9849- perl vcxproj2cmake.pl <vcxproj path> <target configuration>
9850+## Required modules:
9851+* Try::Tiny;
9852+* XML::TreePP;
9853+* XML::TreePP::XMLPath;
9854+* Text::Xslate;
9855+* Readonly
9856+* autobox::Core
9857+
9858+## Usage
9859+
9860+ perl vcxproj2cmake.pl <vcxproj path> <target configuration>
9861diff --git a/OpenARK-SDK/vcxproj2cmake.pl b/OpenARK-SDK/vcxproj2cmake.pl
9862index 35129a7..9e6e9b8 100644
9863--- a/OpenARK-SDK/vcxproj2cmake.pl
9864+++ b/OpenARK-SDK/vcxproj2cmake.pl
9865@@ -1,426 +1,426 @@
9866-#!/usr/bin/env perl
9867-
9868-use strict;
9869-use warnings;
9870-use utf8;
9871-use feature 'say';
9872-use Readonly;
9873-
9874-use autobox::Core;
9875-use Try::Tiny;
9876-use XML::TreePP;
9877-use XML::TreePP::XMLPath;
9878-use Text::Xslate;
9879-use Data::Dumper;
9880-use FindBin;
9881-
9882-my $filepath = $ARGV[0]
9883- || die "Usage: $FindBin::Script <vcxproj path> <target configuration>";
9884-my $target_conf = $ARGV[1]
9885- || die "Usage: $FindBin::Script <vcxproj path> <target configuration>";
9886-
9887-my $filters_path = $filepath . '.filters';
9888-
9889-
9890-my $vcxproj_xml = XML::TreePP->new()->parsefile($filepath);
9891-my $vcxproj_filters_xml = XML::TreePP->new()->parsefile($filters_path);
9892-my $target = $vcxproj_xml->{Project}->{PropertyGroup}->[0]->{RootNamespace};
9893-my $target_prop = get_target_property($target_conf,
9894- get_propertys($vcxproj_xml));
9895-my $filenode_ref = get_file_node($vcxproj_xml);
9896-my $item_def_ref = get_item_def_group($vcxproj_xml,
9897- $target_prop->{-Condition});
9898-my %filters = get_filters($vcxproj_filters_xml);
9899-
9900-make($filenode_ref, $item_def_ref, %filters);
9901-
9902-sub get_filters {
9903- my ($vcxproj_filters_xml) = @_;
9904- my %filters = ();
9905-
9906- my @itemgroups = @{$vcxproj_filters_xml->{Project}->{ItemGroup}};
9907-
9908- # first itemgroup is list of filters
9909- for my $filter (@{$itemgroups[0]->{Filter}}) {
9910- my $filtername = $filter->{-Include};
9911- my @files = ();
9912- @{$filters{$filtername}} = @files;
9913- }
9914-
9915- # second itemgroup contains sorce files filter information
9916- for my $clcompile (@{$itemgroups[1]->{ClCompile}}) {
9917- my $filename = $clcompile->{-Include};
9918- my $filter = $clcompile->{Filter};
9919- push @{$filters{$filter}}, $filename;
9920- }
9921-
9922- # third itemgroup contains header files filter information
9923- for my $clinclude (@{$itemgroups[2]->{ClInclude}}) {
9924- my $filename = $clinclude->{-Include};
9925- my $filter = $clinclude->{Filter};
9926- push @{$filters{$filter}}, $filename;
9927- }
9928-
9929- # fourth itemgroup contains filter information for files that should not compiled (like readme)
9930-
9931- # fifth itemgroup contains recources filter
9932-
9933- # remove empty arrays
9934- my @toDelete;
9935- for my $filter (keys %filters) {
9936- my @filterfiles = @{$filters{$filter}};
9937- if (scalar @filterfiles == 0) {
9938- push @toDelete, $filter;
9939- }
9940- }
9941- #delete @filters{@toDelete};
9942-
9943- return %filters;
9944-}
9945-
9946-sub get_target_property {
9947- my ($target_conf, @property_groups) = @_;
9948- my $target_prop;
9949- for my $property (@property_groups) {
9950- if ($property->{-Condition} =~ m{$target_conf}) {
9951- $target_prop = $property;
9952- last;
9953- }
9954- }
9955-
9956- return $target_prop;
9957-}
9958-
9959-sub get_item_def_group {
9960- my ($vcxproj_xml, $cond) = @_;
9961- my $tppx = new XML::TreePP::XMLPath;
9962-
9963- # my $xpath = '/Project/ItemDefinitionGroup[@Condition="'.$cond.'"]';
9964- # warn $xpath;
9965- # my $item_def_ref = $tppx->filterXMLDoc($vcxproj_xml, $xpath);
9966- my $item_def_ref;
9967- for my $item_def ($tppx->filterXMLDoc($vcxproj_xml,
9968- '/Project/ItemDefinitionGroup')) {
9969- if ($item_def->{-Condition} eq $cond) {
9970- $item_def_ref = $item_def;
9971- last;
9972- }
9973- }
9974-
9975- return $item_def_ref;
9976-}
9977-
9978-sub get_propertys {
9979- my ($vcxproj_xml) = @_;
9980- my $property_node_ref;
9981-
9982- my $tppx = new XML::TreePP::XMLPath;
9983- my @property_groups
9984- = $tppx->filterXMLDoc($vcxproj_xml,
9985- '/Project/PropertyGroup[@Label="Configuration"]');
9986-
9987- return @property_groups;
9988-}
9989-
9990-sub get_file_node {
9991- my ($vcxproj_xml) = @_;
9992- my @itemgroups = @{$vcxproj_xml->{Project}->{ItemGroup}};
9993- my $filenode_ref;
9994- for my $itemgroup (@itemgroups) {
9995- next if (defined $itemgroup->{-Label}
9996- && $itemgroup->{-Label} eq 'ProjectConfigurations');
9997-
9998- for my $nodename (keys %{$itemgroup}) {
9999- my @nodes;
10000-
10001- if (ref($itemgroup->{$nodename}) eq 'HASH') {
10002- push @nodes, $itemgroup->{$nodename};
10003- } else {
10004- @nodes = @{$itemgroup->{$nodename}};
10005- }
10006-
10007- for my $node (@nodes) {
10008- unless (defined $node->{ExcludedFromBuild}
10009- && $node->{ExcludedFromBuild}->{-Condition} eq $target_prop->{-Condition}) {
10010- push @{$filenode_ref->{$nodename}}, $node->{-Include};
10011- }
10012- }
10013- }
10014- }
10015-
10016- return $filenode_ref;
10017-}
10018-
10019-sub render_find_packages {
10020- my ($tx, @srcs) = @_;
10021- my %find_packages_supported_by_cmake = (
10022- # include_pattern => package_name
10023-
10024- #'' => 'ALSA',
10025- #'' => 'Armadillo',
10026- #'' => 'ASPELL',
10027- #'' => 'AVIFile',
10028- #'' => 'BISON',
10029- #'' => 'BLAS',
10030- 'boost/' => 'Boost',
10031- #'' => 'Bullet',
10032- #'' => 'BZip2',
10033- #'' => 'CABLE',
10034- #'' => 'Coin3D',
10035- #'' => 'CUDA',
10036- #'' => 'Cups',
10037- #'' => 'CURL',
10038- #'' => 'Curses',
10039- #'' => 'CVS',
10040- #'' => 'CxxTest',
10041- #'' => 'Cygwin',
10042- #'' => 'Dart',
10043- #'' => 'DCMTK',
10044- #'' => 'DevIL',
10045- #'' => 'Doxygen',
10046- #'' => 'EXPAT',
10047- #'' => 'FLEX',
10048- #'' => 'FLTK',
10049- #'' => 'FLTK2',
10050- #'' => 'Freetype',
10051- #'' => 'GCCXML',
10052- #'' => 'GDAL',
10053- #'' => 'Gettext',
10054- #'' => 'GIF',
10055- #'' => 'Git',
10056- #'' => 'GLU',
10057- #'' => 'GLUT',
10058- #'' => 'Gnuplot',
10059- #'' => 'GnuTLS',
10060- #'' => 'GTest',
10061- #'' => 'GTK',
10062- #'' => 'GTK2',
10063- #'' => 'HDF5',
10064- #'' => 'HSPELL',
10065- #'' => 'HTMLHelp',
10066- #'' => 'ImageMagick',
10067- #'' => 'ITK',
10068- #'' => 'Jasper',
10069- #'' => 'Java',
10070- #'' => 'JNI',
10071- #'' => 'JPEG',
10072- #'' => 'KDE3',
10073- #'' => 'KDE4',
10074- #'' => 'LAPACK',
10075- #'' => 'LATEX',
10076- #'' => 'LibArchive',
10077- #'' => 'LibLZMA',
10078- #'' => 'LibXml2',
10079- #'' => 'LibXslt',
10080- #'' => 'Lua50',
10081- #'' => 'Lua51',
10082- #'' => 'Matlab',
10083- #'' => 'MFC',
10084- #'' => 'Motif',
10085- #'' => 'MPEG',
10086- #'' => 'MPEG2',
10087- #'' => 'MPI',
10088- #'' => 'OpenAL',
10089- #'' => 'OpenGL',
10090- #'' => 'OpenMP',
10091- #'' => 'OpenSceneGraph',
10092- 'openssl/' => 'OpenSSL',
10093- #'' => 'OpenThreads',
10094- #'' => 'osg',
10095- #'' => 'osgAnimation',
10096- #'' => 'osgDB',
10097- #'' => 'osgFX',
10098- #'' => 'osgGA',
10099- #'' => 'osgIntrospection',
10100- #'' => 'osgManipulator',
10101- #'' => 'osgParticle',
10102- #'' => 'osgPresentation',
10103- #'' => 'osgProducer',
10104- #'' => 'osgQt',
10105- #'' => 'osgShadow',
10106- #'' => 'osgSim',
10107- #'' => 'osgTerrain',
10108- #'' => 'osgText',
10109- #'' => 'osgUtil',
10110- #'' => 'osgViewer',
10111- #'' => 'osgVolume',
10112- #'' => 'osgWidget',
10113- #'' => 'osg_functions',
10114- #'' => 'PackageHandleStandardArgs',
10115- #'' => 'PackageMessage',
10116- #'' => 'Perl',
10117- #'' => 'PerlLibs',
10118- #'' => 'PHP4',
10119- #'' => 'PhysFS',
10120- #'' => 'Pike',
10121- #'' => 'PkgConfig',
10122- #'' => 'PNG',
10123- #'' => 'PostgreSQL',
10124- #'' => 'Producer',
10125- #'' => 'Protobuf',
10126- #'' => 'PythonInterp',
10127- #'' => 'PythonLibs',
10128- #'' => 'Qt',
10129- #'' => 'Qt3',
10130- #'' => 'Qt4',
10131- #'' => 'QuickTime',
10132- #'' => 'RTI',
10133- #'' => 'Ruby',
10134- 'SDL/' => 'SDL',
10135- #'' => 'SDL_image',
10136- #'' => 'SDL_mixer',
10137- #'' => 'SDL_net',
10138- #'' => 'SDL_sound',
10139- #'' => 'SDL_ttf',
10140- #'' => 'SelfPackers',
10141- #'' => 'Squish',
10142- #'' => 'Subversion',
10143- #'' => 'SWIG',
10144- #'' => 'TCL',
10145- #'' => 'Tclsh',
10146- #'' => 'TclStub',
10147- #'' => 'Threads',
10148- #'' => 'TIFF',
10149- #'' => 'UnixCommands',
10150- #'' => 'VTK',
10151- #'' => 'Wget',
10152- #'' => 'Wish',
10153- #'' => 'wxWidgets',
10154- #'' => 'wxWindows',
10155- #'' => 'X11',
10156- 'xercesc' => 'XercesC',
10157- #'' => 'XMLRPC',
10158- 'zlib.h' => 'ZLIB',
10159- );
10160- my $rendered_find_packages = '';
10161-
10162- # find all libs that used
10163- my @libs_to_find_patterns = keys(%find_packages_supported_by_cmake);
10164- my @libs;
10165- for my $file (@srcs) {
10166- # find libs that the file uses
10167- open my $info, $file or die "Could not open $file: $!";
10168- while( my $line = <$info>) {
10169- if ($line =~ /#\s*include/) {
10170- my @lib_pattern_indexes_to_delete;
10171-
10172- for my $lib_match (@libs_to_find_patterns) {
10173- if ($line =~ m/^\s*#\s*include\s*<$lib_match/) {
10174- my $lib = $find_packages_supported_by_cmake{$lib_match};
10175- push @libs, $lib;
10176-
10177- my $lib_index = 0;
10178- $lib_index++ until $libs_to_find_patterns[$lib_index] eq $lib_match;
10179- push @lib_pattern_indexes_to_delete, $lib_index;
10180- }
10181- }
10182-
10183- for my $index (@lib_pattern_indexes_to_delete) {
10184- splice(@libs_to_find_patterns, $index, 1);
10185- }
10186- }
10187- }
10188- close $info;
10189- }
10190-
10191- for my $lib (@libs) {
10192- my %vars = (
10193- package => $lib,
10194- package_upcase => uc $lib,
10195- );
10196- warn Dumper(%vars);
10197-
10198- try {
10199- my $render = $tx->render( 'CMakeFindPackage.tx', \%vars );
10200- $rendered_find_packages = $rendered_find_packages . $render;
10201- } catch {
10202- print "caught error: $_\n";
10203- };
10204- }
10205-
10206- return Text::Xslate::Util::mark_raw($rendered_find_packages);
10207-}
10208-
10209-sub render_source_groups {
10210- my ($tx, %filters) = @_;
10211-
10212- my $rendered_source_groups = '';
10213- for my $filter (keys %filters) {
10214- my @files = @{$filters{$filter}};
10215- $filter =~ s/\\/\\\\/g;
10216- my %vars = (
10217- flter => $filter,
10218- files => +(join "\n\t", @files),
10219- );
10220- warn Dumper(%vars);
10221-
10222- try {
10223- my $render = $tx->render( 'CMakeSourceGroup.tx', \%vars );
10224- $rendered_source_groups = $rendered_source_groups . $render;
10225- } catch {
10226- print "caught error: $_\n";
10227- };
10228- }
10229-
10230- return Text::Xslate::Util::mark_raw($rendered_source_groups);
10231-}
10232-
10233-sub make {
10234- my ($filenode_ref, $item_def_ref, %filters) = @_;
10235-
10236- my @srcs = @{$filenode_ref->{ClCompile}};
10237- my @headers = @{$filenode_ref->{ClInclude}};
10238- my $add_dir = $item_def_ref->{ClCompile}->{AdditionalIncludeDirectories};
10239- $add_dir =~ s{\\}{/}g;
10240- my @includes =
10241- grep { $_ ne '%(AdditionalIncludeDirectories)' }
10242- split ';', $add_dir;
10243-
10244- my $def = $item_def_ref->{ClCompile}->{PreprocessorDefinitions};
10245- # add prefix -D. example> -DSHP
10246- my @defs =
10247- map { "-D$_"; }
10248- grep { $_ ne '%(PreprocessorDefinitions)' }
10249- split ';', $def;
10250-
10251- my $add_dep = $item_def_ref->{Link}->{AdditionalDependencies};
10252- $add_dep =~ s{\\}{/}g;
10253- my @deps =
10254- grep { $_ ne '%(AdditionalDependencies)' }
10255- split ';', $add_dep;
10256-
10257- warn Dumper(@includes);
10258-
10259- my $tx = Text::Xslate->new(
10260- syntax => 'TTerse',
10261- path => [ '.', '.' ],
10262- );
10263-
10264- my $rendered_find_packages = render_find_packages($tx, @headers, @srcs);
10265- my $rendered_source_groups = render_source_groups($tx, %filters);
10266-
10267- my %vars = (
10268- type => $target_prop->{ConfigurationType},
10269- charset => $target_prop->{CharacterSet},
10270- target => $target,
10271- def => +(join "\n\t", @defs),
10272- lib => +(join "\n\t", @deps),
10273- include => +(join "\n\t", @includes),
10274- src => +(join "\n\t", @srcs),
10275- header => +(join "\n\t", @headers),
10276- source_groups => $rendered_source_groups,
10277- find_packages => $rendered_find_packages,
10278- );
10279-
10280- warn Dumper(%vars);
10281-
10282- my $render_text;
10283- try {
10284- $render_text = $tx->render( 'CMakeLists.tx', \%vars );
10285- } catch {
10286- print "caught error: $_\n";
10287- };
10288-
10289- open my $cmakelists_file, '>', 'CMakeLists.txt';
10290- print {$cmakelists_file} $render_text;
10291-}
10292+#!/usr/bin/env perl
10293+
10294+use strict;
10295+use warnings;
10296+use utf8;
10297+use feature 'say';
10298+use Readonly;
10299+
10300+use autobox::Core;
10301+use Try::Tiny;
10302+use XML::TreePP;
10303+use XML::TreePP::XMLPath;
10304+use Text::Xslate;
10305+use Data::Dumper;
10306+use FindBin;
10307+
10308+my $filepath = $ARGV[0]
10309+ || die "Usage: $FindBin::Script <vcxproj path> <target configuration>";
10310+my $target_conf = $ARGV[1]
10311+ || die "Usage: $FindBin::Script <vcxproj path> <target configuration>";
10312+
10313+my $filters_path = $filepath . '.filters';
10314+
10315+
10316+my $vcxproj_xml = XML::TreePP->new()->parsefile($filepath);
10317+my $vcxproj_filters_xml = XML::TreePP->new()->parsefile($filters_path);
10318+my $target = $vcxproj_xml->{Project}->{PropertyGroup}->[0]->{RootNamespace};
10319+my $target_prop = get_target_property($target_conf,
10320+ get_propertys($vcxproj_xml));
10321+my $filenode_ref = get_file_node($vcxproj_xml);
10322+my $item_def_ref = get_item_def_group($vcxproj_xml,
10323+ $target_prop->{-Condition});
10324+my %filters = get_filters($vcxproj_filters_xml);
10325+
10326+make($filenode_ref, $item_def_ref, %filters);
10327+
10328+sub get_filters {
10329+ my ($vcxproj_filters_xml) = @_;
10330+ my %filters = ();
10331+
10332+ my @itemgroups = @{$vcxproj_filters_xml->{Project}->{ItemGroup}};
10333+
10334+ # first itemgroup is list of filters
10335+ for my $filter (@{$itemgroups[0]->{Filter}}) {
10336+ my $filtername = $filter->{-Include};
10337+ my @files = ();
10338+ @{$filters{$filtername}} = @files;
10339+ }
10340+
10341+ # second itemgroup contains sorce files filter information
10342+ for my $clcompile (@{$itemgroups[1]->{ClCompile}}) {
10343+ my $filename = $clcompile->{-Include};
10344+ my $filter = $clcompile->{Filter};
10345+ push @{$filters{$filter}}, $filename;
10346+ }
10347+
10348+ # third itemgroup contains header files filter information
10349+ for my $clinclude (@{$itemgroups[2]->{ClInclude}}) {
10350+ my $filename = $clinclude->{-Include};
10351+ my $filter = $clinclude->{Filter};
10352+ push @{$filters{$filter}}, $filename;
10353+ }
10354+
10355+ # fourth itemgroup contains filter information for files that should not compiled (like readme)
10356+
10357+ # fifth itemgroup contains recources filter
10358+
10359+ # remove empty arrays
10360+ my @toDelete;
10361+ for my $filter (keys %filters) {
10362+ my @filterfiles = @{$filters{$filter}};
10363+ if (scalar @filterfiles == 0) {
10364+ push @toDelete, $filter;
10365+ }
10366+ }
10367+ #delete @filters{@toDelete};
10368+
10369+ return %filters;
10370+}
10371+
10372+sub get_target_property {
10373+ my ($target_conf, @property_groups) = @_;
10374+ my $target_prop;
10375+ for my $property (@property_groups) {
10376+ if ($property->{-Condition} =~ m{$target_conf}) {
10377+ $target_prop = $property;
10378+ last;
10379+ }
10380+ }
10381+
10382+ return $target_prop;
10383+}
10384+
10385+sub get_item_def_group {
10386+ my ($vcxproj_xml, $cond) = @_;
10387+ my $tppx = new XML::TreePP::XMLPath;
10388+
10389+ # my $xpath = '/Project/ItemDefinitionGroup[@Condition="'.$cond.'"]';
10390+ # warn $xpath;
10391+ # my $item_def_ref = $tppx->filterXMLDoc($vcxproj_xml, $xpath);
10392+ my $item_def_ref;
10393+ for my $item_def ($tppx->filterXMLDoc($vcxproj_xml,
10394+ '/Project/ItemDefinitionGroup')) {
10395+ if ($item_def->{-Condition} eq $cond) {
10396+ $item_def_ref = $item_def;
10397+ last;
10398+ }
10399+ }
10400+
10401+ return $item_def_ref;
10402+}
10403+
10404+sub get_propertys {
10405+ my ($vcxproj_xml) = @_;
10406+ my $property_node_ref;
10407+
10408+ my $tppx = new XML::TreePP::XMLPath;
10409+ my @property_groups
10410+ = $tppx->filterXMLDoc($vcxproj_xml,
10411+ '/Project/PropertyGroup[@Label="Configuration"]');
10412+
10413+ return @property_groups;
10414+}
10415+
10416+sub get_file_node {
10417+ my ($vcxproj_xml) = @_;
10418+ my @itemgroups = @{$vcxproj_xml->{Project}->{ItemGroup}};
10419+ my $filenode_ref;
10420+ for my $itemgroup (@itemgroups) {
10421+ next if (defined $itemgroup->{-Label}
10422+ && $itemgroup->{-Label} eq 'ProjectConfigurations');
10423+
10424+ for my $nodename (keys %{$itemgroup}) {
10425+ my @nodes;
10426+
10427+ if (ref($itemgroup->{$nodename}) eq 'HASH') {
10428+ push @nodes, $itemgroup->{$nodename};
10429+ } else {
10430+ @nodes = @{$itemgroup->{$nodename}};
10431+ }
10432+
10433+ for my $node (@nodes) {
10434+ unless (defined $node->{ExcludedFromBuild}
10435+ && $node->{ExcludedFromBuild}->{-Condition} eq $target_prop->{-Condition}) {
10436+ push @{$filenode_ref->{$nodename}}, $node->{-Include};
10437+ }
10438+ }
10439+ }
10440+ }
10441+
10442+ return $filenode_ref;
10443+}
10444+
10445+sub render_find_packages {
10446+ my ($tx, @srcs) = @_;
10447+ my %find_packages_supported_by_cmake = (
10448+ # include_pattern => package_name
10449+
10450+ #'' => 'ALSA',
10451+ #'' => 'Armadillo',
10452+ #'' => 'ASPELL',
10453+ #'' => 'AVIFile',
10454+ #'' => 'BISON',
10455+ #'' => 'BLAS',
10456+ 'boost/' => 'Boost',
10457+ #'' => 'Bullet',
10458+ #'' => 'BZip2',
10459+ #'' => 'CABLE',
10460+ #'' => 'Coin3D',
10461+ #'' => 'CUDA',
10462+ #'' => 'Cups',
10463+ #'' => 'CURL',
10464+ #'' => 'Curses',
10465+ #'' => 'CVS',
10466+ #'' => 'CxxTest',
10467+ #'' => 'Cygwin',
10468+ #'' => 'Dart',
10469+ #'' => 'DCMTK',
10470+ #'' => 'DevIL',
10471+ #'' => 'Doxygen',
10472+ #'' => 'EXPAT',
10473+ #'' => 'FLEX',
10474+ #'' => 'FLTK',
10475+ #'' => 'FLTK2',
10476+ #'' => 'Freetype',
10477+ #'' => 'GCCXML',
10478+ #'' => 'GDAL',
10479+ #'' => 'Gettext',
10480+ #'' => 'GIF',
10481+ #'' => 'Git',
10482+ #'' => 'GLU',
10483+ #'' => 'GLUT',
10484+ #'' => 'Gnuplot',
10485+ #'' => 'GnuTLS',
10486+ #'' => 'GTest',
10487+ #'' => 'GTK',
10488+ #'' => 'GTK2',
10489+ #'' => 'HDF5',
10490+ #'' => 'HSPELL',
10491+ #'' => 'HTMLHelp',
10492+ #'' => 'ImageMagick',
10493+ #'' => 'ITK',
10494+ #'' => 'Jasper',
10495+ #'' => 'Java',
10496+ #'' => 'JNI',
10497+ #'' => 'JPEG',
10498+ #'' => 'KDE3',
10499+ #'' => 'KDE4',
10500+ #'' => 'LAPACK',
10501+ #'' => 'LATEX',
10502+ #'' => 'LibArchive',
10503+ #'' => 'LibLZMA',
10504+ #'' => 'LibXml2',
10505+ #'' => 'LibXslt',
10506+ #'' => 'Lua50',
10507+ #'' => 'Lua51',
10508+ #'' => 'Matlab',
10509+ #'' => 'MFC',
10510+ #'' => 'Motif',
10511+ #'' => 'MPEG',
10512+ #'' => 'MPEG2',
10513+ #'' => 'MPI',
10514+ #'' => 'OpenAL',
10515+ #'' => 'OpenGL',
10516+ #'' => 'OpenMP',
10517+ #'' => 'OpenSceneGraph',
10518+ 'openssl/' => 'OpenSSL',
10519+ #'' => 'OpenThreads',
10520+ #'' => 'osg',
10521+ #'' => 'osgAnimation',
10522+ #'' => 'osgDB',
10523+ #'' => 'osgFX',
10524+ #'' => 'osgGA',
10525+ #'' => 'osgIntrospection',
10526+ #'' => 'osgManipulator',
10527+ #'' => 'osgParticle',
10528+ #'' => 'osgPresentation',
10529+ #'' => 'osgProducer',
10530+ #'' => 'osgQt',
10531+ #'' => 'osgShadow',
10532+ #'' => 'osgSim',
10533+ #'' => 'osgTerrain',
10534+ #'' => 'osgText',
10535+ #'' => 'osgUtil',
10536+ #'' => 'osgViewer',
10537+ #'' => 'osgVolume',
10538+ #'' => 'osgWidget',
10539+ #'' => 'osg_functions',
10540+ #'' => 'PackageHandleStandardArgs',
10541+ #'' => 'PackageMessage',
10542+ #'' => 'Perl',
10543+ #'' => 'PerlLibs',
10544+ #'' => 'PHP4',
10545+ #'' => 'PhysFS',
10546+ #'' => 'Pike',
10547+ #'' => 'PkgConfig',
10548+ #'' => 'PNG',
10549+ #'' => 'PostgreSQL',
10550+ #'' => 'Producer',
10551+ #'' => 'Protobuf',
10552+ #'' => 'PythonInterp',
10553+ #'' => 'PythonLibs',
10554+ #'' => 'Qt',
10555+ #'' => 'Qt3',
10556+ #'' => 'Qt4',
10557+ #'' => 'QuickTime',
10558+ #'' => 'RTI',
10559+ #'' => 'Ruby',
10560+ 'SDL/' => 'SDL',
10561+ #'' => 'SDL_image',
10562+ #'' => 'SDL_mixer',
10563+ #'' => 'SDL_net',
10564+ #'' => 'SDL_sound',
10565+ #'' => 'SDL_ttf',
10566+ #'' => 'SelfPackers',
10567+ #'' => 'Squish',
10568+ #'' => 'Subversion',
10569+ #'' => 'SWIG',
10570+ #'' => 'TCL',
10571+ #'' => 'Tclsh',
10572+ #'' => 'TclStub',
10573+ #'' => 'Threads',
10574+ #'' => 'TIFF',
10575+ #'' => 'UnixCommands',
10576+ #'' => 'VTK',
10577+ #'' => 'Wget',
10578+ #'' => 'Wish',
10579+ #'' => 'wxWidgets',
10580+ #'' => 'wxWindows',
10581+ #'' => 'X11',
10582+ 'xercesc' => 'XercesC',
10583+ #'' => 'XMLRPC',
10584+ 'zlib.h' => 'ZLIB',
10585+ );
10586+ my $rendered_find_packages = '';
10587+
10588+ # find all libs that used
10589+ my @libs_to_find_patterns = keys(%find_packages_supported_by_cmake);
10590+ my @libs;
10591+ for my $file (@srcs) {
10592+ # find libs that the file uses
10593+ open my $info, $file or die "Could not open $file: $!";
10594+ while( my $line = <$info>) {
10595+ if ($line =~ /#\s*include/) {
10596+ my @lib_pattern_indexes_to_delete;
10597+
10598+ for my $lib_match (@libs_to_find_patterns) {
10599+ if ($line =~ m/^\s*#\s*include\s*<$lib_match/) {
10600+ my $lib = $find_packages_supported_by_cmake{$lib_match};
10601+ push @libs, $lib;
10602+
10603+ my $lib_index = 0;
10604+ $lib_index++ until $libs_to_find_patterns[$lib_index] eq $lib_match;
10605+ push @lib_pattern_indexes_to_delete, $lib_index;
10606+ }
10607+ }
10608+
10609+ for my $index (@lib_pattern_indexes_to_delete) {
10610+ splice(@libs_to_find_patterns, $index, 1);
10611+ }
10612+ }
10613+ }
10614+ close $info;
10615+ }
10616+
10617+ for my $lib (@libs) {
10618+ my %vars = (
10619+ package => $lib,
10620+ package_upcase => uc $lib,
10621+ );
10622+ warn Dumper(%vars);
10623+
10624+ try {
10625+ my $render = $tx->render( 'CMakeFindPackage.tx', \%vars );
10626+ $rendered_find_packages = $rendered_find_packages . $render;
10627+ } catch {
10628+ print "caught error: $_\n";
10629+ };
10630+ }
10631+
10632+ return Text::Xslate::Util::mark_raw($rendered_find_packages);
10633+}
10634+
10635+sub render_source_groups {
10636+ my ($tx, %filters) = @_;
10637+
10638+ my $rendered_source_groups = '';
10639+ for my $filter (keys %filters) {
10640+ my @files = @{$filters{$filter}};
10641+ $filter =~ s/\\/\\\\/g;
10642+ my %vars = (
10643+ flter => $filter,
10644+ files => +(join "\n\t", @files),
10645+ );
10646+ warn Dumper(%vars);
10647+
10648+ try {
10649+ my $render = $tx->render( 'CMakeSourceGroup.tx', \%vars );
10650+ $rendered_source_groups = $rendered_source_groups . $render;
10651+ } catch {
10652+ print "caught error: $_\n";
10653+ };
10654+ }
10655+
10656+ return Text::Xslate::Util::mark_raw($rendered_source_groups);
10657+}
10658+
10659+sub make {
10660+ my ($filenode_ref, $item_def_ref, %filters) = @_;
10661+
10662+ my @srcs = @{$filenode_ref->{ClCompile}};
10663+ my @headers = @{$filenode_ref->{ClInclude}};
10664+ my $add_dir = $item_def_ref->{ClCompile}->{AdditionalIncludeDirectories};
10665+ $add_dir =~ s{\\}{/}g;
10666+ my @includes =
10667+ grep { $_ ne '%(AdditionalIncludeDirectories)' }
10668+ split ';', $add_dir;
10669+
10670+ my $def = $item_def_ref->{ClCompile}->{PreprocessorDefinitions};
10671+ # add prefix -D. example> -DSHP
10672+ my @defs =
10673+ map { "-D$_"; }
10674+ grep { $_ ne '%(PreprocessorDefinitions)' }
10675+ split ';', $def;
10676+
10677+ my $add_dep = $item_def_ref->{Link}->{AdditionalDependencies};
10678+ $add_dep =~ s{\\}{/}g;
10679+ my @deps =
10680+ grep { $_ ne '%(AdditionalDependencies)' }
10681+ split ';', $add_dep;
10682+
10683+ warn Dumper(@includes);
10684+
10685+ my $tx = Text::Xslate->new(
10686+ syntax => 'TTerse',
10687+ path => [ '.', '.' ],
10688+ );
10689+
10690+ my $rendered_find_packages = render_find_packages($tx, @headers, @srcs);
10691+ my $rendered_source_groups = render_source_groups($tx, %filters);
10692+
10693+ my %vars = (
10694+ type => $target_prop->{ConfigurationType},
10695+ charset => $target_prop->{CharacterSet},
10696+ target => $target,
10697+ def => +(join "\n\t", @defs),
10698+ lib => +(join "\n\t", @deps),
10699+ include => +(join "\n\t", @includes),
10700+ src => +(join "\n\t", @srcs),
10701+ header => +(join "\n\t", @headers),
10702+ source_groups => $rendered_source_groups,
10703+ find_packages => $rendered_find_packages,
10704+ );
10705+
10706+ warn Dumper(%vars);
10707+
10708+ my $render_text;
10709+ try {
10710+ $render_text = $tx->render( 'CMakeLists.tx', \%vars );
10711+ } catch {
10712+ print "caught error: $_\n";
10713+ };
10714+
10715+ open my $cmakelists_file, '>', 'CMakeLists.txt';
10716+ print {$cmakelists_file} $render_text;
10717+}
10718diff --git a/PMDCamera.cpp b/PMDCamera.cpp
10719index 97d3929..ef8b32c 100644
10720--- a/PMDCamera.cpp
10721+++ b/PMDCamera.cpp
10722@@ -1,186 +1,159 @@
10723-#include "PMDCamera.h"
10724-
10725-/***
10726-Private constructor for the PMD depth sensor
10727-***/
10728-PMDCamera::PMDCamera(bool use_live_sensor)
10729-{
10730- CONFIDENCE_THRESHHOLD = (60.0f / 255.0f*500.0f);
10731- INVALID_FLAG_VALUE = PMD_FLAG_INVALID;
10732- X_DIMENSION = 176;
10733- Y_DIMENSION = 120;
10734-
10735- if (!use_live_sensor) {
10736- return;
10737- }
10738-
10739- int res;
10740- std::cout << "Trying to open pmd\n";
10741- res = pmdOpen(&hnd, SOURCE_PLUGIN, SOURCE_PARAM, PROC_PLUGIN, PROC_PARAM); //Open the PMD sensor
10742- if (res != PMD_OK)
10743- {
10744- pmdGetLastError(0, err, 128);
10745- fprintf(stderr, "Could not connect: %s\n", err);
10746- return;
10747- }
10748- printf("opened sensor\n");
10749-
10750- // Updating the sensor is necessary before any data can be retrieved
10751- res = pmdUpdate(hnd);
10752- if (res != PMD_OK)
10753- {
10754- pmdGetLastError(hnd, err, 128);
10755- fprintf(stderr, "Couldn't transfer data: %s\n", err);
10756- pmdClose(hnd);
10757- return;
10758- }
10759- printf("acquired image\n");
10760-
10761- // res: Structure which contains various meta-information about the data delivered by your Nano.
10762- // It is advisabe to always use the data delivered by this struct (for example the width and height of the imager
10763- // and the image format). Please refer to the PMSDSK documentation for more information
10764- res = pmdGetSourceDataDescription(hnd, &dd);
10765- if (res != PMD_OK)
10766- {
10767- pmdGetLastError(hnd, err, 128);
10768- fprintf(stderr, "Couldn't get data description: %s\n", err);
10769- pmdClose(hnd);
10770- return;
10771- }
10772-
10773- printf("retrieved source data description\n");
10774- if (dd.subHeaderType != PMD_IMAGE_DATA)
10775- {
10776- fprintf(stderr, "Source data is not an image!\n");
10777- pmdClose(hnd);
10778- return;
10779- }
10780-
10781- numPixels = dd.img.numRows * dd.img.numColumns; // Number of pixels in camera
10782- dists = new float[3 * numPixels]; // Dists contains XYZ values. needs to be 3x the size of numPixels
10783- amps = new float[numPixels];
10784- frame.create(dd.img.numRows, dd.img.numColumns, CV_8UC3);
10785-
10786- KF.init(6, 3, 0);
10787- KF.transitionMatrix = (cv::Mat_<float>(6, 6) << 1, 0, 0, 1, 0, 0,
10788- 0, 1, 0, 0, 1, 0,
10789- 0, 0, 1, 0, 0, 1,
10790- 0, 0, 0, 1, 0, 0,
10791- 0, 0, 0, 0, 1, 0,
10792- 0, 0, 0, 0, 0, 1);
10793- measurement = cv::Mat_<float>::zeros(3, 1);
10794-
10795- //Initaite Kalman
10796- KF.statePre.setTo(0);
10797- setIdentity(KF.measurementMatrix);
10798- setIdentity(KF.processNoiseCov, cv::Scalar::all(.001)); // Adjust this for faster convergence - but higher noise
10799- setIdentity(KF.measurementNoiseCov, cv::Scalar::all(1e-1));
10800- setIdentity(KF.errorCovPost, cv::Scalar::all(.1));
10801-
10802-}
10803-
10804-/***
10805-Public deconstructor for he PMD depth sensor
10806-***/
10807-PMDCamera::~PMDCamera() {}
10808-
10809-void PMDCamera::destroyInstance()
10810-{
10811- printf("closing sensor\n");
10812- pmdClose(hnd);
10813- printf("sensor closed\n");
10814-}
10815-
10816-/***
10817-Create xyzMap, zMap, ampMap, and flagMap from sensor input
10818-***/
10819-void PMDCamera::update()
10820-{
10821- initilizeImages();
10822-
10823- fillInAmps();
10824- fillInZCoords();
10825- // Flags. Helps with denoising.
10826-
10827- unsigned *flags = new unsigned[ampMap.cols*ampMap.rows];
10828- int res = pmdGetFlags(hnd, flags, numPixels * sizeof(unsigned));
10829- if (res != PMD_OK) {
10830- pmdGetLastError(hnd, err, 128);
10831- fprintf(stderr, "Couldn't get the flags: %s\n", err);
10832- pmdClose(hnd);
10833- return;
10834- }
10835- flagMap.data = (uchar *)flags;
10836-
10837- res = pmdUpdate(hnd);
10838- if (res != PMD_OK) {
10839- pmdGetLastError(hnd, err, 128);
10840- fprintf(stderr, "Couldn't update the PMD camera: %s\n", err);
10841- pmdClose(hnd);
10842- return;
10843- }
10844- delete(flags);
10845-
10846-}
10847-
10848-
10849-/***
10850-Reads the depth data from the sensor and fills in the matrix
10851-***/
10852-void PMDCamera::fillInZCoords()
10853-{
10854- int res = pmdGet3DCoordinates(hnd, dists, 3 * numPixels * sizeof(float)); //store x,y,z coordinates dists (type: float*)
10855- //float * zCoords = new float[1]; //store z-Coordinates of dists in zCoords
10856- if (res != PMD_OK) {
10857- pmdGetLastError(hnd, err, 128);
10858- fprintf(stderr, "Couldn't get 3D coordinates: %s\n", err);
10859- pmdClose(hnd);
10860- return;
10861- }
10862- xyzMap = cv::Mat(xyzMap.size(), xyzMap.type(), dists);
10863- //std::cout << "nrows: " << xyzMap.rows << std::endl;
10864- //std::cout << "ncols: " << xyzMap.cols << std::endl;
10865-}
10866-
10867-/***
10868-Reads the amplitude data from the sensor and fills in the matrix
10869-***/
10870-void PMDCamera::fillInAmps()
10871-{
10872- int res = pmdGetAmplitudes(hnd, amps, numPixels * sizeof(float));
10873- //float * dataPtr = amps;
10874- if (res != PMD_OK) {
10875- pmdGetLastError(hnd, err, 128);
10876- fprintf(stderr, "Couldn't get amplitudes: %s\n", err);
10877- pmdClose(hnd);
10878- return;
10879- }
10880- ampMap.data = (uchar *)amps;
10881-}
10882-
10883-/***
10884-Returns the X value at (i, j)
10885-***/
10886-float PMDCamera::getX(int i, int j) const
10887-{
10888- int flat = j * dd.img.numColumns * 3 + i * 3;
10889- return dists[flat];
10890-}
10891-
10892-/***
10893-Returns the Y value at (i, j)
10894-***/
10895-float PMDCamera::getY(int i, int j) const
10896-{
10897- int flat = j * dd.img.numColumns * 3 + i * 3;
10898- return dists[flat + 1];
10899-}
10900-
10901-/***
10902-Returns the Z value at (i, j)
10903-***/
10904-float PMDCamera::getZ(int i, int j) const
10905-{
10906- int flat = j * dd.img.numColumns * 3 + i * 3;
10907- return dists[flat + 2];
10908+#include "PMDCamera.h"
10909+
10910+/***
10911+Private constructor for the PMD depth sensor
10912+***/
10913+PMDCamera::PMDCamera(bool use_live_sensor)
10914+{
10915+ CONFIDENCE_THRESHHOLD = (60.0f / 255.0f*500.0f);
10916+ INVALID_FLAG_VALUE = PMD_FLAG_INVALID;
10917+ X_DIMENSION = 176;
10918+ Y_DIMENSION = 120;
10919+
10920+ if (!use_live_sensor) {
10921+ return;
10922+ }
10923+
10924+ int res;
10925+ std::cout << "Trying to open pmd\n";
10926+ res = pmdOpen(&hnd, SOURCE_PLUGIN, SOURCE_PARAM, PROC_PLUGIN, PROC_PARAM); //Open the PMD sensor
10927+ if (res != PMD_OK)
10928+ {
10929+ pmdGetLastError(0, err, 128);
10930+ fprintf(stderr, "Could not connect: %s\n", err);
10931+ return;
10932+ }
10933+ printf("opened sensor\n");
10934+
10935+ // Updating the sensor is necessary before any data can be retrieved
10936+ res = pmdUpdate(hnd);
10937+ if (res != PMD_OK)
10938+ {
10939+ pmdGetLastError(hnd, err, 128);
10940+ fprintf(stderr, "Couldn't transfer data: %s\n", err);
10941+ pmdClose(hnd);
10942+ return;
10943+ }
10944+ printf("acquired image\n");
10945+
10946+ // res: Structure which contains various meta-information about the data delivered by your Nano.
10947+ // It is advisabe to always use the data delivered by this struct (for example the width and height of the imager
10948+ // and the image format). Please refer to the PMSDSK documentation for more information
10949+ res = pmdGetSourceDataDescription(hnd, &dd);
10950+ if (res != PMD_OK)
10951+ {
10952+ pmdGetLastError(hnd, err, 128);
10953+ fprintf(stderr, "Couldn't get data description: %s\n", err);
10954+ pmdClose(hnd);
10955+ return;
10956+ }
10957+
10958+ printf("retrieved source data description\n");
10959+ if (dd.subHeaderType != PMD_IMAGE_DATA)
10960+ {
10961+ fprintf(stderr, "Source data is not an image!\n");
10962+ pmdClose(hnd);
10963+ return;
10964+ }
10965+
10966+ numPixels = dd.img.numRows * dd.img.numColumns; // Number of pixels in camera
10967+ dists = new float[3 * numPixels]; // Dists contains XYZ values. needs to be 3x the size of numPixels
10968+ amps = new float[numPixels];
10969+ frame = cvCreateImage(cvSize(dd.img.numColumns, dd.img.numRows), 8, 3); // Create the frame
10970+
10971+ KF.init(6, 3, 0);
10972+ KF.transitionMatrix = (cv::Mat_<float>(6, 6) << 1, 0, 0, 1, 0, 0,
10973+ 0, 1, 0, 0, 1, 0,
10974+ 0, 0, 1, 0, 0, 1,
10975+ 0, 0, 0, 1, 0, 0,
10976+ 0, 0, 0, 0, 1, 0,
10977+ 0, 0, 0, 0, 0, 1);
10978+ measurement = cv::Mat_<float>::zeros(3, 1);
10979+
10980+ //Initaite Kalman
10981+ KF.statePre.setTo(0);
10982+ setIdentity(KF.measurementMatrix);
10983+ setIdentity(KF.processNoiseCov, cv::Scalar::all(.001)); // Adjust this for faster convergence - but higher noise
10984+ setIdentity(KF.measurementNoiseCov, cv::Scalar::all(1e-1));
10985+ setIdentity(KF.errorCovPost, cv::Scalar::all(.1));
10986+}
10987+
10988+/***
10989+Public deconstructor for he PMD depth sensor
10990+***/
10991+PMDCamera::~PMDCamera() {}
10992+
10993+void PMDCamera::destroyInstance()
10994+{
10995+ printf("closing sensor\n");
10996+ pmdClose(hnd);
10997+ printf("sensor closed\n");
10998+}
10999+
11000+/***
11001+Create xyzMap, zMap, ampMap, and flagMap from sensor input
11002+***/
11003+void PMDCamera::update()
11004+{
11005+ initilizeImages();
11006+
11007+ fillInAmps();
11008+ fillInZCoords();
11009+ // Flags. Helps with denoising.
11010+
11011+ unsigned *flags = new unsigned[ampMap.cols*ampMap.rows];
11012+ int res = pmdGetFlags(hnd, flags, numPixels * sizeof(unsigned));
11013+ flagMap.data = (uchar *)flags;
11014+
11015+ pmdUpdate(hnd);
11016+ delete(flags);
11017+
11018+}
11019+
11020+
11021+/***
11022+Reads the depth data from the sensor and fills in the matrix
11023+***/
11024+void PMDCamera::fillInZCoords()
11025+{
11026+ int res = pmdGet3DCoordinates(hnd, dists, 3 * numPixels * sizeof(float)); //store x,y,z coordinates dists (type: float*)
11027+ //float * zCoords = new float[1]; //store z-Coordinates of dists in zCoords
11028+ xyzMap = cv::Mat(xyzMap.size(), xyzMap.type(), dists);
11029+}
11030+
11031+/***
11032+Reads the amplitude data from the sensor and fills in the matrix
11033+***/
11034+void PMDCamera::fillInAmps()
11035+{
11036+ int res = pmdGetAmplitudes(hnd, amps, numPixels * sizeof(float));
11037+ //float * dataPtr = amps;
11038+ ampMap.data = (uchar *)amps;
11039+}
11040+
11041+/***
11042+Returns the X value at (i, j)
11043+***/
11044+float PMDCamera::getX(int i, int j) const
11045+{
11046+ int flat = j * dd.img.numColumns * 3 + i * 3;
11047+ return dists[flat];
11048+}
11049+
11050+/***
11051+Returns the Y value at (i, j)
11052+***/
11053+float PMDCamera::getY(int i, int j) const
11054+{
11055+ int flat = j * dd.img.numColumns * 3 + i * 3;
11056+ return dists[flat + 1];
11057+}
11058+
11059+/***
11060+Returns the Z value at (i, j)
11061+***/
11062+float PMDCamera::getZ(int i, int j) const
11063+{
11064+ int flat = j * dd.img.numColumns * 3 + i * 3;
11065+ return dists[flat + 2];
11066 }
11067\ No newline at end of file
11068diff --git a/PMDCamera.h b/PMDCamera.h
11069index d4930fc..373c1f3 100644
11070--- a/PMDCamera.h
11071+++ b/PMDCamera.h
11072@@ -1,107 +1,107 @@
11073-#pragma once
11074-// C++ Libraries
11075-#include<string.h>
11076-
11077-// PMD Libraries
11078-#include <pmdsdk2.h>
11079-
11080-// OpenCV Libraries
11081-#include <opencv/cxcore.h>
11082-#include <opencv/highgui.h>
11083-#include "opencv2/highgui/highgui.hpp"
11084-#include <opencv2/video/tracking.hpp>
11085-#include "opencv2/imgproc/imgproc.hpp"
11086-#include <opencv2/objdetect/objdetect.hpp>
11087-#include <opencv2/features2d/features2d.hpp>
11088-
11089-// OpenARK Libraries
11090-#include "DepthCamera.h"
11091-
11092-/**
11093-* Class defining the behavior of a PMD Camera.
11094-* Example on how to read from sensor and visualize its output
11095-* @include SensorIO.cpp
11096-*/
11097-class PMDCamera : public DepthCamera
11098-{
11099-public:
11100- /**
11101- * Public constructor initializing the PMD Camera.
11102- * @param use_live_sensor uses input from real sensor if TRUE. Otherwise reads from input file. Default is set to TRUE.
11103- */
11104- PMDCamera(bool use_live_sensor = true);
11105-
11106- /**
11107- * Deconstructor for the PMD Camera.
11108- */
11109- ~PMDCamera();
11110-
11111- /**
11112- * Gets new frame from sensor.
11113- * Updates xyzMap, ampMap, and flagMap. Resets clusters.
11114- */
11115- void update();
11116-
11117- /**
11118- * Gracefully closes the PMD camera.
11119- */
11120- void destroyInstance();
11121-
11122-private:
11123- /**
11124- * Getter method for the x-coordinate at (i,j).
11125- * @param i ith row
11126- * @param j jth column
11127- * @return x-coodinate at (i,j)
11128- */
11129- float getX(int i, int j) const;
11130-
11131- /**
11132- * Getter method for the x-coordinate at (i,j).
11133- * @param i ith row
11134- * @param j jth column
11135- * @return x-coodinate at (i,j)
11136- */
11137- float getY(int i, int j) const;
11138-
11139- /**
11140- * Getter method for the x-coordinate at (i,j).
11141- * @param i ith row
11142- * @param j jth column
11143- * @return x-coodinate at (i,j)
11144- */
11145- float getZ(int i, int j) const;
11146-
11147- /**
11148- * Update the z-coordinates of the xyzMap.
11149- */
11150- void fillInZCoords();
11151-
11152- /**
11153- * Update the values in the ampMap.
11154- */
11155- void fillInAmps();
11156-
11157- //Private Variable
11158- const char* SOURCE_PLUGIN = "camboardpico";
11159- const char* SOURCE_PARAM = "";
11160- const char* PROC_PLUGIN = "camboardpicoproc";
11161- const char* PROC_PARAM = "";
11162-
11163- PMDHandle hnd;
11164- PMDDataDescription dd;
11165- char err[128]; // Char array for storing PMD's error log
11166-
11167- int numPixels;
11168- float* dists;
11169- float* amps;
11170-
11171- cv::Mat frame;
11172- cv::KalmanFilter KF;
11173- cv::Mat_<float> measurement;
11174-};
11175-
11176-/*
11177-* \include SensorIO.cpp
11178-* Example of how to read from sensor
11179+#pragma once
11180+// C++ Libraries
11181+#include<string.h>
11182+
11183+// PMD Libraries
11184+#include <pmdsdk2.h>
11185+
11186+// OpenCV Libraries
11187+#include <opencv/cxcore.h>
11188+#include <opencv/highgui.h>
11189+#include "opencv2/highgui/highgui.hpp"
11190+#include <opencv2/video/tracking.hpp>
11191+#include "opencv2/imgproc/imgproc.hpp"
11192+#include <opencv2/objdetect/objdetect.hpp>
11193+#include <opencv2/features2d/features2d.hpp>
11194+
11195+// OpenARK Libraries
11196+#include "DepthCamera.h"
11197+
11198+/**
11199+* Class defining the behavior of a PMD Camera.
11200+* Example on how to read from sensor and visualize its output
11201+* @include SensorIO.cpp
11202+*/
11203+class PMDCamera : public DepthCamera
11204+{
11205+public:
11206+ /**
11207+ * Public constructor initializing the PMD Camera.
11208+ * @param use_live_sensor uses input from real sensor if TRUE. Otherwise reads from input file. Default is set to TRUE.
11209+ */
11210+ PMDCamera(bool use_live_sensor = true);
11211+
11212+ /**
11213+ * Deconstructor for the PMD Camera.
11214+ */
11215+ ~PMDCamera();
11216+
11217+ /**
11218+ * Gets new frame from sensor.
11219+ * Updates xyzMap, ampMap, and flagMap. Resets clusters.
11220+ */
11221+ void update();
11222+
11223+ /**
11224+ * Gracefully closes the PMD camera.
11225+ */
11226+ void destroyInstance();
11227+
11228+private:
11229+ /**
11230+ * Getter method for the x-coordinate at (i,j).
11231+ * @param i ith row
11232+ * @param j jth column
11233+ * @return x-coodinate at (i,j)
11234+ */
11235+ float getX(int i, int j) const;
11236+
11237+ /**
11238+ * Getter method for the x-coordinate at (i,j).
11239+ * @param i ith row
11240+ * @param j jth column
11241+ * @return x-coodinate at (i,j)
11242+ */
11243+ float getY(int i, int j) const;
11244+
11245+ /**
11246+ * Getter method for the x-coordinate at (i,j).
11247+ * @param i ith row
11248+ * @param j jth column
11249+ * @return x-coodinate at (i,j)
11250+ */
11251+ float getZ(int i, int j) const;
11252+
11253+ /**
11254+ * Update the z-coordinates of the xyzMap.
11255+ */
11256+ void fillInZCoords();
11257+
11258+ /**
11259+ * Update the values in the ampMap.
11260+ */
11261+ void fillInAmps();
11262+
11263+ //Private Variable
11264+ const char* SOURCE_PLUGIN = "camboardpico";
11265+ const char* SOURCE_PARAM = "";
11266+ const char* PROC_PLUGIN = "camboardpicoproc";
11267+ const char* PROC_PARAM = "";
11268+
11269+ PMDHandle hnd;
11270+ PMDDataDescription dd;
11271+ char err[128]; // Char array for storing PMD's error log
11272+
11273+ int numPixels;
11274+ float* dists;
11275+ float* amps;
11276+
11277+ IplImage * frame;
11278+ cv::KalmanFilter KF;
11279+ cv::Mat_<float> measurement;
11280+};
11281+
11282+/*
11283+* \include SensorIO.cpp
11284+* Example of how to read from sensor
11285 */
11286\ No newline at end of file
11287diff --git a/Plane.cpp b/Plane.cpp
11288index e21a5fb..370135d 100644
11289--- a/Plane.cpp
11290+++ b/Plane.cpp
11291@@ -1,276 +1,276 @@
11292-#include "Plane.h"
11293-
11294-Plane::Plane()
11295-{
11296-
11297-}
11298-
11299-Plane::Plane(cv::Mat &src)
11300-{
11301- // Initialize Variables
11302- cloud = new pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud <pcl::PointXYZ>);
11303- normals = new pcl::PointCloud <pcl::Normal>::Ptr(new pcl::PointCloud <pcl::Normal>);
11304- down_cloud = new pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
11305- down_normals = new pcl::PointCloud<pcl::Normal>::Ptr(new pcl::PointCloud<pcl::Normal>);
11306- upsampled_colored_cloud = new pcl::PointCloud<pcl::PointXYZRGB>::Ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
11307-
11308- initializeCloud(src);
11309-
11310- if (cloud->get()->width < CLOUD_SIZE_THRESHOLD) {
11311- return;
11312- }
11313-
11314- compute();
11315-}
11316-
11317-Plane::~Plane() {
11318-}
11319-
11320-int Plane::compute()
11321-{
11322- voxelDownsample();
11323-
11324- // calculate normals
11325- pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> normal_estimator;
11326- pcl::search::Search<pcl::PointXYZ>::Ptr tree
11327- = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> >(new pcl::search::KdTree<pcl::PointXYZ>);
11328- calculateNormals(normal_estimator, tree);
11329-
11330- // region grow with normals
11331- pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
11332- regionGrow(reg, tree);
11333-
11334- // find index of dominant plane
11335- int index_max = -1;
11336- for (int i = 0; i < clusters.size(); i++) {
11337- if (index_max == -1 || clusters[i].indices.size() > clusters[index_max].indices.size()) {
11338- index_max = i;
11339- }
11340- }
11341- if (index_max == -1) {
11342- return -1;
11343- }
11344-
11345- computePlaneLSE(clusters[index_max]);
11346- computeSphereLSE(clusters[index_max]);
11347-
11348- num_plane_points = computePlaneIndices();
11349- num_sphere_points = computeSphereIndices();
11350-
11351- return 0;
11352-}
11353-
11354-void Plane::computePlaneLSE(pcl::PointIndices &ind)
11355-{
11356- Eigen::MatrixXd A(ind.indices.size(), 3);
11357- Eigen::MatrixXd b(ind.indices.size(), 1);
11358-
11359- for (int i = 0; i < ind.indices.size(); i++) {
11360- int index = ind.indices[i];
11361- A(i, 0) = down_cloud->get()->points[index].x;
11362- A(i, 1) = down_cloud->get()->points[index].y;
11363- A(i, 2) = 1;
11364- b(i, 0) = down_cloud->get()->points[index].z;
11365- }
11366-
11367- Eigen::MatrixXd mul = A.transpose() * A;
11368- Eigen::MatrixXd inv = mul.inverse();
11369- Eigen::MatrixXd b_hat = A.transpose() * b;
11370- Eigen::MatrixXd vals = inv * b_hat;
11371-
11372- plane_equation.clear();
11373- plane_equation.resize(3);
11374- plane_equation[0] = vals(0, 0);
11375- plane_equation[1] = vals(1, 0);
11376- plane_equation[2] = vals(2, 0);
11377-}
11378-
11379-void Plane::computeSphereLSE( pcl::PointIndices &ind)
11380-{
11381- Eigen::MatrixXd A(ind.indices.size(), 4);
11382- Eigen::MatrixXd b(ind.indices.size(), 1);
11383-
11384- for (int i = 0; i < ind.indices.size(); i++) {
11385- int index = ind.indices[i];
11386- A(i, 0) = 1;
11387- A(i, 1) = down_cloud->get()->points[index].x;
11388- A(i, 2) = down_cloud->get()->points[index].y;
11389- A(i, 3) = down_cloud->get()->points[index].z;
11390- b(i, 0) = down_cloud->get()->points[index].x * down_cloud->get()->points[index].x +
11391- down_cloud->get()->points[index].y * down_cloud->get()->points[index].y +
11392- down_cloud->get()->points[index].z * down_cloud->get()->points[index].z;
11393- }
11394-
11395- Eigen::MatrixXd mul = A.transpose() * A;
11396- Eigen::MatrixXd inv = mul.inverse();
11397- Eigen::MatrixXd b_hat = A.transpose() * b;
11398- Eigen::MatrixXd vals = inv * b_hat;
11399-
11400- double a0 = vals(0, 0);
11401- double coef_a = vals(1, 0) / 2;
11402- double coef_b = vals(2, 0) / 2;
11403- double coef_c = vals(3, 0) / 2;
11404- double radius = sqrt(a0 + coef_a * coef_a + coef_b * coef_b + coef_c * coef_c);
11405-
11406- sphere_equation.clear();
11407- sphere_equation.resize(4);
11408- sphere_equation[0] = coef_a;
11409- sphere_equation[1] = coef_b;
11410- sphere_equation[2] = coef_c;
11411- sphere_equation[3] = radius;
11412-}
11413-
11414-int Plane::computePlaneIndices()
11415-{
11416- int rowSize = depth_img.rows;
11417- int colSize = depth_img.cols;
11418- plane_indices.clear();
11419- int num_points_detected = 0;
11420- for (int r = 0; r < rowSize; r++) {
11421- for (int c = 0; c < colSize; c++) {
11422- double x = depth_img.at<cv::Vec3f>(r, c)[0];
11423- double y = depth_img.at<cv::Vec3f>(r, c)[1];
11424- double z = depth_img.at<cv::Vec3f>(r, c)[2];
11425-
11426- if (z > 0) {
11427- double z_hat = plane_equation[0] * x + plane_equation[1] * y + plane_equation[2];
11428- double r_squared = (z - z_hat) * (z - z_hat);
11429-
11430- if (r_squared < R_SQUARED_DISTANCE_THRESHOLD) {
11431- plane_indices.push_back(cv::Point2i(c, r));
11432- num_points_detected++;
11433- }
11434- }
11435- }
11436- }
11437- return num_points_detected;
11438-}
11439-
11440-int Plane::computeSphereIndices()
11441-{
11442- int rowSize = depth_img.rows;
11443- int colSize = depth_img.cols;
11444- sphere_indices.clear();
11445- int pointsDetected = 0;
11446- for (int r = 0; r < rowSize; r++) {
11447- for (int c = 0; c < colSize; c++) {
11448- double x = depth_img.at<cv::Vec3f>(r, c)[0];
11449- double y = depth_img.at<cv::Vec3f>(r, c)[1];
11450- double z = depth_img.at<cv::Vec3f>(r, c)[2];
11451-
11452- if (z > 0) {
11453- double radius = sqrt((x - sphere_equation[0]) * (x - sphere_equation[0])
11454- + (y - sphere_equation[1]) * (y - sphere_equation[1])
11455- + (z - sphere_equation[2]) * (z - sphere_equation[2]));
11456- double radial_r_squared = (radius - sphere_equation[3]) * (radius - sphere_equation[3]);
11457-
11458- if (radial_r_squared < R_SQUARED_DISTANCE_THRESHOLD) {
11459- sphere_indices.push_back(cv::Point2i(c, r));
11460- pointsDetected++;
11461- }
11462- }
11463- }
11464- }
11465- return pointsDetected;
11466-}
11467-
11468-void Plane::regionGrow(pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> ®, pcl::search::Search<pcl::PointXYZ>::Ptr tree)
11469-{
11470- if (down_cloud->get()->width < 100 && down_normals->get()->width < 100) {
11471- return;
11472- }
11473-
11474- reg.setMinClusterSize(20);
11475- reg.setMaxClusterSize(1000000);
11476- reg.setSearchMethod(tree);
11477- reg.setNumberOfNeighbours(30);
11478- reg.setInputCloud(*down_cloud);
11479- reg.setInputNormals(*down_normals);
11480- reg.setSmoothnessThreshold(3.0 / 180.0 * M_PI);
11481- reg.setCurvatureThreshold(2.5);
11482- reg.extract(clusters);
11483-}
11484-
11485-void Plane::voxelDownsample()
11486-{
11487- pcl::PCLPointCloud2::Ptr temp_cloud(new pcl::PCLPointCloud2());
11488- pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());
11489- pcl::toPCLPointCloud2(*cloud->get(), *temp_cloud);
11490-
11491- pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
11492- sor.setInputCloud(temp_cloud);
11493- sor.setLeafSize(0.01f, 0.01f, 0.01f);
11494- sor.filter(*cloud_filtered);
11495- pcl::fromPCLPointCloud2(*cloud_filtered, *down_cloud->get());
11496-}
11497-
11498-void Plane::calculateNormals(pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> normal_estimator,
11499- pcl::search::Search<pcl::PointXYZ>::Ptr tree)
11500-{
11501- normal_estimator.setNumberOfThreads(NUM_CORES);
11502- normal_estimator.setSearchMethod(tree);
11503- normal_estimator.setInputCloud(*down_cloud);
11504- normal_estimator.setKSearch(50);
11505- normal_estimator.compute(*down_normals->get());
11506-}
11507-
11508-void Plane::initializeCloud(cv::Mat &src)
11509-{
11510- depth_img = src.clone();
11511- int rowSize = src.rows;
11512- int colSize = src.cols;
11513- int cloudSize = 0;
11514- for (size_t r = 0; r < rowSize; r++) {
11515- for (size_t c = 0; c < colSize; c++) {
11516- if (src.at<cv::Vec3f>(r, c)[2] != 0) {
11517- cloudSize++;
11518- }
11519- }
11520- }
11521- cloud->get()->width = cloudSize;
11522- cloud->get()->height = 1;
11523- cloud->get()->points.resize(cloud->get()->width * cloud->get()->height);
11524-
11525- int index = 0;
11526- for (size_t r = 0; r < rowSize; r++) {
11527- for (size_t c = 0; c < colSize; c++) {
11528- if (src.at<cv::Vec3f>(r, c)[2] != 0) {
11529- cloud->get()->points[index].x = src.at<cv::Vec3f>(r, c)[0];
11530- cloud->get()->points[index].y = src.at<cv::Vec3f>(r, c)[1];
11531- cloud->get()->points[index].z = src.at<cv::Vec3f>(r, c)[2];
11532- index++;
11533- }
11534- }
11535- }
11536-
11537-}
11538-
11539-pcl::PointCloud<pcl::PointXYZ>::Ptr Plane::getCloud()
11540-{
11541- return *cloud;
11542-}
11543-
11544-pcl::PointCloud<pcl::PointXYZ>::Ptr Plane::getDownCloud()
11545-{
11546- return *down_cloud;
11547-}
11548-
11549-std::vector<double> Plane::getPlaneEquation()
11550-{
11551- return plane_equation;
11552-}
11553-
11554-std::vector<double> Plane::getSphereEquation()
11555-{
11556- return sphere_equation;
11557-}
11558-
11559-std::vector<cv::Point2i> Plane::getPlaneIndicies()
11560-{
11561- return plane_indices;
11562-}
11563-
11564-std::vector<cv::Point2i> Plane::getSphereIndices()
11565-{
11566- return sphere_indices;
11567+#include "Plane.h"
11568+
11569+Plane::Plane()
11570+{
11571+
11572+}
11573+
11574+Plane::Plane(cv::Mat &src)
11575+{
11576+ // Initialize Variables
11577+ cloud = new pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud <pcl::PointXYZ>);
11578+ normals = new pcl::PointCloud <pcl::Normal>::Ptr(new pcl::PointCloud <pcl::Normal>);
11579+ down_cloud = new pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
11580+ down_normals = new pcl::PointCloud<pcl::Normal>::Ptr(new pcl::PointCloud<pcl::Normal>);
11581+ upsampled_colored_cloud = new pcl::PointCloud<pcl::PointXYZRGB>::Ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
11582+
11583+ initializeCloud(src);
11584+
11585+ if (cloud->get()->width < CLOUD_SIZE_THRESHOLD) {
11586+ return;
11587+ }
11588+
11589+ compute();
11590+}
11591+
11592+Plane::~Plane() {
11593+}
11594+
11595+int Plane::compute()
11596+{
11597+ voxelDownsample();
11598+
11599+ // calculate normals
11600+ pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> normal_estimator;
11601+ pcl::search::Search<pcl::PointXYZ>::Ptr tree
11602+ = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> >(new pcl::search::KdTree<pcl::PointXYZ>);
11603+ calculateNormals(normal_estimator, tree);
11604+
11605+ // region grow with normals
11606+ pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
11607+ regionGrow(reg, tree);
11608+
11609+ // find index of dominant plane
11610+ int index_max = -1;
11611+ for (int i = 0; i < clusters.size(); i++) {
11612+ if (index_max == -1 || clusters[i].indices.size() > clusters[index_max].indices.size()) {
11613+ index_max = i;
11614+ }
11615+ }
11616+ if (index_max == -1) {
11617+ return -1;
11618+ }
11619+
11620+ computePlaneLSE(clusters[index_max]);
11621+ computeSphereLSE(clusters[index_max]);
11622+
11623+ num_plane_points = computePlaneIndices();
11624+ num_sphere_points = computeSphereIndices();
11625+
11626+ return 0;
11627+}
11628+
11629+void Plane::computePlaneLSE(pcl::PointIndices &ind)
11630+{
11631+ Eigen::MatrixXd A(ind.indices.size(), 3);
11632+ Eigen::MatrixXd b(ind.indices.size(), 1);
11633+
11634+ for (int i = 0; i < ind.indices.size(); i++) {
11635+ int index = ind.indices[i];
11636+ A(i, 0) = down_cloud->get()->points[index].x;
11637+ A(i, 1) = down_cloud->get()->points[index].y;
11638+ A(i, 2) = 1;
11639+ b(i, 0) = down_cloud->get()->points[index].z;
11640+ }
11641+
11642+ Eigen::MatrixXd mul = A.transpose() * A;
11643+ Eigen::MatrixXd inv = mul.inverse();
11644+ Eigen::MatrixXd b_hat = A.transpose() * b;
11645+ Eigen::MatrixXd vals = inv * b_hat;
11646+
11647+ plane_equation.clear();
11648+ plane_equation.resize(3);
11649+ plane_equation[0] = vals(0, 0);
11650+ plane_equation[1] = vals(1, 0);
11651+ plane_equation[2] = vals(2, 0);
11652+}
11653+
11654+void Plane::computeSphereLSE( pcl::PointIndices &ind)
11655+{
11656+ Eigen::MatrixXd A(ind.indices.size(), 4);
11657+ Eigen::MatrixXd b(ind.indices.size(), 1);
11658+
11659+ for (int i = 0; i < ind.indices.size(); i++) {
11660+ int index = ind.indices[i];
11661+ A(i, 0) = 1;
11662+ A(i, 1) = down_cloud->get()->points[index].x;
11663+ A(i, 2) = down_cloud->get()->points[index].y;
11664+ A(i, 3) = down_cloud->get()->points[index].z;
11665+ b(i, 0) = down_cloud->get()->points[index].x * down_cloud->get()->points[index].x +
11666+ down_cloud->get()->points[index].y * down_cloud->get()->points[index].y +
11667+ down_cloud->get()->points[index].z * down_cloud->get()->points[index].z;
11668+ }
11669+
11670+ Eigen::MatrixXd mul = A.transpose() * A;
11671+ Eigen::MatrixXd inv = mul.inverse();
11672+ Eigen::MatrixXd b_hat = A.transpose() * b;
11673+ Eigen::MatrixXd vals = inv * b_hat;
11674+
11675+ double a0 = vals(0, 0);
11676+ double coef_a = vals(1, 0) / 2;
11677+ double coef_b = vals(2, 0) / 2;
11678+ double coef_c = vals(3, 0) / 2;
11679+ double radius = sqrt(a0 + coef_a * coef_a + coef_b * coef_b + coef_c * coef_c);
11680+
11681+ sphere_equation.clear();
11682+ sphere_equation.resize(4);
11683+ sphere_equation[0] = coef_a;
11684+ sphere_equation[1] = coef_b;
11685+ sphere_equation[2] = coef_c;
11686+ sphere_equation[3] = radius;
11687+}
11688+
11689+int Plane::computePlaneIndices()
11690+{
11691+ int rowSize = depth_img.rows;
11692+ int colSize = depth_img.cols;
11693+ plane_indices.clear();
11694+ int num_points_detected = 0;
11695+ for (int r = 0; r < rowSize; r++) {
11696+ for (int c = 0; c < colSize; c++) {
11697+ double x = depth_img.at<cv::Vec3f>(r, c)[0];
11698+ double y = depth_img.at<cv::Vec3f>(r, c)[1];
11699+ double z = depth_img.at<cv::Vec3f>(r, c)[2];
11700+
11701+ if (z > 0) {
11702+ double z_hat = plane_equation[0] * x + plane_equation[1] * y + plane_equation[2];
11703+ double r_squared = (z - z_hat) * (z - z_hat);
11704+
11705+ if (r_squared < R_SQUARED_DISTANCE_THRESHOLD) {
11706+ plane_indices.push_back(cv::Point2i(c, r));
11707+ num_points_detected++;
11708+ }
11709+ }
11710+ }
11711+ }
11712+ return num_points_detected;
11713+}
11714+
11715+int Plane::computeSphereIndices()
11716+{
11717+ int rowSize = depth_img.rows;
11718+ int colSize = depth_img.cols;
11719+ sphere_indices.clear();
11720+ int pointsDetected = 0;
11721+ for (int r = 0; r < rowSize; r++) {
11722+ for (int c = 0; c < colSize; c++) {
11723+ double x = depth_img.at<cv::Vec3f>(r, c)[0];
11724+ double y = depth_img.at<cv::Vec3f>(r, c)[1];
11725+ double z = depth_img.at<cv::Vec3f>(r, c)[2];
11726+
11727+ if (z > 0) {
11728+ double radius = sqrt((x - sphere_equation[0]) * (x - sphere_equation[0])
11729+ + (y - sphere_equation[1]) * (y - sphere_equation[1])
11730+ + (z - sphere_equation[2]) * (z - sphere_equation[2]));
11731+ double radial_r_squared = (radius - sphere_equation[3]) * (radius - sphere_equation[3]);
11732+
11733+ if (radial_r_squared < R_SQUARED_DISTANCE_THRESHOLD) {
11734+ sphere_indices.push_back(cv::Point2i(c, r));
11735+ pointsDetected++;
11736+ }
11737+ }
11738+ }
11739+ }
11740+ return pointsDetected;
11741+}
11742+
11743+void Plane::regionGrow(pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> ®, pcl::search::Search<pcl::PointXYZ>::Ptr tree)
11744+{
11745+ if (down_cloud->get()->width < 100 && down_normals->get()->width < 100) {
11746+ return;
11747+ }
11748+
11749+ reg.setMinClusterSize(20);
11750+ reg.setMaxClusterSize(1000000);
11751+ reg.setSearchMethod(tree);
11752+ reg.setNumberOfNeighbours(30);
11753+ reg.setInputCloud(*down_cloud);
11754+ reg.setInputNormals(*down_normals);
11755+ reg.setSmoothnessThreshold(3.0 / 180.0 * M_PI);
11756+ reg.setCurvatureThreshold(2.5);
11757+ reg.extract(clusters);
11758+}
11759+
11760+void Plane::voxelDownsample()
11761+{
11762+ pcl::PCLPointCloud2::Ptr temp_cloud(new pcl::PCLPointCloud2());
11763+ pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());
11764+ pcl::toPCLPointCloud2(*cloud->get(), *temp_cloud);
11765+
11766+ pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
11767+ sor.setInputCloud(temp_cloud);
11768+ sor.setLeafSize(0.01f, 0.01f, 0.01f);
11769+ sor.filter(*cloud_filtered);
11770+ pcl::fromPCLPointCloud2(*cloud_filtered, *down_cloud->get());
11771+}
11772+
11773+void Plane::calculateNormals(pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> normal_estimator,
11774+ pcl::search::Search<pcl::PointXYZ>::Ptr tree)
11775+{
11776+ normal_estimator.setNumberOfThreads(NUM_CORES);
11777+ normal_estimator.setSearchMethod(tree);
11778+ normal_estimator.setInputCloud(*down_cloud);
11779+ normal_estimator.setKSearch(50);
11780+ normal_estimator.compute(*down_normals->get());
11781+}
11782+
11783+void Plane::initializeCloud(cv::Mat &src)
11784+{
11785+ depth_img = src.clone();
11786+ int rowSize = src.rows;
11787+ int colSize = src.cols;
11788+ int cloudSize = 0;
11789+ for (size_t r = 0; r < rowSize; r++) {
11790+ for (size_t c = 0; c < colSize; c++) {
11791+ if (src.at<cv::Vec3f>(r, c)[2] != 0) {
11792+ cloudSize++;
11793+ }
11794+ }
11795+ }
11796+ cloud->get()->width = cloudSize;
11797+ cloud->get()->height = 1;
11798+ cloud->get()->points.resize(cloud->get()->width * cloud->get()->height);
11799+
11800+ int index = 0;
11801+ for (size_t r = 0; r < rowSize; r++) {
11802+ for (size_t c = 0; c < colSize; c++) {
11803+ if (src.at<cv::Vec3f>(r, c)[2] != 0) {
11804+ cloud->get()->points[index].x = src.at<cv::Vec3f>(r, c)[0];
11805+ cloud->get()->points[index].y = src.at<cv::Vec3f>(r, c)[1];
11806+ cloud->get()->points[index].z = src.at<cv::Vec3f>(r, c)[2];
11807+ index++;
11808+ }
11809+ }
11810+ }
11811+
11812+}
11813+
11814+pcl::PointCloud<pcl::PointXYZ>::Ptr Plane::getCloud()
11815+{
11816+ return *cloud;
11817+}
11818+
11819+pcl::PointCloud<pcl::PointXYZ>::Ptr Plane::getDownCloud()
11820+{
11821+ return *down_cloud;
11822+}
11823+
11824+std::vector<double> Plane::getPlaneEquation()
11825+{
11826+ return plane_equation;
11827+}
11828+
11829+std::vector<double> Plane::getSphereEquation()
11830+{
11831+ return sphere_equation;
11832+}
11833+
11834+std::vector<cv::Point2i> Plane::getPlaneIndicies()
11835+{
11836+ return plane_indices;
11837+}
11838+
11839+std::vector<cv::Point2i> Plane::getSphereIndices()
11840+{
11841+ return sphere_indices;
11842 }
11843\ No newline at end of file
11844diff --git a/Plane.h b/Plane.h
11845index a455f05..ac09874 100644
11846--- a/Plane.h
11847+++ b/Plane.h
11848@@ -1,171 +1,171 @@
11849-#pragma once
11850-// C++ Libraries
11851-#include <iostream>
11852-#include <cstdio>
11853-#include <ctime>
11854-
11855-// OpenCV Libaries
11856-#include <opencv2/highgui/highgui.hpp>
11857-#include <opencv2/core/core.hpp>
11858-#include <opencv2/imgproc/imgproc.hpp>
11859-
11860-// PCL Libaries
11861-#include <pcl/filters/voxel_grid.h>
11862-#include <pcl/point_types.h>
11863-#include <pcl/features/normal_3d.h>
11864-#include <pcl/io/pcd_io.h>
11865-#include <pcl/io/ply_io.h>
11866-#include <pcl/point_cloud.h>
11867-#include <pcl/console/parse.h>
11868-#include <pcl/common/transforms.h>
11869-#include <pcl/visualization/pcl_visualizer.h>
11870-#include <pcl/filters/passthrough.h>
11871-#include <pcl/features/integral_image_normal.h>
11872-#include <pcl/visualization/cloud_viewer.h>
11873-#include <pcl/segmentation/region_growing.h>
11874-#include <pcl/features/normal_3d_omp.h>
11875-
11876-/**
11877-* Class defining a plane object.
11878-* The plane object will be defined by its regression equation
11879-* Example on tracking hand and background plane object simulateously
11880-* @include HandandPlane.cpp
11881-*/
11882-class Plane {
11883-public:
11884- Plane();
11885-
11886- /**
11887- * Constructs a plane object from a unsegemented xyzMap.
11888- * @param [in] src the raw xyzMap.
11889- */
11890- Plane(cv::Mat &src);
11891-
11892- /**
11893- * Deconstructs the plane object.
11894- */
11895- ~Plane();
11896-
11897- /**
11898- * Initializes all the required point clouds.
11899- * @param [in] src the raw xyzMap
11900- */
11901- void initializeCloud(cv::Mat &src);
11902-
11903- /**
11904- * Returns the PCL representation of the xyzMap.
11905- * @return PCL point cloud
11906- */
11907- pcl::PointCloud<pcl::PointXYZ>::Ptr getCloud();
11908-
11909- /**
11910- * Returns the PCL representatino of a down sampled xyzMap.
11911- * @return down sampled PCL point cloud
11912- */
11913- pcl::PointCloud<pcl::PointXYZ>::Ptr getDownCloud();
11914-
11915- /**
11916- * Returns the planar regression equation of the identified plane.
11917- * @return coefficients for the planar regression equation
11918- */
11919- std::vector<double> getPlaneEquation();
11920-
11921- /**
11922- * Returns the sphereical regression equation of the identified plane.
11923- * @return coefficients for the sphereical regression equation
11924- */
11925- std::vector<double> getSphereEquation();
11926-
11927- /**
11928- * Returns the (i,j) indices for which the plane appears on the xyzMap.
11929- * @return vector of (i,j) coordinates defining the points that make up the plane on the xyzMap
11930- */
11931- std::vector<cv::Point2i> getPlaneIndicies();
11932-
11933- /**
11934- * Returns the (i,j) indices for which the plane appears on the xyzMap.
11935- * @return vector of (i,j) coordinates defining the points that make up the plane on the xyzMap
11936- */
11937- std::vector<cv::Point2i> getSphereIndices();
11938-
11939- /**
11940- * Maximum cloud size (pixel) allowed.
11941- */
11942- const int CLOUD_SIZE_THRESHOLD = 1000;
11943-
11944- /**
11945- * Maximum distance (mm) allowed between real point and regression equation.
11946- */
11947- const double R_SQUARED_DISTANCE_THRESHOLD = 0.0005;
11948-
11949-private:
11950- /**
11951- * Performs a series of computations to find the plane.
11952- */
11953- int compute();
11954-
11955- /**
11956- * Computes the normals at every point.
11957- * @param [in] normal_estimator a OMP instance of the normal estimator
11958- * @param [in] tree a KD-tree used by the normal estimator to preform neareest neighbor searches
11959- */
11960- void calculateNormals(pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> normal_estimator, pcl::search::Search<pcl::PointXYZ>::Ptr tree);
11961-
11962- /**
11963- * Down samples the cloud via a median filter.
11964- */
11965- void voxelDownsample();
11966-
11967- /**
11968- * Aggregates points with like normals.
11969- * @param [out] reg equation of the final plane
11970- * @param [in] tree KD-tree used for nearest neighbor search
11971- */
11972- void regionGrow(pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> ®, pcl::search::Search<pcl::PointXYZ>::Ptr tree);
11973-
11974- /**
11975- * Compute a planar regression equation.
11976- * @param [in] ind all the points on the plane
11977- */
11978- void computePlaneLSE(pcl::PointIndices &ind);
11979-
11980- /**
11981- * Compute a sphereical regression equation.
11982- * @param [in] ind all the points on the plane
11983- */
11984- void computeSphereLSE(pcl::PointIndices &ind);
11985-
11986- /**
11987- * Compute all the (i,j) index of the plane points from the planar regression.
11988- */
11989- int computePlaneIndices();
11990-
11991- /**
11992- * Compute all the (i,j) index of the plane points from the sphereical regression.
11993- */
11994- int computeSphereIndices();
11995-
11996- int drawSphereRegressionPoints(cv::Mat &output_mat, cv::Mat &input_mat, std::vector<double> &equation,
11997- const int rowSize, const int colSize, const double threshold, bool clicked);
11998-
11999- // Private Variables
12000- pcl::PointCloud<pcl::PointXYZ>::Ptr *cloud;
12001- pcl::PointCloud <pcl::Normal>::Ptr *normals;
12002- pcl::PointCloud<pcl::PointXYZ>::Ptr *down_cloud;
12003- pcl::PointCloud<pcl::Normal>::Ptr *down_normals;
12004- pcl::PointCloud <pcl::PointXYZRGB>::Ptr *colored_cloud;
12005- pcl::PointCloud <pcl::PointXYZRGB>::Ptr *upsampled_colored_cloud;
12006- std::vector<pcl::PointIndices> clusters;
12007- std::vector<double> plane_equation;
12008- std::vector<double> sphere_equation;
12009- std::vector<cv::Point2i> plane_indices;
12010- std::vector<cv::Point2i> sphere_indices;
12011- cv::Mat sphere_mat;
12012- cv::Mat plane_mat;
12013- cv::Mat display_img;
12014- cv::Mat depth_img;
12015- int num_sphere_points;
12016- int num_plane_points;
12017-
12018- const int NUM_CORES = boost::thread::hardware_concurrency();
12019+#pragma once
12020+// C++ Libraries
12021+#include <iostream>
12022+#include <cstdio>
12023+#include <ctime>
12024+
12025+// OpenCV Libaries
12026+#include <opencv2/highgui/highgui.hpp>
12027+#include <opencv2/core/core.hpp>
12028+#include <opencv2/imgproc/imgproc.hpp>
12029+
12030+// PCL Libaries
12031+#include <pcl/filters/voxel_grid.h>
12032+#include <pcl/point_types.h>
12033+#include <pcl/features/normal_3d.h>
12034+#include <pcl/io/pcd_io.h>
12035+#include <pcl/io/ply_io.h>
12036+#include <pcl/point_cloud.h>
12037+#include <pcl/console/parse.h>
12038+#include <pcl/common/transforms.h>
12039+#include <pcl/visualization/pcl_visualizer.h>
12040+#include <pcl/filters/passthrough.h>
12041+#include <pcl/features/integral_image_normal.h>
12042+#include <pcl/visualization/cloud_viewer.h>
12043+#include <pcl/segmentation/region_growing.h>
12044+#include <pcl/features/normal_3d_omp.h>
12045+
12046+/**
12047+* Class defining a plane object.
12048+* The plane object will be defined by its regression equation
12049+* Example on tracking hand and background plane object simulateously
12050+* @include HandandPlane.cpp
12051+*/
12052+class Plane {
12053+public:
12054+ Plane();
12055+
12056+ /**
12057+ * Constructs a plane object from a unsegemented xyzMap.
12058+ * @param [in] src the raw xyzMap.
12059+ */
12060+ Plane(cv::Mat &src);
12061+
12062+ /**
12063+ * Deconstructs the plane object.
12064+ */
12065+ ~Plane();
12066+
12067+ /**
12068+ * Initializes all the required point clouds.
12069+ * @param [in] src the raw xyzMap
12070+ */
12071+ void initializeCloud(cv::Mat &src);
12072+
12073+ /**
12074+ * Returns the PCL representation of the xyzMap.
12075+ * @return PCL point cloud
12076+ */
12077+ pcl::PointCloud<pcl::PointXYZ>::Ptr getCloud();
12078+
12079+ /**
12080+ * Returns the PCL representatino of a down sampled xyzMap.
12081+ * @return down sampled PCL point cloud
12082+ */
12083+ pcl::PointCloud<pcl::PointXYZ>::Ptr getDownCloud();
12084+
12085+ /**
12086+ * Returns the planar regression equation of the identified plane.
12087+ * @return coefficients for the planar regression equation
12088+ */
12089+ std::vector<double> getPlaneEquation();
12090+
12091+ /**
12092+ * Returns the sphereical regression equation of the identified plane.
12093+ * @return coefficients for the sphereical regression equation
12094+ */
12095+ std::vector<double> getSphereEquation();
12096+
12097+ /**
12098+ * Returns the (i,j) indices for which the plane appears on the xyzMap.
12099+ * @return vector of (i,j) coordinates defining the points that make up the plane on the xyzMap
12100+ */
12101+ std::vector<cv::Point2i> getPlaneIndicies();
12102+
12103+ /**
12104+ * Returns the (i,j) indices for which the plane appears on the xyzMap.
12105+ * @return vector of (i,j) coordinates defining the points that make up the plane on the xyzMap
12106+ */
12107+ std::vector<cv::Point2i> getSphereIndices();
12108+
12109+ /**
12110+ * Maximum cloud size (pixel) allowed.
12111+ */
12112+ const int CLOUD_SIZE_THRESHOLD = 1000;
12113+
12114+ /**
12115+ * Maximum distance (mm) allowed between real point and regression equation.
12116+ */
12117+ const double R_SQUARED_DISTANCE_THRESHOLD = 0.0005;
12118+
12119+private:
12120+ /**
12121+ * Performs a series of computations to find the plane.
12122+ */
12123+ int compute();
12124+
12125+ /**
12126+ * Computes the normals at every point.
12127+ * @param [in] normal_estimator a OMP instance of the normal estimator
12128+ * @param [in] tree a KD-tree used by the normal estimator to preform neareest neighbor searches
12129+ */
12130+ void calculateNormals(pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> normal_estimator, pcl::search::Search<pcl::PointXYZ>::Ptr tree);
12131+
12132+ /**
12133+ * Down samples the cloud via a median filter.
12134+ */
12135+ void voxelDownsample();
12136+
12137+ /**
12138+ * Aggregates points with like normals.
12139+ * @param [out] reg equation of the final plane
12140+ * @param [in] tree KD-tree used for nearest neighbor search
12141+ */
12142+ void regionGrow(pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> ®, pcl::search::Search<pcl::PointXYZ>::Ptr tree);
12143+
12144+ /**
12145+ * Compute a planar regression equation.
12146+ * @param [in] ind all the points on the plane
12147+ */
12148+ void computePlaneLSE(pcl::PointIndices &ind);
12149+
12150+ /**
12151+ * Compute a sphereical regression equation.
12152+ * @param [in] ind all the points on the plane
12153+ */
12154+ void computeSphereLSE(pcl::PointIndices &ind);
12155+
12156+ /**
12157+ * Compute all the (i,j) index of the plane points from the planar regression.
12158+ */
12159+ int computePlaneIndices();
12160+
12161+ /**
12162+ * Compute all the (i,j) index of the plane points from the sphereical regression.
12163+ */
12164+ int computeSphereIndices();
12165+
12166+ int drawSphereRegressionPoints(cv::Mat &output_mat, cv::Mat &input_mat, std::vector<double> &equation,
12167+ const int rowSize, const int colSize, const double threshold, bool clicked);
12168+
12169+ // Private Variables
12170+ pcl::PointCloud<pcl::PointXYZ>::Ptr *cloud;
12171+ pcl::PointCloud <pcl::Normal>::Ptr *normals;
12172+ pcl::PointCloud<pcl::PointXYZ>::Ptr *down_cloud;
12173+ pcl::PointCloud<pcl::Normal>::Ptr *down_normals;
12174+ pcl::PointCloud <pcl::PointXYZRGB>::Ptr *colored_cloud;
12175+ pcl::PointCloud <pcl::PointXYZRGB>::Ptr *upsampled_colored_cloud;
12176+ std::vector<pcl::PointIndices> clusters;
12177+ std::vector<double> plane_equation;
12178+ std::vector<double> sphere_equation;
12179+ std::vector<cv::Point2i> plane_indices;
12180+ std::vector<cv::Point2i> sphere_indices;
12181+ cv::Mat sphere_mat;
12182+ cv::Mat plane_mat;
12183+ cv::Mat display_img;
12184+ cv::Mat depth_img;
12185+ int num_sphere_points;
12186+ int num_plane_points;
12187+
12188+ const int NUM_CORES = boost::thread::hardware_concurrency();
12189 };
12190\ No newline at end of file
12191diff --git a/README.md b/README.md
12192index 2ab905b..68b9fd3 100644
12193--- a/README.md
12194+++ b/README.md
12195@@ -1,58 +1,58 @@
12196-# OpenARK
12197-
12198-OpenARK is an open-source wearable augmented reality (AR) system founded at UC Berkeley in 2016. The C++ based software offers innovative core functionalities to power a wide range of off-the-shelf AR components, including see-through glasses, depth cameras, and IMUs. The open-source platform includes fundamental tools such as AR-based camera calibration and SLAM, and it also includes higher-level functions to aid human-computer interaction, such as 3D gesture recognition and multi-user collaboration.
12199-
12200-At a Glance
12201-
12202- - **Technology stack**: C++, OpenCV, PCL, Boost, OpenNI
12203- - **Status**: Beta 0.8
12204- - **Application Demo**: vimeo.com/205084929
12205-
12206-
12207-## Dependencies
12208-Hardware
12209-- Depth Camera
12210-- RGB Camera
12211-- Transparent AR Glasses (optional)
12212-
12213-Software
12214-- OpenCV 3.0
12215-- PCL 1.8
12216-- OpenNI 1.5.8
12217-- Boost 1.6.4
12218-
12219-## Installation
12220-
12221-1. Download and install all software depedencies (OpenCV, PCL, OpenNI, Boost)
12222-2. Clone repo to local machine
12223-3. Open the Visual Studios solution (OpenARK.sln)
12224-
12225-## Configuration
12226-
12227-Configure project properties (see /documentation/OpenARK_Setup.pdf)
12228-
12229-## Usage
12230-
12231-OpenARK is made for easy customization. Please feel free to build on top of this platform to fit your needs.
12232-
12233-## How to test the software
12234-
12235-Code used to run the demo video is included in main.cpp. Additional sample code can be found in /samplecode/.
12236-
12237-## Known issues
12238-
12239-OpenCV currently do not offer prebuilt VC14+ binaries. Running VC12 OpenCV binaries with VC14 will result in memories errors in findCountours(). If you are using VC12+ to compile OpenARK, you will need to use CMake to rebuilt OpenCV from source.
12240-
12241-## Getting help
12242-
12243-If you have questions, concerns, bug reports, etc, please file an issue in this repository's Issue Tracker.
12244-
12245-## Getting involved
12246-
12247-The Center for Augmented Cognition welcome interested industry partners to join our alliance to support the Open ARK platform. More information can be found on cac.berkeley.edu
12248-
12249-----
12250-
12251-## Credits and references
12252-
12253-Bill Zhou, Allen Yang, S.Shankar, Will Huang, Larry Yang, Eric Nyugen, Michelli Ni, Peter Li, Jessica Jiang
12254+# OpenARK
12255+
12256+OpenARK is an open-source wearable augmented reality (AR) system founded at UC Berkeley in 2016. The C++ based software offers innovative core functionalities to power a wide range of off-the-shelf AR components, including see-through glasses, depth cameras, and IMUs. The open-source platform includes fundamental tools such as AR-based camera calibration and SLAM, and it also includes higher-level functions to aid human-computer interaction, such as 3D gesture recognition and multi-user collaboration.
12257+
12258+At a Glance
12259+
12260+ - **Technology stack**: C++, OpenCV, PCL, Boost, OpenNI
12261+ - **Status**: Beta 0.8
12262+ - **Application Demo**: vimeo.com/205084929
12263+
12264+
12265+## Dependencies
12266+Hardware
12267+- Depth Camera
12268+- RGB Camera
12269+- Transparent AR Glasses (optional)
12270+
12271+Software
12272+- OpenCV 3.0
12273+- PCL 1.8
12274+- OpenNI 1.5.8
12275+- Boost 1.6.4
12276+
12277+## Installation
12278+
12279+1. Download and install all software depedencies (OpenCV, PCL, OpenNI, Boost)
12280+2. Clone repo to local machine
12281+3. Open the Visual Studios solution (OpenARK.sln)
12282+
12283+## Configuration
12284+
12285+Configure project properties (see /documentation/OpenARK_Setup.pdf)
12286+
12287+## Usage
12288+
12289+OpenARK is made for easy customization. Please feel free to build on top of this platform to fit your needs.
12290+
12291+## How to test the software
12292+
12293+Code used to run the demo video is included in main.cpp. Additional sample code can be found in /samplecode/.
12294+
12295+## Known issues
12296+
12297+OpenCV currently do not offer prebuilt VC14+ binaries. Running VC12 OpenCV binaries with VC14 will result in memories errors in findCountours(). If you are using VC12+ to compile OpenARK, you will need to use CMake to rebuilt OpenCV from source.
12298+
12299+## Getting help
12300+
12301+If you have questions, concerns, bug reports, etc, please file an issue in this repository's Issue Tracker.
12302+
12303+## Getting involved
12304+
12305+The Center for Augmented Cognition welcome interested industry partners to join our alliance to support the Open ARK platform. More information can be found on cac.berkeley.edu
12306+
12307+----
12308+
12309+## Credits and references
12310+
12311+Bill Zhou, Allen Yang, S.Shankar, Will Huang, Larry Yang, Eric Nyugen, Michelli Ni, Peter Li, Jessica Jiang
12312diff --git a/RGBCamera.cpp b/RGBCamera.cpp
12313index 4a0f292..b7703ed 100644
12314--- a/RGBCamera.cpp
12315+++ b/RGBCamera.cpp
12316@@ -1,10 +1,10 @@
12317-#include "RGBCamera.h"
12318-
12319-/***
12320-Returns the next frame if next frame is recorded
12321-Returns the previous frame if next frame is not recorded
12322-***/
12323-cv::Mat RGBCamera::getFrame()
12324-{
12325- return frame;
12326+#include "RGBCamera.h"
12327+
12328+/***
12329+Returns the next frame if next frame is recorded
12330+Returns the previous frame if next frame is not recorded
12331+***/
12332+cv::Mat RGBCamera::getFrame()
12333+{
12334+ return frame;
12335 }
12336\ No newline at end of file
12337diff --git a/RGBCamera.h b/RGBCamera.h
12338index c671c95..7c883e8 100644
12339--- a/RGBCamera.h
12340+++ b/RGBCamera.h
12341@@ -1,33 +1,33 @@
12342-#pragma once
12343-//OpenCV libraries
12344-#include "opencv2/highgui/highgui.hpp"
12345-
12346-/**
12347-* Abstract class that defines the behavior of a RGB camera.
12348-*/
12349-class RGBCamera
12350-{
12351-public:
12352- /**
12353- * Updates the current frame on the RGB camera.
12354- * Should be overriden by a concerte implementation specific to the RGB camera
12355- */
12356- virtual void update() = 0;
12357-
12358- /**
12359- * Returns the current frame.
12360- * @return the current frame
12361- */
12362- cv::Mat getFrame();
12363-
12364-protected:
12365- /**
12366- * Camera handle.
12367- */
12368- cv::VideoCapture cap;
12369-
12370- /**
12371- * Current frame.
12372- */
12373- cv::Mat frame;
12374+#pragma once
12375+#include <opencv/cxcore.h>
12376+#include "opencv2/highgui/highgui.hpp"
12377+
12378+/**
12379+* Abstract class that defines the behavior of a RGB camera.
12380+*/
12381+class RGBCamera
12382+{
12383+public:
12384+ /**
12385+ * Updates the current frame on the RGB camera.
12386+ * Should be overriden by a concerte implementation specific to the RGB camera
12387+ */
12388+ virtual void update() = 0;
12389+
12390+ /**
12391+ * Returns the current frame.
12392+ * @return the current frame
12393+ */
12394+ cv::Mat getFrame();
12395+
12396+protected:
12397+ /**
12398+ * Camera handle.
12399+ */
12400+ cv::VideoCapture cap;
12401+
12402+ /**
12403+ * Current frame.
12404+ */
12405+ cv::Mat frame;
12406 };
12407\ No newline at end of file
12408diff --git a/RT_Transform.txt b/RT_Transform.txt
12409index f708c02..d1f20fc 100644
12410--- a/RT_Transform.txt
12411+++ b/RT_Transform.txt
12412@@ -1,13 +1,13 @@
12413-%YAML:1.0
12414-R: !!opencv-matrix
12415- rows: 3
12416- cols: 3
12417- dt: f
12418- data: [ 9.99971926e-001, -7.48438481e-003, -4.79703158e-006,
12419- -7.47213839e-003, -9.98298407e-001, -5.78310676e-002,
12420- -4.28037398e-004, -5.78294173e-002, 9.98326361e-001 ]
12421-T: !!opencv-matrix
12422- rows: 3
12423- cols: 1
12424- dt: f
12425- data: [ 1.13893911e-001, 8.25873576e-003, -1.35086179e-002 ]
12426+%YAML:1.0
12427+R: !!opencv-matrix
12428+ rows: 3
12429+ cols: 3
12430+ dt: f
12431+ data: [ 9.99971926e-001, -7.48438481e-003, -4.79703158e-006,
12432+ -7.47213839e-003, -9.98298407e-001, -5.78310676e-002,
12433+ -4.28037398e-004, -5.78294173e-002, 9.98326361e-001 ]
12434+T: !!opencv-matrix
12435+ rows: 3
12436+ cols: 1
12437+ dt: f
12438+ data: [ 1.13893911e-001, 8.25873576e-003, -1.35086179e-002 ]
12439diff --git a/SR300Camera.cpp b/SR300Camera.cpp
12440deleted file mode 100644
12441index 589a10e..0000000
12442--- a/SR300Camera.cpp
12443+++ /dev/null
12444@@ -1,157 +0,0 @@
12445-#include "SR300Camera.h"
12446-#include "Visualizer.h"
12447-#include <iostream>
12448-
12449-
12450-
12451-/***
12452-Private constructor for the SR300 Camera depth sensor
12453-***/
12454-using namespace std;
12455-
12456-
12457-
12458-/***
12459-Private constructor for the Intel RealSense SR300 camera depth sensor
12460-***/
12461-SR300Camera::SR300Camera(bool use_live_sensor)
12462-{
12463-
12464- session->SetCoordinateSystem(Intel::RealSense::CoordinateSystem::COORDINATE_SYSTEM_FRONT_DEFAULT);
12465- X_DIMENSION = 640;
12466- Y_DIMENSION = 480;
12467- if (!sm)
12468- {
12469- wprintf_s(L"Unable to create the SenseManager\n");
12470- }
12471- cm = sm->QueryCaptureManager();
12472- Intel::RealSense::Status sts = Intel::RealSense::Status::STATUS_DATA_UNAVAILABLE;
12473-
12474- sm->EnableStream(Intel::RealSense::Capture::StreamType::STREAM_TYPE_DEPTH, X_DIMENSION, Y_DIMENSION, depth_fps);
12475- sts = sm->Init();
12476- if (sts < Intel::RealSense::Status::STATUS_NO_ERROR)
12477- {
12478- sm->Close();
12479- sm->EnableStream(Intel::RealSense::Capture::STREAM_TYPE_DEPTH);
12480- sts = sm->Init();
12481- if (sts < Intel::RealSense::Status::STATUS_NO_ERROR)
12482- {
12483- sm->Close();
12484- sts = sm->Init();
12485- }
12486- }
12487- device = cm->QueryDevice();
12488-}
12489-
12490-
12491-/***
12492-Public deconstructor for the SR300 Camera depth sensor
12493-***/
12494-SR300Camera::~SR300Camera() {};
12495-
12496-void SR300Camera::destroyInstance()
12497-{
12498- printf("closing sensor\n");
12499- sm->Release();
12500- sm->Close();
12501- printf("sensor closed\n");
12502-}
12503-
12504-
12505-/***
12506-Create xyzMap, zMap, ampMap, and flagMap from sensor input
12507-***/
12508-void SR300Camera::update()
12509-{
12510- initilizeImages();
12511- fillInAmps();
12512- fillInZCoords();
12513- sm->ReleaseFrame();
12514-}
12515-
12516-
12517-/***
12518-Reads the depth data from the sensor and fills in the matrix
12519-***/
12520-void SR300Camera::fillInZCoords()
12521-{
12522-
12523- int num_pixels;
12524- vector<cv::Point3f> xyzBuffer;
12525-
12526- int res;
12527- Intel::RealSense::Status sts = sm ->AcquireFrame(true);
12528- if (sts < Intel::RealSense::STATUS_NO_ERROR) {
12529- if (sts == Intel::RealSense::Status::STATUS_STREAM_CONFIG_CHANGED)
12530- {
12531- wprintf_s(L"Stream configuration was changed, re-initilizing\n");
12532- sm ->Close();
12533- }
12534- }
12535- sample = sm->QuerySample();
12536- Intel::RealSense::Image *depthMap = sample->depth;
12537- Intel::RealSense::Image::ImageData depthImage;
12538- depthMap->AcquireAccess(Intel::RealSense::Image::ACCESS_READ, &depthImage);
12539- cv::Mat img;
12540- Converter::ConvertPXCImageToOpenCVMat(depthMap, depthImage, &img);
12541- cv::imshow("Depth Image by OpenARK", Visualizer::visualizeDepthMap(img));
12542- Intel::RealSense::Image::ImageInfo imgInfo = depthMap->QueryInfo();
12543- depth_width = imgInfo.width;
12544- depth_height = imgInfo.height;
12545- num_pixels = depth_width * depth_height;
12546- Intel::RealSense::Projection * projection = device->CreateProjection();
12547- Intel::RealSense::Point3DF32 *pos3D = new Intel::RealSense::Point3DF32[num_pixels];
12548- sts = projection->QueryVertices(depthMap, &pos3D[0]);
12549- if (sts < Intel::RealSense::Status::STATUS_NO_ERROR)
12550- {
12551- wprintf_s(L"Projection was unsuccessful! \n");
12552- sm->Close();
12553- }
12554- xyzBuffer.clear();
12555- for (int k = 0; k < num_pixels; k++)
12556- {
12557- xyzBuffer.emplace_back(cv::Point3f(pos3D[k].x / 1000.0f, pos3D[k].y / 1000.0f, pos3D[k].z / 1000.0f));
12558- }
12559- xyzMap = cv::Mat(xyzBuffer, true).reshape(3, 480);
12560- cv::namedWindow("XYZ Image by OpenARK", CV_WINDOW_AUTOSIZE);
12561- cv::imshow("XYZ Image by OpenARK", Visualizer::visualizeXYZMap(xyzMap));
12562-}
12563-
12564-
12565-/***
12566-Reads the amplitude data from the sensor and fills in the matrix
12567-***/
12568-void SR300Camera::fillInAmps()
12569-{
12570- ampMap.data = NULL;
12571-}
12572-
12573-
12574-/***
12575-Returns the X value at (i, j)
12576-***/
12577-float SR300Camera::getX(int i, int j) const
12578-{
12579- int flat = j * depth_width * 3 + i * 3;
12580- return dists[flat];
12581-}
12582-
12583-
12584-/***
12585-Returns the Y value at (i, j)
12586-***/
12587-float SR300Camera::getY(int i, int j) const
12588-{
12589- int flat = j * depth_width * 3 + i * 3;
12590- return dists[flat + 1];
12591-}
12592-
12593-
12594-/***
12595-Returns the Z value at (i, j)
12596-***/
12597-float SR300Camera::getZ(int i, int j) const
12598-{
12599- int flat = j * depth_width * 3 + i * 3;
12600- return dists[flat + 2];
12601-}
12602\ No newline at end of file
12603diff --git a/SR300Camera.h b/SR300Camera.h
12604deleted file mode 100644
12605index 1e901f3..0000000
12606--- a/SR300Camera.h
12607+++ /dev/null
12608@@ -1,104 +0,0 @@
12609-#pragma once
12610-// C++ Libraries
12611-#include<string.h>
12612-
12613-
12614-// OpenCV Libraries
12615-#include <opencv2/opencv.hpp>
12616-#include "opencv2/highgui/highgui.hpp"
12617-#include <opencv2/video/tracking.hpp>
12618-#include "opencv2/imgproc/imgproc.hpp"
12619-#include <opencv2/objdetect/objdetect.hpp>
12620-#include <opencv2/features2d/features2d.hpp>
12621-
12622-
12623-// OpenARK Libraries
12624-#include "DepthCamera.h"
12625-#include "Converter.h"
12626-
12627-//using namespace Intel::RealSense;
12628-
12629-/**
12630-* Class defining the behavior of an SR300 Camera.
12631-* Example on how to read from sensor and visualize its output
12632-* @include SensorIO.cpp
12633-*/
12634-class SR300Camera : public DepthCamera
12635-{
12636-public:
12637-
12638-
12639- /**
12640- * Public constructor initializing the SR300 Camera.
12641- * @param use_live_sensor uses input from real sensor if TRUE. Otherwise reads from input file. Default is set to TRUE.
12642- */
12643- SR300Camera(bool use_live_sensor = true);
12644-
12645- /**
12646- * Deconstructor for the SR300 Camera.
12647- */
12648- ~SR300Camera();
12649-
12650- /**
12651- * Gets new frame from sensor.
12652- * Updates xyzMap, ampMap, and flagMap. Resets clusters.
12653- */
12654- void update();
12655-
12656- /**
12657- * Gracefully closes the SR300 camera.
12658- */
12659- void destroyInstance();
12660-
12661-private:
12662- /**
12663- * Getter method for the x-coordinate at (i,j).
12664- * @param i ith row
12665- * @param j jth column
12666- * @return x-coodinate at (i,j)
12667- */
12668- float getX(int i, int j) const;
12669-
12670-
12671- /**
12672- * Getter method for the x-coordinate at (i,j).
12673- * @param i ith row
12674- * @param j jth column
12675- * @return x-coodinate at (i,j)
12676- */
12677- float getY(int i, int j) const;
12678-
12679- /**
12680- * Getter method for the x-coordinate at (i,j).
12681- * @param i ith row
12682- * @param j jth column
12683- * @return x-coodinate at (i,j)
12684- */
12685- float getZ(int i, int j) const;
12686-
12687- /**
12688- * Update the z-coordinates of the xyzMap.
12689- */
12690- void fillInZCoords();
12691-
12692- /**
12693- * Update the values in the ampMap.
12694- */
12695- void fillInAmps();
12696-
12697-
12698- //Private Variables
12699- float* dists;
12700- float* amps;
12701- cv::Mat frame;
12702- const int depth_fps = 30;
12703- int depth_width;
12704- int depth_height;
12705- cv::Size bufferSize;
12706- const Intel::RealSense::Sample *sample;
12707- Intel::RealSense::SenseManager *sm = Intel::RealSense::SenseManager::CreateInstance();
12708- Intel::RealSense::Session *session = sm->QuerySession();
12709- Intel::RealSense::Device *device;
12710- Intel::RealSense::CaptureManager *cm;
12711-
12712-};
12713\ No newline at end of file
12714diff --git a/SensorIO.cpp b/SensorIO.cpp
12715index 6abf574..d569ff8 100644
12716--- a/SensorIO.cpp
12717+++ b/SensorIO.cpp
12718@@ -1,41 +1,41 @@
12719-// C++ Libraries
12720-#include <stdio.h>
12721-#include <iostream>
12722-#include <string>
12723-
12724-// OpenCV Libraries
12725-#include <opencv/cxcore.h>
12726-#include "opencv2/highgui/highgui.hpp"
12727-
12728-// OpenARK Libraries
12729-#include "PMDCamera.h"
12730-#include "Visualizer.h"
12731-#include "Util.h"
12732-
12733-int main() {
12734- DepthCamera* pmd = new PMDCamera();
12735- int frame = 0;
12736-
12737- while (true)
12738- {
12739- // Update the current frame
12740- pmd->update();
12741-
12742- // REmove the current frame
12743- pmd->removeNoise();
12744-
12745- // Visualize the XYZ Map
12746- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
12747-
12748- /**** Start: Loop Break Condition ****/
12749- int c = cvWaitKey(1);
12750- if (c == 'q' || c == 'Q' || c == 27) {
12751- break;
12752- }
12753- /**** End: Loop Break Condition ****/
12754- frame++;
12755- }
12756-
12757- pmd->destroyInstance();
12758- return 0;
12759+// C++ Libraries
12760+#include <stdio.h>
12761+#include <iostream>
12762+#include <string>
12763+
12764+// OpenCV Libraries
12765+#include <opencv/cxcore.h>
12766+#include "opencv2/highgui/highgui.hpp"
12767+
12768+// OpenARK Libraries
12769+#include "PMDCamera.h"
12770+#include "Visualizer.h"
12771+#include "Util.h"
12772+
12773+int main() {
12774+ DepthCamera* pmd = new PMDCamera();
12775+ int frame = 0;
12776+
12777+ while (true)
12778+ {
12779+ // Update the current frame
12780+ pmd->update();
12781+
12782+ // REmove the current frame
12783+ pmd->removeNoise();
12784+
12785+ // Visualize the XYZ Map
12786+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
12787+
12788+ /**** Start: Loop Break Condition ****/
12789+ int c = cvWaitKey(1);
12790+ if (c == 'q' || c == 'Q' || c == 27) {
12791+ break;
12792+ }
12793+ /**** End: Loop Break Condition ****/
12794+ frame++;
12795+ }
12796+
12797+ pmd->destroyInstance();
12798+ return 0;
12799 }
12800\ No newline at end of file
12801diff --git a/StreamingAverager.cpp b/StreamingAverager.cpp
12802index 99d2d76..4aff320 100644
12803--- a/StreamingAverager.cpp
12804+++ b/StreamingAverager.cpp
12805@@ -1,51 +1,51 @@
12806-#include "StreamingAverager.h"
12807-
12808-StreamingAverager::StreamingAverager(int frequency, double rejectionDistance)
12809-{
12810- sampleFrequency = frequency;
12811- rejectionThreshold = rejectionDistance;
12812- dataPoints = std::deque<cv::Vec3f>();
12813-}
12814-
12815-cv::Vec3f StreamingAverager::addDataPoint(cv::Vec3f pt)
12816-{
12817- if (dataPoints.size() > 0 && Util::euclidianDistance3D(pt, getCurrentAverage()) > rejectionThreshold) {
12818- addEmptyPoint();
12819- return getCurrentAverage();
12820- }
12821-
12822- if (dataPoints.size() >= sampleFrequency) {
12823- cv::Vec3f extra = dataPoints.front();
12824- dataPoints.pop_front();
12825- currentValue -= extra;
12826- }
12827- dataPoints.push_back(pt);
12828- currentValue += pt;
12829-
12830- return getCurrentAverage();
12831-}
12832-
12833-void StreamingAverager::addEmptyPoint()
12834-{
12835- if (dataPoints.size() > 0) {
12836- cv::Vec3f extra = dataPoints.front();
12837- dataPoints.pop_front();
12838- currentValue = currentValue - extra;
12839- }
12840-}
12841-
12842-cv::Vec3f StreamingAverager::getCurrentAverage()
12843-{
12844- cv::Vec3f average;
12845- if (dataPoints.size() != 0) {
12846- average[0] = currentValue[0] / dataPoints.size();
12847- average[1] = currentValue[1] / dataPoints.size();
12848- average[2] = currentValue[2] / dataPoints.size();
12849- }
12850- return average;
12851-}
12852-
12853-StreamingAverager::~StreamingAverager()
12854-{
12855-
12856+#include "StreamingAverager.h"
12857+
12858+StreamingAverager::StreamingAverager(int frequency, double rejectionDistance)
12859+{
12860+ sampleFrequency = frequency;
12861+ rejectionThreshold = rejectionDistance;
12862+ dataPoints = std::deque<cv::Vec3f>();
12863+}
12864+
12865+cv::Vec3f StreamingAverager::addDataPoint(cv::Vec3f pt)
12866+{
12867+ if (dataPoints.size() > 0 && Util::euclidianDistance3D(pt, getCurrentAverage()) > rejectionThreshold) {
12868+ addEmptyPoint();
12869+ return getCurrentAverage();
12870+ }
12871+
12872+ if (dataPoints.size() >= sampleFrequency) {
12873+ cv::Vec3f extra = dataPoints.front();
12874+ dataPoints.pop_front();
12875+ currentValue -= extra;
12876+ }
12877+ dataPoints.push_back(pt);
12878+ currentValue += pt;
12879+
12880+ return getCurrentAverage();
12881+}
12882+
12883+void StreamingAverager::addEmptyPoint()
12884+{
12885+ if (dataPoints.size() > 0) {
12886+ cv::Vec3f extra = dataPoints.front();
12887+ dataPoints.pop_front();
12888+ currentValue = currentValue - extra;
12889+ }
12890+}
12891+
12892+cv::Vec3f StreamingAverager::getCurrentAverage()
12893+{
12894+ cv::Vec3f average;
12895+ if (dataPoints.size() != 0) {
12896+ average[0] = currentValue[0] / dataPoints.size();
12897+ average[1] = currentValue[1] / dataPoints.size();
12898+ average[2] = currentValue[2] / dataPoints.size();
12899+ }
12900+ return average;
12901+}
12902+
12903+StreamingAverager::~StreamingAverager()
12904+{
12905+
12906 }
12907\ No newline at end of file
12908diff --git a/StreamingAverager.h b/StreamingAverager.h
12909index a763836..74387c0 100644
12910--- a/StreamingAverager.h
12911+++ b/StreamingAverager.h
12912@@ -1,66 +1,69 @@
12913-#pragma once
12914-// C++ Libraries
12915-#include <deque>
12916-
12917-// OpenARK Libraries
12918-#include "Util.h"
12919-
12920-/*
12921-* Averages streaming data to combate outliers. A sample frequency and rejection threshold is used to determined the best fit point at the current time frame.
12922-*/
12923-class StreamingAverager
12924-{
12925-public:
12926- /*
12927- * Constructs a new instance of the streaming averager.
12928- * @param frequency how many previous points to use in the averaging computation
12929- * @param rejectionDistance maximum jump distance allowed between current point and previous point
12930- */
12931- StreamingAverager(int frequency, double rejectionDistance);
12932-
12933- /*
12934- * Deconstructs an instance of the streaming averager.
12935- */
12936- ~StreamingAverager();
12937-
12938- /*
12939- * Adds new data point to the streaming averager.
12940- * @param pt point at the current frame
12941- * @return the average a the current frame
12942- */
12943- cv::Vec3f addDataPoint(cv::Vec3f pt);
12944-
12945- /*
12946- * Adds a empty data point to the stream of points.
12947- * If there are no points to add at the current frame, an empty point should be added to push out the old points
12948- */
12949- void addEmptyPoint();
12950-
12951-private:
12952- /*
12953- * Number of previous points to be used in the average.
12954- */
12955- int sampleFrequency;
12956-
12957- /*
12958- * Maximum jump distance allowed between current point and previous point
12959- */
12960- double rejectionThreshold;
12961-
12962- /*
12963- * The current average value
12964- */
12965- cv::Vec3f currentValue;
12966-
12967- /*
12968- * Recently seen data points
12969- * @see sampleFrequency
12970- */
12971- std::deque<cv::Vec3f> dataPoints;
12972-
12973- /*
12974- * Compute the current average.
12975- * @return (x,y,z) average at current frame
12976- */
12977- cv::Vec3f getCurrentAverage();
12978+#pragma once
12979+// C++ Libraries
12980+#include <deque>
12981+
12982+// OpenCV Libraries
12983+#include <opencv/cxcore.h>
12984+
12985+// OpenARK Libraries
12986+#include "Util.h"
12987+
12988+/*
12989+* Averages streaming data to combate outliers. A sample frequency and rejection threshold is used to determined the best fit point at the current time frame.
12990+*/
12991+class StreamingAverager
12992+{
12993+public:
12994+ /*
12995+ * Constructs a new instance of the streaming averager.
12996+ * @param frequency how many previous points to use in the averaging computation
12997+ * @param rejectionDistance maximum jump distance allowed between current point and previous point
12998+ */
12999+ StreamingAverager(int frequency, double rejectionDistance);
13000+
13001+ /*
13002+ * Deconstructs an instance of the streaming averager.
13003+ */
13004+ ~StreamingAverager();
13005+
13006+ /*
13007+ * Adds new data point to the streaming averager.
13008+ * @param pt point at the current frame
13009+ * @return the average a the current frame
13010+ */
13011+ cv::Vec3f addDataPoint(cv::Vec3f pt);
13012+
13013+ /*
13014+ * Adds a empty data point to the stream of points.
13015+ * If there are no points to add at the current frame, an empty point should be added to push out the old points
13016+ */
13017+ void addEmptyPoint();
13018+
13019+private:
13020+ /*
13021+ * Number of previous points to be used in the average.
13022+ */
13023+ int sampleFrequency;
13024+
13025+ /*
13026+ * Maximum jump distance allowed between current point and previous point
13027+ */
13028+ double rejectionThreshold;
13029+
13030+ /*
13031+ * The current average value
13032+ */
13033+ cv::Vec3f currentValue;
13034+
13035+ /*
13036+ * Recently seen data points
13037+ * @see sampleFrequency
13038+ */
13039+ std::deque<cv::Vec3f> dataPoints;
13040+
13041+ /*
13042+ * Compute the current average.
13043+ * @return (x,y,z) average at current frame
13044+ */
13045+ cv::Vec3f getCurrentAverage();
13046 };
13047\ No newline at end of file
13048diff --git a/UDPSender.cpp b/UDPSender.cpp
13049index 23586c7..d26c8d7 100644
13050--- a/UDPSender.cpp
13051+++ b/UDPSender.cpp
13052@@ -1,45 +1,45 @@
13053-#include "UDPSender.h"
13054-#define _WINSOCK_DEPRECATED_NO_WARNINGS
13055-
13056-UDPSender::UDPSender()
13057-{
13058- //Initialise winsock
13059- printf("\nInitialising Winsock...");
13060- if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
13061- {
13062- printf("Failed. Error Code : %d", WSAGetLastError());
13063- exit(EXIT_FAILURE);
13064- }
13065- printf("Initialised.\n");
13066-
13067- //create socket
13068- if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
13069- {
13070- printf("socket() failed with error code : %d", WSAGetLastError());
13071- exit(EXIT_FAILURE);
13072- }
13073-
13074- //setup address structure
13075- memset((char *)&si_other, 0, sizeof(si_other));
13076- si_other.sin_family = AF_INET;
13077- si_other.sin_port = htons(PORT);
13078- si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
13079-
13080-}
13081-
13082-int UDPSender::send(std::string message)
13083-{
13084- if (sendto(s, message.c_str(), strlen(message.c_str()), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
13085- {
13086- printf("sendto() failed with error code : %d", WSAGetLastError());
13087- exit(EXIT_FAILURE);
13088- }
13089- return 0;
13090-}
13091-
13092-int UDPSender::close()
13093-{
13094- closesocket(s);
13095- WSACleanup();
13096- return 0;
13097+#include "UDPSender.h"
13098+#define _WINSOCK_DEPRECATED_NO_WARNINGS
13099+
13100+UDPSender::UDPSender()
13101+{
13102+ //Initialise winsock
13103+ printf("\nInitialising Winsock...");
13104+ if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
13105+ {
13106+ printf("Failed. Error Code : %d", WSAGetLastError());
13107+ exit(EXIT_FAILURE);
13108+ }
13109+ printf("Initialised.\n");
13110+
13111+ //create socket
13112+ if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
13113+ {
13114+ printf("socket() failed with error code : %d", WSAGetLastError());
13115+ exit(EXIT_FAILURE);
13116+ }
13117+
13118+ //setup address structure
13119+ memset((char *)&si_other, 0, sizeof(si_other));
13120+ si_other.sin_family = AF_INET;
13121+ si_other.sin_port = htons(PORT);
13122+ si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
13123+
13124+}
13125+
13126+int UDPSender::send(std::string message)
13127+{
13128+ if (sendto(s, message.c_str(), strlen(message.c_str()), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
13129+ {
13130+ printf("sendto() failed with error code : %d", WSAGetLastError());
13131+ exit(EXIT_FAILURE);
13132+ }
13133+ return 0;
13134+}
13135+
13136+int UDPSender::close()
13137+{
13138+ closesocket(s);
13139+ WSACleanup();
13140+ return 0;
13141 }
13142\ No newline at end of file
13143diff --git a/UDPSender.h b/UDPSender.h
13144index e3bf8f3..0a3fe7c 100644
13145--- a/UDPSender.h
13146+++ b/UDPSender.h
13147@@ -1,40 +1,40 @@
13148-#pragma once
13149-#define _WINSOCK_DEPRECATED_NO_WARNINGS
13150-#include <winsock2.h>
13151-#include <stdio.h>
13152-#include <iostream>
13153-
13154-#pragma comment(lib,"ws2_32.lib") //Winsock Library
13155-
13156-#define SERVER "127.0.0.1" //ip address of udp server
13157-#define BUFLEN 512 //Max length of buffer
13158-#define PORT 8051 //The port on which to listen for incoming data
13159-
13160-/**
13161-* UDP client.
13162-* Used to communicate information with game engines such as Unity
13163-*/
13164-class UDPSender {
13165-public:
13166- /**
13167- * Constructs a new UPD sender.
13168- */
13169- UDPSender();
13170-
13171- /**
13172- * Sends a message.
13173- * @param message the data to be sent
13174- */
13175- int send(std::string message);
13176-
13177- /**
13178- * Close the current connection.
13179- */
13180- int close();
13181-
13182- struct sockaddr_in si_other;
13183- int s, slen = sizeof(si_other);
13184- char buf[BUFLEN];
13185- char message[BUFLEN];
13186- WSADATA wsa;
13187+#pragma once
13188+#define _WINSOCK_DEPRECATED_NO_WARNINGS
13189+#include <winsock2.h>
13190+#include <stdio.h>
13191+#include <iostream>
13192+
13193+#pragma comment(lib,"ws2_32.lib") //Winsock Library
13194+
13195+#define SERVER "127.0.0.1" //ip address of udp server
13196+#define BUFLEN 512 //Max length of buffer
13197+#define PORT 8051 //The port on which to listen for incoming data
13198+
13199+/**
13200+* UDP client.
13201+* Used to communicate information with game engines such as Unity
13202+*/
13203+class UDPSender {
13204+public:
13205+ /**
13206+ * Constructs a new UPD sender.
13207+ */
13208+ UDPSender();
13209+
13210+ /**
13211+ * Sends a message.
13212+ * @param message the data to be sent
13213+ */
13214+ int send(std::string message);
13215+
13216+ /**
13217+ * Close the current connection.
13218+ */
13219+ int close();
13220+
13221+ struct sockaddr_in si_other;
13222+ int s, slen = sizeof(si_other);
13223+ char buf[BUFLEN];
13224+ char message[BUFLEN];
13225+ WSADATA wsa;
13226 };
13227\ No newline at end of file
13228diff --git a/Util.cpp b/Util.cpp
13229index ec12c76..44a62f2 100644
13230--- a/Util.cpp
13231+++ b/Util.cpp
13232@@ -1,273 +1,273 @@
13233-#include "Util.h"
13234-
13235-cv::Vec3b Util::colorGenerator2()
13236-{
13237- return cv::Vec3b(rand() % 256, rand() % 256, rand() % 256);
13238-}
13239-
13240-float Util::normalize(float a, float b)
13241-{
13242- return sqrt(a*a + b*b);
13243-}
13244-
13245-bool Util::isMember(cv::Mat image, int x, int y)
13246-{
13247- if (x < 0 || y < 0 || x >= image.cols || y >= image.rows) {
13248- return false;
13249- }
13250-
13251- if (image.at<uchar>(y, x) != 0) {
13252- return true;
13253- }
13254-
13255- return false;
13256-}
13257-int Util::getDistanceT(int x1, int y1, int x2, int y2)
13258-{
13259- return abs(y1 - y2) + abs(x2 - x1);
13260-}
13261-
13262-double Util::euclidianDistance3D(cv::Vec3f pt1, cv::Vec3f pt2)
13263-{
13264- double dx = pt1[0] - pt2[0];
13265- double dy = pt1[1] - pt2[1];
13266- double dz = pt1[2] - pt2[2];
13267-
13268- return sqrtf(dx*dx + dy*dy + dz*dz);
13269-}
13270-
13271-double Util::euclideanDistance2D(cv::Point pt1, cv::Point pt2)
13272-{
13273- double dx = pt1.x - pt2.x;
13274- double dy = pt1.y - pt2.y;
13275- return sqrtf(dx*dx + dy*dy);
13276-}
13277-
13278-double Util::euclideanDistancePerPixel(cv::Mat xyzMap, cv::Point pt, int radius)
13279-{
13280- int x = pt.x;
13281- int y = pt.y;
13282-
13283- int r_lower = (y - radius < 0) ? 0 : y - radius;
13284- int c_lower = (x - radius < 0) ? 0 : x - radius;
13285- int r_upper = (y + radius > xyzMap.rows) ? xyzMap.rows : y + radius;
13286- int c_upper = (x + radius > xyzMap.cols) ? xyzMap.cols : x + radius;
13287-
13288- int count = 0;
13289- double average = 0;
13290- for (int r = r_lower; r < r_upper; r++) {
13291- for (int c = c_lower; c < c_upper; c++) {
13292- if (xyzMap.at<cv::Vec3f>(r, c)[2] != 0) {
13293- double distance = euclideanDistance2D(pt, cv::Point(c, r));
13294- if (distance != 0) {
13295- average += euclidianDistance3D(xyzMap.at<cv::Vec3f>(pt.y, pt.x), xyzMap.at<cv::Vec3f>(r, c)) / distance;
13296- count++;
13297- }
13298- }
13299- }
13300- }
13301-
13302- if (average == 0) {
13303- return average;
13304- }
13305- return average / count;
13306-}
13307-
13308-cv::Mat Util::removePoints(cv::Mat img, std::vector<cv::Point2i> points)
13309-{
13310- cv::Mat result = img.clone();
13311- for (int i = 0; i < points.size(); i++) {
13312- int x = points[i].x;
13313- int y = points[i].y;
13314- result.at<cv::Vec3f>(y, x)[0] = 0;
13315- result.at<cv::Vec3f>(y, x)[1] = 0;
13316- result.at<cv::Vec3f>(y, x)[2] = 0;
13317- }
13318- return result;
13319-}
13320-
13321-cv::Vec3f Util::averageAroundPoint(cv::Mat xyzMap, cv::Point2i pt, int radius)
13322-{
13323- int x = pt.x;
13324- int y = pt.y;
13325-
13326- int r_lower = (y - radius < 0) ? 0 : y - radius;
13327- int c_lower = (x - radius < 0) ? 0 : x - radius;
13328- int r_upper = (y + radius > xyzMap.rows) ? xyzMap.rows : y + radius;
13329- int c_upper = (x + radius > xyzMap.cols) ? xyzMap.cols : x + radius;
13330-
13331- int count = 0;
13332- cv::Vec3f average;
13333- for (int r = r_lower; r < r_upper; r++) {
13334- for (int c = c_lower; c < c_upper; c++) {
13335- if (xyzMap.at<cv::Vec3f>(r, c)[2] != 0) {
13336- average[0] += xyzMap.at<cv::Vec3f>(r, c)[0];
13337- average[1] += xyzMap.at<cv::Vec3f>(r, c)[1];
13338- average[2] += xyzMap.at<cv::Vec3f>(r, c)[2];
13339- count++;
13340- }
13341- }
13342- }
13343-
13344- if (count == 0) {
13345- return 0;
13346- }
13347-
13348- average[0] /= count;
13349- average[1] /= count;
13350- average[2] /= count;
13351-
13352- return average;
13353-}
13354-
13355-cv::Point Util::findCentroid(cv::Mat xyzMap)
13356-{
13357- cv::Mat channels[3];
13358- cv::split(xyzMap, channels);
13359- cv::Moments m = cv::moments(channels[2], false);
13360- cv::Point center(m.m10 / m.m00, m.m01 / m.m00);
13361- return center;
13362-}
13363-
13364-//Function to find Lenght of sides of triangle
13365-double Util::DistanceTwoPoints(double x1, double y1, double x2, double y2)
13366-{
13367- double x, y, distance;
13368- x = x2 - x1;
13369- y = y2 - y1;
13370- distance = pow(x, 2) + pow(y, 2);
13371- distance = sqrt(distance);
13372- return distance;
13373-}
13374-
13375-//Function to find angle with Sine rule
13376-double Util::otherAngleFind(double biggerAngle, double largestDistance, double smallDistance)
13377-{
13378- double otherAngle;
13379- otherAngle = smallDistance *sin(biggerAngle*3.14159265 / 180);
13380- otherAngle = otherAngle / largestDistance;
13381- otherAngle = asin(otherAngle)*180.0 / PI;
13382- return otherAngle;
13383-}
13384-
13385-//Function to find angle opposite to largest side of triangle
13386-double Util::BiggerAngleFind(double largestDistance, double smallDistanceOne, double smallDistanceTwo)
13387-{
13388- double biggerAngle;
13389- biggerAngle = pow(smallDistanceOne, 2) + pow(smallDistanceTwo, 2) - pow(largestDistance, 2);
13390- biggerAngle = fabs(biggerAngle / (2 * smallDistanceOne*smallDistanceTwo));
13391- biggerAngle = acos(biggerAngle)* 180.0 / PI;
13392- return biggerAngle;
13393-}
13394-
13395-//Calculate angle of triangle given three coordinates c++ code
13396-double Util::TriangleAngleCalculation(double x1, double y1, double x2, double y2, double x3, double y3)
13397-{
13398- double dist1, dist2, dist3;
13399- double angle1, angle2, angle3;
13400- double total;
13401-
13402- int largestLength = 0;
13403- dist1 = DistanceTwoPoints(x1, y1, x2, y2);
13404- dist2 = DistanceTwoPoints(x2, y2, x3, y3);
13405- dist3 = DistanceTwoPoints(x1, y1, x3, y3);
13406-
13407- if (dist1>dist2 && dist1 > dist3)
13408- {
13409- //cout<<"dist1 is greater";
13410- angle1 = BiggerAngleFind(dist1, dist2, dist3);
13411- angle2 = otherAngleFind(angle1, dist1, dist2);
13412- angle3 = otherAngleFind(angle1, dist1, dist3);
13413-
13414- //angle2 = OtherAngleFind(angle1, dist1, dist2);
13415-
13416- total = angle1 + angle2 + angle3;
13417-
13418- if (total <180)
13419- {
13420- angle1 = 180 - angle1;
13421- }
13422- }
13423- else if (dist2 > dist3 && dist2 > dist1)
13424- {
13425- // cout<<"dist2 is greater";
13426- angle2 = BiggerAngleFind(dist2, dist1, dist3);
13427- angle1 = otherAngleFind(angle2, dist2, dist1);
13428- angle3 = otherAngleFind(angle2, dist2, dist3);
13429-
13430- total = angle1 + angle2 + angle3;
13431-
13432- if (total <180)
13433- {
13434- angle2 = 180 - angle2;
13435- }
13436- }
13437- else
13438- {
13439- // cout<<"dist3 is greater";
13440- angle3 = BiggerAngleFind(dist3, dist1, dist2);
13441- angle1 = otherAngleFind(angle3, dist3, dist2);
13442- angle2 = otherAngleFind(angle3, dist3, dist2);
13443-
13444- total = angle1 + angle2 + angle3;
13445-
13446- if (total <180)
13447- {
13448- angle3 = 180 - angle3;
13449- }
13450- }
13451-
13452- //cout << endl << "Angle Between First Point and Second Point = " << angle3 << endl;
13453- //cout << "Angle Between First Point and Third Point = " << angle2 << endl;
13454- //cout << "Angle Between Second Point and Third Point = " << angle1 << endl;
13455- return angle2;
13456-}
13457-
13458-/***
13459-Recursively performs floodfill on depthMap
13460-***/
13461-void Util::floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)
13462-{
13463- if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] == 0.0)
13464- return;
13465- if (closeEnough(x, y, depthMap, 4, max_distance)) {
13466- mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
13467- depthMap.at<cv::Vec3f>(y, x)[0] = 0;
13468- depthMap.at<cv::Vec3f>(y, x)[1] = 0;
13469- depthMap.at<cv::Vec3f>(y, x)[2] = 0;
13470- }
13471- else {
13472- return;
13473- }
13474-
13475- floodFill(x + 1, y, depthMap, mask, max_distance);
13476- floodFill(x - 1, y, depthMap, mask, max_distance);
13477- floodFill(x, y + 1, depthMap, mask, max_distance);
13478- floodFill(x, y - 1, depthMap, mask, max_distance);
13479-}
13480-
13481-/***
13482-Check whether candidate point is close enough to neighboring points
13483-***/
13484-bool Util::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)
13485-{
13486- int num_close = 0;
13487- if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) {
13488- num_close++;
13489- }
13490- if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) {
13491- num_close++;
13492- }
13493- if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) {
13494- num_close++;
13495- }
13496- if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) {
13497- num_close++;
13498- }
13499-
13500- if (num_close >= num_neighbors) {
13501- return true;
13502- }
13503-
13504- return false;
13505+#include "Util.h"
13506+
13507+cv::Vec3b Util::colorGenerator2()
13508+{
13509+ return cv::Vec3b(rand() % 256, rand() % 256, rand() % 256);
13510+}
13511+
13512+float Util::normalize(float a, float b)
13513+{
13514+ return sqrt(a*a + b*b);
13515+}
13516+
13517+bool Util::isMember(cv::Mat image, int x, int y)
13518+{
13519+ if (x < 0 || y < 0 || x >= image.cols || y >= image.rows) {
13520+ return false;
13521+ }
13522+
13523+ if (image.at<uchar>(y, x) != 0) {
13524+ return true;
13525+ }
13526+
13527+ return false;
13528+}
13529+int Util::getDistanceT(int x1, int y1, int x2, int y2)
13530+{
13531+ return abs(y1 - y2) + abs(x2 - x1);
13532+}
13533+
13534+double Util::euclidianDistance3D(cv::Vec3f pt1, cv::Vec3f pt2)
13535+{
13536+ double dx = pt1[0] - pt2[0];
13537+ double dy = pt1[1] - pt2[1];
13538+ double dz = pt1[2] - pt2[2];
13539+
13540+ return sqrtf(dx*dx + dy*dy + dz*dz);
13541+}
13542+
13543+double Util::euclideanDistance2D(cv::Point pt1, cv::Point pt2)
13544+{
13545+ double dx = pt1.x - pt2.x;
13546+ double dy = pt1.y - pt2.y;
13547+ return sqrtf(dx*dx + dy*dy);
13548+}
13549+
13550+double Util::euclideanDistancePerPixel(cv::Mat xyzMap, cv::Point pt, int radius)
13551+{
13552+ int x = pt.x;
13553+ int y = pt.y;
13554+
13555+ int r_lower = (y - radius < 0) ? 0 : y - radius;
13556+ int c_lower = (x - radius < 0) ? 0 : x - radius;
13557+ int r_upper = (y + radius > xyzMap.rows) ? xyzMap.rows : y + radius;
13558+ int c_upper = (x + radius > xyzMap.cols) ? xyzMap.cols : x + radius;
13559+
13560+ int count = 0;
13561+ double average = 0;
13562+ for (int r = r_lower; r < r_upper; r++) {
13563+ for (int c = c_lower; c < c_upper; c++) {
13564+ if (xyzMap.at<cv::Vec3f>(r, c)[2] != 0) {
13565+ double distance = euclideanDistance2D(pt, cv::Point(c, r));
13566+ if (distance != 0) {
13567+ average += euclidianDistance3D(xyzMap.at<cv::Vec3f>(pt.y, pt.x), xyzMap.at<cv::Vec3f>(r, c)) / distance;
13568+ count++;
13569+ }
13570+ }
13571+ }
13572+ }
13573+
13574+ if (average == 0) {
13575+ return average;
13576+ }
13577+ return average / count;
13578+}
13579+
13580+cv::Mat Util::removePoints(cv::Mat img, std::vector<cv::Point2i> points)
13581+{
13582+ cv::Mat result = img.clone();
13583+ for (int i = 0; i < points.size(); i++) {
13584+ int x = points[i].x;
13585+ int y = points[i].y;
13586+ result.at<cv::Vec3f>(y, x)[0] = 0;
13587+ result.at<cv::Vec3f>(y, x)[1] = 0;
13588+ result.at<cv::Vec3f>(y, x)[2] = 0;
13589+ }
13590+ return result;
13591+}
13592+
13593+cv::Vec3f Util::averageAroundPoint(cv::Mat xyzMap, cv::Point2i pt, int radius)
13594+{
13595+ int x = pt.x;
13596+ int y = pt.y;
13597+
13598+ int r_lower = (y - radius < 0) ? 0 : y - radius;
13599+ int c_lower = (x - radius < 0) ? 0 : x - radius;
13600+ int r_upper = (y + radius > xyzMap.rows) ? xyzMap.rows : y + radius;
13601+ int c_upper = (x + radius > xyzMap.cols) ? xyzMap.cols : x + radius;
13602+
13603+ int count = 0;
13604+ cv::Vec3f average;
13605+ for (int r = r_lower; r < r_upper; r++) {
13606+ for (int c = c_lower; c < c_upper; c++) {
13607+ if (xyzMap.at<cv::Vec3f>(r, c)[2] != 0) {
13608+ average[0] += xyzMap.at<cv::Vec3f>(r, c)[0];
13609+ average[1] += xyzMap.at<cv::Vec3f>(r, c)[1];
13610+ average[2] += xyzMap.at<cv::Vec3f>(r, c)[2];
13611+ count++;
13612+ }
13613+ }
13614+ }
13615+
13616+ if (count == 0) {
13617+ return 0;
13618+ }
13619+
13620+ average[0] /= count;
13621+ average[1] /= count;
13622+ average[2] /= count;
13623+
13624+ return average;
13625+}
13626+
13627+cv::Point Util::findCentroid(cv::Mat xyzMap)
13628+{
13629+ cv::Mat channels[3];
13630+ cv::split(xyzMap, channels);
13631+ cv::Moments m = cv::moments(channels[2], false);
13632+ cv::Point center(m.m10 / m.m00, m.m01 / m.m00);
13633+ return center;
13634+}
13635+
13636+//Function to find Lenght of sides of triangle
13637+double Util::DistanceTwoPoints(double x1, double y1, double x2, double y2)
13638+{
13639+ double x, y, distance;
13640+ x = x2 - x1;
13641+ y = y2 - y1;
13642+ distance = pow(x, 2) + pow(y, 2);
13643+ distance = sqrt(distance);
13644+ return distance;
13645+}
13646+
13647+//Function to find angle with Sine rule
13648+double Util::otherAngleFind(double biggerAngle, double largestDistance, double smallDistance)
13649+{
13650+ double otherAngle;
13651+ otherAngle = smallDistance *sin(biggerAngle*3.14159265 / 180);
13652+ otherAngle = otherAngle / largestDistance;
13653+ otherAngle = asin(otherAngle)*180.0 / PI;
13654+ return otherAngle;
13655+}
13656+
13657+//Function to find angle opposite to largest side of triangle
13658+double Util::BiggerAngleFind(double largestDistance, double smallDistanceOne, double smallDistanceTwo)
13659+{
13660+ double biggerAngle;
13661+ biggerAngle = pow(smallDistanceOne, 2) + pow(smallDistanceTwo, 2) - pow(largestDistance, 2);
13662+ biggerAngle = fabs(biggerAngle / (2 * smallDistanceOne*smallDistanceTwo));
13663+ biggerAngle = acos(biggerAngle)* 180.0 / PI;
13664+ return biggerAngle;
13665+}
13666+
13667+//Calculate angle of triangle given three coordinates c++ code
13668+double Util::TriangleAngleCalculation(double x1, double y1, double x2, double y2, double x3, double y3)
13669+{
13670+ double dist1, dist2, dist3;
13671+ double angle1, angle2, angle3;
13672+ double total;
13673+
13674+ int largestLength = 0;
13675+ dist1 = DistanceTwoPoints(x1, y1, x2, y2);
13676+ dist2 = DistanceTwoPoints(x2, y2, x3, y3);
13677+ dist3 = DistanceTwoPoints(x1, y1, x3, y3);
13678+
13679+ if (dist1>dist2 && dist1 > dist3)
13680+ {
13681+ //cout<<"dist1 is greater";
13682+ angle1 = BiggerAngleFind(dist1, dist2, dist3);
13683+ angle2 = otherAngleFind(angle1, dist1, dist2);
13684+ angle3 = otherAngleFind(angle1, dist1, dist3);
13685+
13686+ //angle2 = OtherAngleFind(angle1, dist1, dist2);
13687+
13688+ total = angle1 + angle2 + angle3;
13689+
13690+ if (total <180)
13691+ {
13692+ angle1 = 180 - angle1;
13693+ }
13694+ }
13695+ else if (dist2 > dist3 && dist2 > dist1)
13696+ {
13697+ // cout<<"dist2 is greater";
13698+ angle2 = BiggerAngleFind(dist2, dist1, dist3);
13699+ angle1 = otherAngleFind(angle2, dist2, dist1);
13700+ angle3 = otherAngleFind(angle2, dist2, dist3);
13701+
13702+ total = angle1 + angle2 + angle3;
13703+
13704+ if (total <180)
13705+ {
13706+ angle2 = 180 - angle2;
13707+ }
13708+ }
13709+ else
13710+ {
13711+ // cout<<"dist3 is greater";
13712+ angle3 = BiggerAngleFind(dist3, dist1, dist2);
13713+ angle1 = otherAngleFind(angle3, dist3, dist2);
13714+ angle2 = otherAngleFind(angle3, dist3, dist2);
13715+
13716+ total = angle1 + angle2 + angle3;
13717+
13718+ if (total <180)
13719+ {
13720+ angle3 = 180 - angle3;
13721+ }
13722+ }
13723+
13724+ //cout << endl << "Angle Between First Point and Second Point = " << angle3 << endl;
13725+ //cout << "Angle Between First Point and Third Point = " << angle2 << endl;
13726+ //cout << "Angle Between Second Point and Third Point = " << angle1 << endl;
13727+ return angle2;
13728+}
13729+
13730+/***
13731+Recursively performs floodfill on depthMap
13732+***/
13733+void Util::floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)
13734+{
13735+ if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] == 0.0)
13736+ return;
13737+ if (closeEnough(x, y, depthMap, 4, max_distance)) {
13738+ mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
13739+ depthMap.at<cv::Vec3f>(y, x)[0] = 0;
13740+ depthMap.at<cv::Vec3f>(y, x)[1] = 0;
13741+ depthMap.at<cv::Vec3f>(y, x)[2] = 0;
13742+ }
13743+ else {
13744+ return;
13745+ }
13746+
13747+ floodFill(x + 1, y, depthMap, mask, max_distance);
13748+ floodFill(x - 1, y, depthMap, mask, max_distance);
13749+ floodFill(x, y + 1, depthMap, mask, max_distance);
13750+ floodFill(x, y - 1, depthMap, mask, max_distance);
13751+}
13752+
13753+/***
13754+Check whether candidate point is close enough to neighboring points
13755+***/
13756+bool Util::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)
13757+{
13758+ int num_close = 0;
13759+ if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) {
13760+ num_close++;
13761+ }
13762+ if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) {
13763+ num_close++;
13764+ }
13765+ if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) {
13766+ num_close++;
13767+ }
13768+ if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) {
13769+ num_close++;
13770+ }
13771+
13772+ if (num_close >= num_neighbors) {
13773+ return true;
13774+ }
13775+
13776+ return false;
13777 }
13778\ No newline at end of file
13779diff --git a/Util.h b/Util.h
13780index 0bbe24a..b33b9a4 100644
13781--- a/Util.h
13782+++ b/Util.h
13783@@ -1,108 +1,108 @@
13784-#pragma once
13785-// OpenCV Libraries
13786-#include "opencv2/imgproc/imgproc.hpp"
13787-
13788-// Constants Redefined
13789-#ifndef M_PI
13790- #define M_PI 3.14159265358979323846
13791- #define PI 3.14159265;
13792-#endif
13793-
13794-/**
13795-* Class containing generic helper functions.
13796-*/
13797-class Util
13798-{
13799-public:
13800-
13801- /**
13802- * Generates a random RGB color.
13803- * @return random RGB color in Vec3b format
13804- */
13805- static cv::Vec3b colorGenerator2();
13806-
13807- /**
13808- * Get euclidean distance between two 2D points.
13809- * @param x1 x-coordinate of point 1
13810- * @param y1 y-coordinate of point 1
13811- * @param x2 x-coordinate of point 2
13812- * @param y2 y-coordinate of point 2
13813- * @return the euclidean distance
13814- */
13815- static int getDistanceT(int x1, int y1, int x2, int y2);
13816-
13817- /**
13818- * Return the hypotenuse length.
13819- * @param a leg length
13820- * @param b leg length
13821- * return hypotenuse length
13822- */
13823- static float normalize(float a, float b);
13824-
13825- /*
13826- * Compute the euclidean distance between (x1,y1) and (x2,y2)
13827- * @param p1 (x1, y1)
13828- * @param p2 (x2, y2)
13829- * @return the euclidean distance between the two points
13830- */
13831- static double euclideanDistance2D(cv::Point p1, cv::Point pt2);
13832-
13833- /**
13834- * Get euclidean distance between two 3D points.
13835- * @param pt1 point 1
13836- * @param pt2 point 2
13837- * @return euclidean distance
13838- */
13839- static double euclidianDistance3D(cv::Vec3f pt1, cv::Vec3f pt2);
13840-
13841- static double euclideanDistancePerPixel(cv::Mat xyzMap, cv::Point pt, int radius);
13842-
13843- /**
13844- * Removes points on img with indicies defined in points.
13845- * @param img the input image
13846- * @param points list of indicies (i,j) to be set to 0
13847- * @return processed image
13848- */
13849- static cv::Mat removePoints(cv::Mat img, std::vector<cv::Point2i> points);
13850-
13851- /**
13852- * Average all non-zero values around a point.
13853- * @param img base image to use
13854- * @param pt the point of interest
13855- * @param radius number of neighboring points to be used for computing the average
13856- * @return average (x,y,z) value of the point of interest
13857- */
13858- static cv::Vec3f averageAroundPoint(cv::Mat img, cv::Point2i pt, int radius);
13859-
13860- /**
13861- * Determine whether (x,y) is a non-zero point in the matrix.
13862- * @param xyzMap Input image
13863- * @param x x-coordinate of the point
13864- * @param y y-coordinate of the point
13865- * @return true if (x.y) is non-zero
13866- */
13867- static bool isMember(cv::Mat xyzMap, int x, int y);
13868-
13869- /*
13870- * Find the centroid of the point cloud
13871- * @param xyzMap input point cloud
13872- * @return (x,y) coordinate of the centroid
13873- */
13874- static cv::Point findCentroid(cv::Mat xyzMap);
13875-
13876- /*
13877- * Compute the angle formed by 3 points
13878- * @return the angle formed
13879- */
13880- static double TriangleAngleCalculation(double x1, double y1, double x2, double y2, double x3, double y3);
13881-
13882- static void floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance);
13883-
13884-
13885-private:
13886- static double DistanceTwoPoints(double x1, double y1, double x2, double y2);
13887- static double otherAngleFind(double biggerAngle, double largestDistance, double smallDistance);
13888- static double BiggerAngleFind(double largestDistance, double smallDistanceOne, double smallDistanceTwo);
13889- static bool Util::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance);
13890-
13891+#pragma once
13892+// OpenCV Libraries
13893+#include <opencv/cxcore.h>
13894+#include "opencv2/imgproc/imgproc.hpp"
13895+
13896+// Constants Redefined
13897+#ifndef M_PI
13898+ #define M_PI 3.14159265358979323846
13899+ #define PI 3.14159265;
13900+#endif
13901+
13902+/**
13903+* Class containing generic helper functions.
13904+*/
13905+class Util
13906+{
13907+public:
13908+ /**
13909+ * Generates a random RGB color.
13910+ * @return random RGB color in Vec3b format
13911+ */
13912+ static cv::Vec3b colorGenerator2();
13913+
13914+ /**
13915+ * Get euclidean distance between two 2D points.
13916+ * @param x1 x-coordinate of point 1
13917+ * @param y1 y-coordinate of point 1
13918+ * @param x2 x-coordinate of point 2
13919+ * @param y2 y-coordinate of point 2
13920+ * @return the euclidean distance
13921+ */
13922+ static int getDistanceT(int x1, int y1, int x2, int y2);
13923+
13924+ /**
13925+ * Return the hypotenuse length.
13926+ * @param a leg length
13927+ * @param b leg length
13928+ * return hypotenuse length
13929+ */
13930+ static float normalize(float a, float b);
13931+
13932+ /*
13933+ * Compute the euclidean distance between (x1,y1) and (x2,y2)
13934+ * @param p1 (x1, y1)
13935+ * @param p2 (x2, y2)
13936+ * @return the euclidean distance between the two points
13937+ */
13938+ static double euclideanDistance2D(cv::Point p1, cv::Point pt2);
13939+
13940+ /**
13941+ * Get euclidean distance between two 3D points.
13942+ * @param pt1 point 1
13943+ * @param pt2 point 2
13944+ * @return euclidean distance
13945+ */
13946+ static double euclidianDistance3D(cv::Vec3f pt1, cv::Vec3f pt2);
13947+
13948+ static double euclideanDistancePerPixel(cv::Mat xyzMap, cv::Point pt, int radius);
13949+
13950+ /**
13951+ * Removes points on img with indicies defined in points.
13952+ * @param img the input image
13953+ * @param points list of indicies (i,j) to be set to 0
13954+ * @return processed image
13955+ */
13956+ static cv::Mat removePoints(cv::Mat img, std::vector<cv::Point2i> points);
13957+
13958+ /**
13959+ * Average all non-zero values around a point.
13960+ * @param img base image to use
13961+ * @param pt the point of interest
13962+ * @param radius number of neighboring points to be used for computing the average
13963+ * @return average (x,y,z) value of the point of interest
13964+ */
13965+ static cv::Vec3f averageAroundPoint(cv::Mat img, cv::Point2i pt, int radius);
13966+
13967+ /**
13968+ * Determine whether (x,y) is a non-zero point in the matrix.
13969+ * @param xyzMap Input image
13970+ * @param x x-coordinate of the point
13971+ * @param y y-coordinate of the point
13972+ * @return true if (x.y) is non-zero
13973+ */
13974+ static bool isMember(cv::Mat xyzMap, int x, int y);
13975+
13976+ /*
13977+ * Find the centroid of the point cloud
13978+ * @param xyzMap input point cloud
13979+ * @return (x,y) coordinate of the centroid
13980+ */
13981+ static cv::Point findCentroid(cv::Mat xyzMap);
13982+
13983+ /*
13984+ * Compute the angle formed by 3 points
13985+ * @return the angle formed
13986+ */
13987+ static double TriangleAngleCalculation(double x1, double y1, double x2, double y2, double x3, double y3);
13988+
13989+ static void floodFill(int x, int y, cv::Mat& depthMap, cv::Mat& mask, double max_distance);
13990+
13991+
13992+private:
13993+ static double DistanceTwoPoints(double x1, double y1, double x2, double y2);
13994+ static double otherAngleFind(double biggerAngle, double largestDistance, double smallDistance);
13995+ static double BiggerAngleFind(double largestDistance, double smallDistanceOne, double smallDistanceTwo);
13996+ static bool Util::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance);
13997+
13998 };
13999\ No newline at end of file
14000diff --git a/Visualizer.cpp b/Visualizer.cpp
14001index 82aaabc..91e534d 100644
14002--- a/Visualizer.cpp
14003+++ b/Visualizer.cpp
14004@@ -1,159 +1,158 @@
14005-#include "Visualizer.h"
14006-
14007-pcl::visualization::PCLVisualizer Visualizer::viewer = pcl::visualization::PCLVisualizer("Point Cloud");
14008-
14009-/***
14010-Maps matrix values to [0, 255] for viewing
14011-***/
14012-cv::Mat Visualizer::visualizeMatrix(cv::Mat &input)
14013-{
14014- cv::Mat img;
14015- cv::normalize(input, img, 0, 255, cv::NORM_MINMAX, CV_8UC3);
14016- return img;
14017-}
14018-
14019-/***
14020-RGB depth map visualization
14021-***/
14022-cv::Mat Visualizer::visualizeDepthMap(cv::Mat &depthMap)
14023-{
14024- cv::Mat img;
14025- cv::normalize(depthMap, img, 0, 255, cv::NORM_MINMAX, CV_8UC1);
14026- cv::applyColorMap(img, img, cv::COLORMAP_HOT);
14027- return img;
14028-}
14029-
14030-cv::Mat Visualizer::visualizeXYZMap(cv::Mat &xyzMap)
14031-{
14032- cv::Mat channels[3];
14033- cv::split(xyzMap, channels);
14034- return visualizeDepthMap(channels[2]);
14035-}
14036-
14037-cv::Mat Visualizer::visualizeHand(cv::Mat xyzMap, cv::Point2i finger, cv::Point2i centroid)
14038-{
14039- cv::Mat displayImg;
14040- if (xyzMap.type() == CV_32FC3) {
14041- displayImg = Visualizer::visualizeXYZMap(xyzMap);
14042- }
14043- else {
14044- displayImg = xyzMap;
14045- }
14046-
14047- cv::circle(displayImg, cv::Point(finger.x, finger.y), 2, cv::Scalar(0, 255, 255), 2);
14048- cv::circle(displayImg, cv::Point(centroid.x, centroid.y), 2, cv::Scalar(0, 255, 0), 2);
14049- return displayImg;
14050-}
14051-
14052-void Visualizer::visualizeCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
14053-{
14054- viewer.setBackgroundColor(0, 0, 0);
14055- if (!viewer.updatePointCloud(cloud))
14056- viewer.addPointCloud(cloud);
14057- viewer.spinOnce();
14058-}
14059-
14060-cv::Mat Visualizer::visualizePlaneRegression(cv::Mat &input_mat, std::vector<double> &equation, const double threshold, bool clicked)
14061-{
14062- cv::Mat output_mat;
14063- if (input_mat.type() == CV_32FC3) {
14064- output_mat = Visualizer::visualizeXYZMap(input_mat);
14065- }
14066- else {
14067- output_mat = input_mat;
14068- }
14069-
14070- if (equation.size() < 3)
14071- {
14072- return output_mat;
14073- }
14074- int rowSize = input_mat.rows;
14075- int colSize = input_mat.cols;
14076- cv::Scalar color;
14077- if (clicked) {
14078- color = cv::Scalar(255, 255, 0);
14079- }
14080- else {
14081- color = cv::Scalar(0, 255, 0);
14082- }
14083-
14084- int pointsDetected = 0;
14085- for (int r = 0; r < rowSize; r++) {
14086- for (int c = 0; c < colSize; c++) {
14087- double x = input_mat.at<cv::Vec3f>(r, c)[0];
14088- double y = input_mat.at<cv::Vec3f>(r, c)[1];
14089- double z = input_mat.at<cv::Vec3f>(r, c)[2];
14090-
14091- if (z == 0) {
14092- continue;
14093- }
14094-
14095- double z_hat = equation[0] * x + equation[1] * y + equation[2];
14096- double r_squared = (z - z_hat) * (z - z_hat);
14097-
14098- if (r_squared < threshold) {
14099- cv::circle(output_mat, cv::Point(c, r), 1, color, -1);
14100- pointsDetected++;
14101- }
14102- }
14103- }
14104- return output_mat;
14105-}
14106-
14107-void Visualizer::visualizePlanePoints(cv::Mat &input_mat, std::vector<cv::Point2i> indicies)
14108-{
14109- for (int i = 0; i < indicies.size(); i++) {
14110- input_mat.at<uchar>(indicies[i].y, indicies[i].x) = (uchar)255;
14111- }
14112-}
14113-
14114-void Visualizer::visulizePolygonMesh(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
14115-{
14116- if (cloud.get()->width == 0) {
14117- return;
14118- }
14119- // Normal estimation*
14120- pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
14121- pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
14122- pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
14123- tree->setInputCloud(cloud);
14124- n.setInputCloud(cloud);
14125- n.setSearchMethod(tree);
14126- n.setKSearch(20);
14127- n.compute(*normals);
14128- //* normals should not contain the point normals + surface curvatures
14129-
14130- // Concatenate the XYZ and normal fields*
14131- pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
14132- pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
14133- //* cloud_with_normals = cloud + normals
14134-
14135- // Create search tree*
14136- pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
14137- tree2->setInputCloud(cloud_with_normals);
14138-
14139- // Initialize objects
14140- pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
14141- pcl::PolygonMesh triangles;
14142-
14143- // Set the maximum distance between connected points (maximum edge length)
14144- gp3.setSearchRadius(0.025);
14145-
14146- // Set typical values for the parameters
14147- gp3.setMu(2.5);
14148- gp3.setMaximumNearestNeighbors(100);
14149- gp3.setMaximumSurfaceAngle(M_PI / 4); // 45 degrees
14150- gp3.setMinimumAngle(M_PI / 18); // 10 degrees
14151- gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
14152- gp3.setNormalConsistency(false);
14153-
14154- // Get result
14155- gp3.setInputCloud(cloud_with_normals);
14156- gp3.setSearchMethod(tree2);
14157- gp3.reconstruct(triangles);
14158-
14159- viewer.setBackgroundColor(0, 0, 0);
14160- if (!viewer.updatePolygonMesh(triangles))
14161- viewer.addPolygonMesh(triangles);
14162- viewer.spinOnce();
14163+#include "Visualizer.h"
14164+
14165+pcl::visualization::PCLVisualizer Visualizer::viewer = pcl::visualization::PCLVisualizer("Point Cloud");
14166+
14167+/***
14168+Maps matrix values to [0, 255] for viewing
14169+***/
14170+cv::Mat Visualizer::visualizeMatrix(cv::Mat &input)
14171+{
14172+ cv::Mat img;
14173+ cv::normalize(input, img, 0, 255, cv::NORM_MINMAX, CV_8UC3);
14174+ return img;
14175+}
14176+
14177+/***
14178+RGB depth map visualization
14179+***/
14180+cv::Mat Visualizer::visualizeDepthMap(cv::Mat &depthMap)
14181+{
14182+ cv::Mat img;
14183+ cv::normalize(depthMap, img, 0, 255, cv::NORM_MINMAX, CV_8UC1);
14184+ cv::applyColorMap(img, img, cv::COLORMAP_HOT);
14185+ return img;
14186+}
14187+
14188+cv::Mat Visualizer::visualizeXYZMap(cv::Mat &xyzMap)
14189+{
14190+ cv::Mat channels[3];
14191+ cv::split(xyzMap, channels);
14192+ return visualizeDepthMap(channels[2]);
14193+}
14194+
14195+cv::Mat Visualizer::visualizeHand(cv::Mat xyzMap, cv::Point2i finger, cv::Point2i centroid)
14196+{
14197+ cv::Mat displayImg;
14198+ if (xyzMap.type() == CV_32FC3) {
14199+ displayImg = Visualizer::visualizeXYZMap(xyzMap);
14200+ }
14201+ else {
14202+ displayImg = xyzMap;
14203+ }
14204+
14205+ cv::circle(displayImg, cv::Point(finger.x, finger.y), 2, cv::Scalar(0, 255, 255), 2);
14206+ cv::circle(displayImg, cv::Point(centroid.x, centroid.y), 2, cv::Scalar(0, 255, 0), 2);
14207+ return displayImg;
14208+}
14209+
14210+void Visualizer::visualizeCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
14211+{
14212+ viewer.setBackgroundColor(0, 0, 0);
14213+ if (!viewer.updatePointCloud(cloud))
14214+ viewer.addPointCloud(cloud);
14215+ viewer.spinOnce();
14216+}
14217+
14218+cv::Mat Visualizer::visualizePlaneRegression(cv::Mat &input_mat, std::vector<double> &equation, const double threshold, bool clicked)
14219+{
14220+ cv::Mat output_mat;
14221+ if (input_mat.type() == CV_32FC3) {
14222+ output_mat = Visualizer::visualizeXYZMap(input_mat);
14223+ } else {
14224+ output_mat = input_mat;
14225+ }
14226+
14227+ if (equation.size() < 3)
14228+ {
14229+ return output_mat;
14230+ }
14231+ int rowSize = input_mat.rows;
14232+ int colSize = input_mat.cols;
14233+ cv::Scalar color;
14234+ if (clicked) {
14235+ color = cv::Scalar(255, 255, 0);
14236+ }
14237+ else {
14238+ color = cv::Scalar(0, 255, 0);
14239+ }
14240+
14241+ int pointsDetected = 0;
14242+ for (int r = 0; r < rowSize; r++) {
14243+ for (int c = 0; c < colSize; c++) {
14244+ double x = input_mat.at<cv::Vec3f>(r, c)[0];
14245+ double y = input_mat.at<cv::Vec3f>(r, c)[1];
14246+ double z = input_mat.at<cv::Vec3f>(r, c)[2];
14247+
14248+ if (z == 0) {
14249+ continue;
14250+ }
14251+
14252+ double z_hat = equation[0] * x + equation[1] * y + equation[2];
14253+ double r_squared = (z - z_hat) * (z - z_hat);
14254+
14255+ if (r_squared < threshold) {
14256+ cv::circle(output_mat, cv::Point(c, r), 1, color, -1);
14257+ pointsDetected++;
14258+ }
14259+ }
14260+ }
14261+ return output_mat;
14262+}
14263+
14264+void Visualizer::visualizePlanePoints(cv::Mat &input_mat, std::vector<cv::Point2i> indicies)
14265+{
14266+ for (int i = 0; i < indicies.size(); i++) {
14267+ input_mat.at<uchar>(indicies[i].y, indicies[i].x) = (uchar) 255;
14268+ }
14269+}
14270+
14271+void Visualizer::visulizePolygonMesh(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
14272+{
14273+ if (cloud.get()->width == 0) {
14274+ return;
14275+ }
14276+ // Normal estimation*
14277+ pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
14278+ pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
14279+ pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
14280+ tree->setInputCloud(cloud);
14281+ n.setInputCloud(cloud);
14282+ n.setSearchMethod(tree);
14283+ n.setKSearch(20);
14284+ n.compute(*normals);
14285+ //* normals should not contain the point normals + surface curvatures
14286+
14287+ // Concatenate the XYZ and normal fields*
14288+ pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
14289+ pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
14290+ //* cloud_with_normals = cloud + normals
14291+
14292+ // Create search tree*
14293+ pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
14294+ tree2->setInputCloud(cloud_with_normals);
14295+
14296+ // Initialize objects
14297+ pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
14298+ pcl::PolygonMesh triangles;
14299+
14300+ // Set the maximum distance between connected points (maximum edge length)
14301+ gp3.setSearchRadius(0.025);
14302+
14303+ // Set typical values for the parameters
14304+ gp3.setMu(2.5);
14305+ gp3.setMaximumNearestNeighbors(100);
14306+ gp3.setMaximumSurfaceAngle(M_PI / 4); // 45 degrees
14307+ gp3.setMinimumAngle(M_PI / 18); // 10 degrees
14308+ gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
14309+ gp3.setNormalConsistency(false);
14310+
14311+ // Get result
14312+ gp3.setInputCloud(cloud_with_normals);
14313+ gp3.setSearchMethod(tree2);
14314+ gp3.reconstruct(triangles);
14315+
14316+ viewer.setBackgroundColor(0, 0, 0);
14317+ if (!viewer.updatePolygonMesh(triangles))
14318+ viewer.addPolygonMesh(triangles);
14319+ viewer.spinOnce();
14320 }
14321\ No newline at end of file
14322diff --git a/Visualizer.h b/Visualizer.h
14323index d716c12..8eae51d 100644
14324--- a/Visualizer.h
14325+++ b/Visualizer.h
14326@@ -1,91 +1,90 @@
14327-#pragma once
14328-//OpenCV Libraries
14329-#include <opencv2/core/core.hpp>
14330-#include <opencv2/highgui/highgui.hpp>
14331-#include <opencv2/core.hpp>
14332-#include <opencv2/imgproc.hpp>
14333-#include <opencv2/imgcodecs.hpp>
14334-#include <opencv2/highgui.hpp>
14335-
14336-// PCL Libraries
14337-#include <pcl/point_types.h>
14338-#include <pcl/io/pcd_io.h>
14339-#include <pcl/kdtree/kdtree_flann.h>
14340-#include <pcl/features/normal_3d.h>
14341-#include <pcl/surface/gp3.h>
14342-#include <pcl/visualization/cloud_viewer.h>
14343-
14344-/**
14345-* Utility class containing various conversions and visualization techniques.
14346-*/
14347-class Visualizer
14348-{
14349-public:
14350- /**
14351- * Visualization for xyzMap.
14352- * @param [in] xyzMap input point cloud matrix
14353- * @return a CV_8UC3 representation of the xyzMap
14354- */
14355- static cv::Mat visualizeXYZMap(cv::Mat &xyzMap);
14356-
14357- /**
14358- * Visualization for hand object.
14359- * @param [in] xyzMap the base image to draw on
14360- * @param [in] finger (i,j) coordinates of the finger
14361- * @param [in] centroid (i,j) coordinates of the centroid
14362- * @return a CV_8UC3 matrix with the hand points drawn
14363- */
14364- static cv::Mat visualizeHand(cv::Mat xyzMap, cv::Point2i finger, cv::Point2i centroid);
14365-
14366- /**
14367- * Visualization for PCL point cloud.
14368- * @param [in] cloud PCL point cloud to be visualized
14369- */
14370- static void visualizeCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
14371-
14372- /**
14373- * Visualization for polygon mesh.
14374- * Visualize a PCL point cloud as a polygon mesh
14375- * @param [in] cloud PCL point cloud to be visualized
14376- */
14377- static void visulizePolygonMesh(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
14378-
14379- /**
14380- * Visualization for plane regression.
14381- * @param [in] input_mat the base xyzMap on which to draw the visualization
14382- * @param [in] equation equation of the plane
14383- * @param threshold maximum error distance (mm) allowed for points to be considered covered by regression equation
14384- * @param clicked whether the finger is currently current contacting the regression equation. Default is FALSE
14385- * @return a CV_8UC3 representation of the matrix with the regression plane drawn
14386- */
14387- static cv::Mat visualizePlaneRegression(cv::Mat &input_mat, std::vector<double> &equation, const double threshold, bool clicked = false);
14388-
14389- /*
14390- * Visualize points that lie on the plane.
14391- * @param input_mat the input point cloud
14392- * @indicies (i,j) coordinates of the points belonging to the plane
14393- */
14394- static void visualizePlanePoints(cv::Mat &input_mat, std::vector<cv::Point2i> indicies);
14395- static cv::Mat visualizeDepthMap(cv::Mat &depthMap);
14396-
14397-private:
14398-
14399- /**
14400- * Visualization for a generic matrix.
14401- * @param [in] input matrix to be visualized
14402- * @return a CV_8UC3 representation of the input matrix
14403- */
14404- static cv::Mat visualizeMatrix(cv::Mat &input);
14405-
14406- /**
14407- * Visualization for a depth map matrix (i,j,z).
14408- * @param [in] depthMap matrix to be visualized
14409- * @return a CV_8UC3 representation of the input matrix
14410- */
14411-
14412-
14413- /**
14414- * PCL point cloud viewer
14415- */
14416- static pcl::visualization::PCLVisualizer viewer;
14417+#pragma once
14418+//OpenCV Libraries
14419+#include <opencv2/core/core.hpp>
14420+#include <opencv2/highgui/highgui.hpp>
14421+#include <opencv2/core.hpp>
14422+#include <opencv2/imgproc.hpp>
14423+#include <opencv2/imgcodecs.hpp>
14424+#include <opencv2/highgui.hpp>
14425+
14426+// PCL Libraries
14427+#include <pcl/point_types.h>
14428+#include <pcl/io/pcd_io.h>
14429+#include <pcl/kdtree/kdtree_flann.h>
14430+#include <pcl/features/normal_3d.h>
14431+#include <pcl/surface/gp3.h>
14432+#include <pcl/visualization/cloud_viewer.h>
14433+
14434+/**
14435+* Utility class containing various conversions and visualization techniques.
14436+*/
14437+class Visualizer
14438+{
14439+public:
14440+ /**
14441+ * Visualization for xyzMap.
14442+ * @param [in] xyzMap input point cloud matrix
14443+ * @return a CV_8UC3 representation of the xyzMap
14444+ */
14445+ static cv::Mat visualizeXYZMap(cv::Mat &xyzMap);
14446+
14447+ /**
14448+ * Visualization for hand object.
14449+ * @param [in] xyzMap the base image to draw on
14450+ * @param [in] finger (i,j) coordinates of the finger
14451+ * @param [in] centroid (i,j) coordinates of the centroid
14452+ * @return a CV_8UC3 matrix with the hand points drawn
14453+ */
14454+ static cv::Mat visualizeHand(cv::Mat xyzMap, cv::Point2i finger, cv::Point2i centroid);
14455+
14456+ /**
14457+ * Visualization for PCL point cloud.
14458+ * @param [in] cloud PCL point cloud to be visualized
14459+ */
14460+ static void visualizeCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
14461+
14462+ /**
14463+ * Visualization for polygon mesh.
14464+ * Visualize a PCL point cloud as a polygon mesh
14465+ * @param [in] cloud PCL point cloud to be visualized
14466+ */
14467+ static void visulizePolygonMesh(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
14468+
14469+ /**
14470+ * Visualization for plane regression.
14471+ * @param [in] input_mat the base xyzMap on which to draw the visualization
14472+ * @param [in] equation equation of the plane
14473+ * @param threshold maximum error distance (mm) allowed for points to be considered covered by regression equation
14474+ * @param clicked whether the finger is currently current contacting the regression equation. Default is FALSE
14475+ * @return a CV_8UC3 representation of the matrix with the regression plane drawn
14476+ */
14477+ static cv::Mat visualizePlaneRegression(cv::Mat &input_mat, std::vector<double> &equation, const double threshold, bool clicked = false);
14478+
14479+ /*
14480+ * Visualize points that lie on the plane.
14481+ * @param input_mat the input point cloud
14482+ * @indicies (i,j) coordinates of the points belonging to the plane
14483+ */
14484+ static void visualizePlanePoints(cv::Mat &input_mat, std::vector<cv::Point2i> indicies);
14485+
14486+private:
14487+
14488+ /**
14489+ * Visualization for a generic matrix.
14490+ * @param [in] input matrix to be visualized
14491+ * @return a CV_8UC3 representation of the input matrix
14492+ */
14493+ static cv::Mat visualizeMatrix(cv::Mat &input);
14494+
14495+ /**
14496+ * Visualization for a depth map matrix (i,j,z).
14497+ * @param [in] depthMap matrix to be visualized
14498+ * @return a CV_8UC3 representation of the input matrix
14499+ */
14500+ static cv::Mat visualizeDepthMap(cv::Mat &depthMap);
14501+
14502+ /**
14503+ * PCL point cloud viewer
14504+ */
14505+ static pcl::visualization::PCLVisualizer viewer;
14506 };
14507\ No newline at end of file
14508diff --git a/Webcam.cpp b/Webcam.cpp
14509index eed13c9..734a31d 100644
14510--- a/Webcam.cpp
14511+++ b/Webcam.cpp
14512@@ -1,22 +1,22 @@
14513-#include "Webcam.h"
14514-
14515-/***
14516-Opens a webcam and returns the handle
14517-***/
14518-Webcam::Webcam(int code) {
14519- cap.release();
14520- cap.open(code);
14521-}
14522-
14523-void Webcam::update()
14524-{
14525- cap.read(frame);
14526-}
14527-
14528-/***
14529-Closes the webcam
14530-***/
14531-Webcam::~Webcam()
14532-{
14533- cap.release();
14534+#include "Webcam.h"
14535+
14536+/***
14537+Opens a webcam and returns the handle
14538+***/
14539+Webcam::Webcam(int code) {
14540+ cap.release();
14541+ cap.open(code);
14542+}
14543+
14544+void Webcam::update()
14545+{
14546+ cap.read(frame);
14547+}
14548+
14549+/***
14550+Closes the webcam
14551+***/
14552+Webcam::~Webcam()
14553+{
14554+ cap.release();
14555 }
14556\ No newline at end of file
14557diff --git a/Webcam.h b/Webcam.h
14558index 73d4d84..2d83852 100644
14559--- a/Webcam.h
14560+++ b/Webcam.h
14561@@ -1,30 +1,30 @@
14562-#pragma once
14563-// OpenCV Libaries
14564-
14565-// OpenARK Libraries
14566-#include "RGBCamera.h"
14567-
14568-/**
14569-* Class defining the behavior of a standard webcam.
14570-*/
14571-class Webcam : public RGBCamera
14572-{
14573-public:
14574- /**
14575- * Constructs a new webcam instance.
14576- * @param code the code for the webcam. Default is 0 if there is only one webcam connected
14577- */
14578- Webcam(int code = 0);
14579-
14580- /**
14581- * Deconstructs a webcam instance.
14582- */
14583- ~Webcam();
14584-
14585- /**
14586- * Updates the webcam infomration with the current frame.
14587- */
14588- void update();
14589-
14590-private:
14591+#pragma once
14592+// OpenCV Libaries
14593+
14594+// OpenARK Libraries
14595+#include "RGBCamera.h"
14596+
14597+/**
14598+* Class defining the behavior of a standard webcam.
14599+*/
14600+class Webcam : public RGBCamera
14601+{
14602+public:
14603+ /**
14604+ * Constructs a new webcam instance.
14605+ * @param code the code for the webcam. Default is 0 if there is only one webcam connected
14606+ */
14607+ Webcam(int code = 0);
14608+
14609+ /**
14610+ * Deconstructs a webcam instance.
14611+ */
14612+ ~Webcam();
14613+
14614+ /**
14615+ * Updates the webcam infomration with the current frame.
14616+ */
14617+ void update();
14618+
14619+private:
14620 };
14621\ No newline at end of file
14622diff --git a/global.cpp b/global.cpp
14623deleted file mode 100644
14624index 908fbc6..0000000
14625--- a/global.cpp
14626+++ /dev/null
14627@@ -1,3 +0,0 @@
14628-#include "global.h"
14629-
14630-char * camera_name = "sr300";
14631\ No newline at end of file
14632diff --git a/global.h b/global.h
14633deleted file mode 100644
14634index 21401b8..0000000
14635--- a/global.h
14636+++ /dev/null
14637@@ -1,2 +0,0 @@
14638-#pragma once
14639-extern char * camera_name;
14640\ No newline at end of file
14641diff --git a/samplecode/ARTiltBrushDemo.cpp b/samplecode/ARTiltBrushDemo.cpp
14642index 7cd97c6..a3afe71 100644
14643--- a/samplecode/ARTiltBrushDemo.cpp
14644+++ b/samplecode/ARTiltBrushDemo.cpp
14645@@ -1,179 +1,179 @@
14646-// C++ Libraries
14647-#include <stdio.h>
14648-#include <iostream>
14649-#include <string>
14650-#include <time.h>
14651-
14652-// OpenCV Libraries
14653-#include <opencv/cxcore.h>
14654-#include "opencv2/highgui/highgui.hpp"
14655-
14656-// OpenARK Libraries
14657-#include "PMDCamera.h"
14658-#include "Webcam.h"
14659-#include "Visualizer.h"
14660-#include "Hand.h"
14661-#include "Plane.h"
14662-#include "Calibration.h"
14663-#include "Util.h"
14664-#include "UDPSender.h"
14665-#include "Object3D.h"
14666-#include "StreamingAverager.h"
14667-
14668-int main() {
14669- clock_t starttime = clock();
14670- DepthCamera* pmd = new PMDCamera();
14671- //RGBCamera *cam = new Webcam(1);
14672- int frame = 0;
14673- //Calibration::XYZToUnity(*pmd, 4, 4, 3);
14674- cv::FileStorage fs;
14675- fs.open("RT_Transform.txt", cv::FileStorage::READ);
14676-
14677- cv::Mat r, t;
14678- fs["R"] >> r;
14679- fs["T"] >> t;
14680-
14681- fs.release();
14682-
14683- UDPSender u = UDPSender();
14684- cv::namedWindow("Results", CV_WINDOW_NORMAL);
14685-
14686- StreamingAverager handAverager = StreamingAverager(4, 0.1);
14687- StreamingAverager paleeteAverager = StreamingAverager(6, 0.05);
14688-
14689- while (true)
14690- {
14691- pmd->update();
14692-
14693- /**
14694- std::string filename = "..//OpenARK_Datasets//TwoHandDataSet1//img" + std::to_string(frame) + ".yml";
14695- if (!pmd->readImage(filename))
14696- break;
14697- **/
14698-
14699- // Loading image from sensor
14700-
14701- pmd->removeNoise();
14702- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
14703- if (pmd->badInput) {
14704- continue;
14705- }
14706-
14707- // Classifying objects in the scene
14708-
14709- pmd->computeClusters(0.02, 500);
14710- std::vector<cv::Mat> clusters = pmd->getClusters();
14711- std::vector<Object3D> objects;
14712-
14713- int handObjectIndex = -1, planeObjectIndex = -1;
14714- for (int i = 0; i < clusters.size(); i++) {
14715- Object3D obj = Object3D(clusters[i].clone());
14716- if (obj.hasHand) {
14717- handObjectIndex = i;
14718- }
14719-
14720- if (obj.hasPlane) {
14721- planeObjectIndex = i;
14722- }
14723- objects.push_back(obj);
14724-
14725- }
14726-
14727- // Interprate the relationship between the objects
14728-
14729- bool clicked = false, paletteFound = false;
14730- Object3D handObject, planeObject;
14731- cv::Point paletteCenter(-1. -1);
14732- cv::Mat mask = cv::Mat::zeros(pmd->getXYZMap().rows, pmd->getXYZMap().cols, CV_8UC1);
14733- if (planeObjectIndex != -1 && handObjectIndex != -1) {
14734- planeObject = objects[planeObjectIndex];
14735- handObject = objects[handObjectIndex];
14736-
14737- clicked = handObject.getHand().touchObject(planeObject.getPlane().getPlaneEquation(), planeObject.getPlane().R_SQUARED_DISTANCE_THRESHOLD * 5);
14738- cv::Mat scene = Visualizer::visualizePlaneRegression(pmd->getXYZMap(), planeObject.getPlane().getPlaneEquation(), planeObject.getPlane().R_SQUARED_DISTANCE_THRESHOLD, clicked);
14739- //scene = Visualizer::visualizeHand(scene, handObject.getHand().pointer_finger_ij, handObject.getHand().shape_centroid_ij);
14740- if (planeObject.leftEdgeConnected) {
14741- Visualizer::visualizePlanePoints(mask, planeObject.getPlane().getPlaneIndicies());
14742- cv::Moments m = cv::moments(mask, false);
14743- paletteCenter = cv::Point (m.m10 / m.m00, m.m01 / m.m00);
14744- cv::circle(scene, paletteCenter, 2, cv::Scalar(0, 0, 255), 2);
14745- paletteFound = true;
14746- }
14747- cv::imshow("Results", scene);
14748- } else if (handObjectIndex != -1) {
14749- handObject = objects[handObjectIndex];
14750- //cv::imshow("Results", Visualizer::visualizeHand(pmd->getXYZMap(), handObject.getHand().pointer_finger_ij, handObject.getHand().shape_centroid_ij));
14751- } else if (planeObjectIndex != -1) {
14752- planeObject = objects[planeObjectIndex];
14753- cv::Mat scene = Visualizer::visualizePlaneRegression(pmd->getXYZMap(), planeObject.getPlane().getPlaneEquation(), planeObject.getPlane().R_SQUARED_DISTANCE_THRESHOLD, clicked);
14754- if (planeObject.leftEdgeConnected) {
14755- Visualizer::visualizePlanePoints(mask, planeObject.getPlane().getPlaneIndicies());
14756- cv::Moments m = cv::moments(mask, false);
14757- paletteCenter = cv::Point (m.m10 / m.m00, m.m01 / m.m00);
14758- cv::circle(scene, paletteCenter, 2, cv::Scalar(0, 0, 255), 2);
14759- paletteFound = true;
14760- }
14761- cv::imshow("Results", scene);
14762- }
14763-
14764- // Organize the data and send to game engine
14765-
14766- std::string handX = "-", handY = "-", handZ = "-";
14767- std::string paletteX = "-", paletteY = "-", paletteZ = "-";
14768- std::string clickStatus = "2";
14769- std::string num_fingers = "0";
14770- if (handObjectIndex != -1) {
14771- cv::Vec3f handPos = handAverager.addDataPoint(objects[handObjectIndex].getHand().fingers_xyz[0]);
14772- //float hand_pt[3] = { objects[handObjectIndex].getHand().pointer_finger_xyz[0], objects[handObjectIndex].getHand().pointer_finger_xyz[1], objects[handObjectIndex].getHand().pointer_finger_xyz[2]};
14773- float hand_pt[3] = { handPos[0], handPos[1], handPos[2] };
14774- cv::Mat hand_mat = cv::Mat(3, 1, CV_32FC1, &hand_pt);
14775- hand_mat = r*hand_mat + t;
14776- handX = std::to_string(hand_mat.at<float>(0, 0));
14777- handY = std::to_string(hand_mat.at<float>(1, 0));
14778- handZ = std::to_string(hand_mat.at<float>(2, 0));
14779- num_fingers = std::to_string(objects[handObjectIndex].getHand().fingers_xyz.size());
14780- }
14781- else {
14782- handAverager.addEmptyPoint();
14783- }
14784- if (paletteFound) {
14785- cv::Vec3f pt = paleeteAverager.addDataPoint(pmd->getXYZMap().at<cv::Vec3f>(paletteCenter.y, paletteCenter.x));
14786- float palette_pt[3] = { pt[0], pt[1], pt[2] };
14787- cv::Mat palette_mat = cv::Mat(3, 1, CV_32FC1, &palette_pt);
14788- palette_mat = r*palette_mat + t;
14789- paletteX = std::to_string(palette_mat.at<float>(0, 0));
14790- paletteY = std::to_string(palette_mat.at<float>(1, 0));
14791- paletteZ = std::to_string(palette_mat.at<float>(2, 0));
14792- } else {
14793- paleeteAverager.addEmptyPoint();
14794- }
14795- if (clicked) {
14796- clickStatus = "1";
14797- }
14798-
14799- std::string tempS = "";
14800- tempS = handX + "%" + handY + "%" + handZ + "%" + paletteX + "%" + paletteY + "%" + paletteZ + "%" + clickStatus + "%" + num_fingers;
14801- u.send(tempS);
14802-
14803-
14804-
14805- /**** Start: Write Frames to File ****/
14806- //std::string filename = "img" + std::to_string(frame) + ".yml";
14807- //pmd->writeImage(filename);
14808- //std::cout << filename << std::endl;
14809- /**** End: Write Frames to File ****/
14810-
14811-
14812-
14813- /**** Start: Loop Break Condition ****/
14814- int c = cvWaitKey(1);
14815- if (c == 'q' || c == 'Q' || c == 27) {
14816- break;
14817- }
14818- /**** End: Loop Break Condition ****/
14819- frame++;
14820- }
14821-
14822- pmd->destroyInstance();
14823- return 0;
14824+// C++ Libraries
14825+#include <stdio.h>
14826+#include <iostream>
14827+#include <string>
14828+#include <time.h>
14829+
14830+// OpenCV Libraries
14831+#include <opencv/cxcore.h>
14832+#include "opencv2/highgui/highgui.hpp"
14833+
14834+// OpenARK Libraries
14835+#include "PMDCamera.h"
14836+#include "Webcam.h"
14837+#include "Visualizer.h"
14838+#include "Hand.h"
14839+#include "Plane.h"
14840+#include "Calibration.h"
14841+#include "Util.h"
14842+#include "UDPSender.h"
14843+#include "Object3D.h"
14844+#include "StreamingAverager.h"
14845+
14846+int main() {
14847+ clock_t starttime = clock();
14848+ DepthCamera* pmd = new PMDCamera();
14849+ //RGBCamera *cam = new Webcam(1);
14850+ int frame = 0;
14851+ //Calibration::XYZToUnity(*pmd, 4, 4, 3);
14852+ cv::FileStorage fs;
14853+ fs.open("RT_Transform.txt", cv::FileStorage::READ);
14854+
14855+ cv::Mat r, t;
14856+ fs["R"] >> r;
14857+ fs["T"] >> t;
14858+
14859+ fs.release();
14860+
14861+ UDPSender u = UDPSender();
14862+ cv::namedWindow("Results", CV_WINDOW_NORMAL);
14863+
14864+ StreamingAverager handAverager = StreamingAverager(4, 0.1);
14865+ StreamingAverager paleeteAverager = StreamingAverager(6, 0.05);
14866+
14867+ while (true)
14868+ {
14869+ pmd->update();
14870+
14871+ /**
14872+ std::string filename = "..//OpenARK_Datasets//TwoHandDataSet1//img" + std::to_string(frame) + ".yml";
14873+ if (!pmd->readImage(filename))
14874+ break;
14875+ **/
14876+
14877+ // Loading image from sensor
14878+
14879+ pmd->removeNoise();
14880+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
14881+ if (pmd->badInput) {
14882+ continue;
14883+ }
14884+
14885+ // Classifying objects in the scene
14886+
14887+ pmd->computeClusters(0.02, 500);
14888+ std::vector<cv::Mat> clusters = pmd->getClusters();
14889+ std::vector<Object3D> objects;
14890+
14891+ int handObjectIndex = -1, planeObjectIndex = -1;
14892+ for (int i = 0; i < clusters.size(); i++) {
14893+ Object3D obj = Object3D(clusters[i].clone());
14894+ if (obj.hasHand) {
14895+ handObjectIndex = i;
14896+ }
14897+
14898+ if (obj.hasPlane) {
14899+ planeObjectIndex = i;
14900+ }
14901+ objects.push_back(obj);
14902+
14903+ }
14904+
14905+ // Interprate the relationship between the objects
14906+
14907+ bool clicked = false, paletteFound = false;
14908+ Object3D handObject, planeObject;
14909+ cv::Point paletteCenter(-1. -1);
14910+ cv::Mat mask = cv::Mat::zeros(pmd->getXYZMap().rows, pmd->getXYZMap().cols, CV_8UC1);
14911+ if (planeObjectIndex != -1 && handObjectIndex != -1) {
14912+ planeObject = objects[planeObjectIndex];
14913+ handObject = objects[handObjectIndex];
14914+
14915+ clicked = handObject.getHand().touchObject(planeObject.getPlane().getPlaneEquation(), planeObject.getPlane().R_SQUARED_DISTANCE_THRESHOLD * 5);
14916+ cv::Mat scene = Visualizer::visualizePlaneRegression(pmd->getXYZMap(), planeObject.getPlane().getPlaneEquation(), planeObject.getPlane().R_SQUARED_DISTANCE_THRESHOLD, clicked);
14917+ //scene = Visualizer::visualizeHand(scene, handObject.getHand().pointer_finger_ij, handObject.getHand().shape_centroid_ij);
14918+ if (planeObject.leftEdgeConnected) {
14919+ Visualizer::visualizePlanePoints(mask, planeObject.getPlane().getPlaneIndicies());
14920+ cv::Moments m = cv::moments(mask, false);
14921+ paletteCenter = cv::Point (m.m10 / m.m00, m.m01 / m.m00);
14922+ cv::circle(scene, paletteCenter, 2, cv::Scalar(0, 0, 255), 2);
14923+ paletteFound = true;
14924+ }
14925+ cv::imshow("Results", scene);
14926+ } else if (handObjectIndex != -1) {
14927+ handObject = objects[handObjectIndex];
14928+ //cv::imshow("Results", Visualizer::visualizeHand(pmd->getXYZMap(), handObject.getHand().pointer_finger_ij, handObject.getHand().shape_centroid_ij));
14929+ } else if (planeObjectIndex != -1) {
14930+ planeObject = objects[planeObjectIndex];
14931+ cv::Mat scene = Visualizer::visualizePlaneRegression(pmd->getXYZMap(), planeObject.getPlane().getPlaneEquation(), planeObject.getPlane().R_SQUARED_DISTANCE_THRESHOLD, clicked);
14932+ if (planeObject.leftEdgeConnected) {
14933+ Visualizer::visualizePlanePoints(mask, planeObject.getPlane().getPlaneIndicies());
14934+ cv::Moments m = cv::moments(mask, false);
14935+ paletteCenter = cv::Point (m.m10 / m.m00, m.m01 / m.m00);
14936+ cv::circle(scene, paletteCenter, 2, cv::Scalar(0, 0, 255), 2);
14937+ paletteFound = true;
14938+ }
14939+ cv::imshow("Results", scene);
14940+ }
14941+
14942+ // Organize the data and send to game engine
14943+
14944+ std::string handX = "-", handY = "-", handZ = "-";
14945+ std::string paletteX = "-", paletteY = "-", paletteZ = "-";
14946+ std::string clickStatus = "2";
14947+ std::string num_fingers = "0";
14948+ if (handObjectIndex != -1) {
14949+ cv::Vec3f handPos = handAverager.addDataPoint(objects[handObjectIndex].getHand().fingers_xyz[0]);
14950+ //float hand_pt[3] = { objects[handObjectIndex].getHand().pointer_finger_xyz[0], objects[handObjectIndex].getHand().pointer_finger_xyz[1], objects[handObjectIndex].getHand().pointer_finger_xyz[2]};
14951+ float hand_pt[3] = { handPos[0], handPos[1], handPos[2] };
14952+ cv::Mat hand_mat = cv::Mat(3, 1, CV_32FC1, &hand_pt);
14953+ hand_mat = r*hand_mat + t;
14954+ handX = std::to_string(hand_mat.at<float>(0, 0));
14955+ handY = std::to_string(hand_mat.at<float>(1, 0));
14956+ handZ = std::to_string(hand_mat.at<float>(2, 0));
14957+ num_fingers = std::to_string(objects[handObjectIndex].getHand().fingers_xyz.size());
14958+ }
14959+ else {
14960+ handAverager.addEmptyPoint();
14961+ }
14962+ if (paletteFound) {
14963+ cv::Vec3f pt = paleeteAverager.addDataPoint(pmd->getXYZMap().at<cv::Vec3f>(paletteCenter.y, paletteCenter.x));
14964+ float palette_pt[3] = { pt[0], pt[1], pt[2] };
14965+ cv::Mat palette_mat = cv::Mat(3, 1, CV_32FC1, &palette_pt);
14966+ palette_mat = r*palette_mat + t;
14967+ paletteX = std::to_string(palette_mat.at<float>(0, 0));
14968+ paletteY = std::to_string(palette_mat.at<float>(1, 0));
14969+ paletteZ = std::to_string(palette_mat.at<float>(2, 0));
14970+ } else {
14971+ paleeteAverager.addEmptyPoint();
14972+ }
14973+ if (clicked) {
14974+ clickStatus = "1";
14975+ }
14976+
14977+ std::string tempS = "";
14978+ tempS = handX + "%" + handY + "%" + handZ + "%" + paletteX + "%" + paletteY + "%" + paletteZ + "%" + clickStatus + "%" + num_fingers;
14979+ u.send(tempS);
14980+
14981+
14982+
14983+ /**** Start: Write Frames to File ****/
14984+ //std::string filename = "img" + std::to_string(frame) + ".yml";
14985+ //pmd->writeImage(filename);
14986+ //std::cout << filename << std::endl;
14987+ /**** End: Write Frames to File ****/
14988+
14989+
14990+
14991+ /**** Start: Loop Break Condition ****/
14992+ int c = cvWaitKey(1);
14993+ if (c == 'q' || c == 'Q' || c == 27) {
14994+ break;
14995+ }
14996+ /**** End: Loop Break Condition ****/
14997+ frame++;
14998+ }
14999+
15000+ pmd->destroyInstance();
15001+ return 0;
15002 }
15003\ No newline at end of file
15004diff --git a/samplecode/CreatingDebugData.cpp b/samplecode/CreatingDebugData.cpp
15005index 9f66c0b..8ff63ed 100644
15006--- a/samplecode/CreatingDebugData.cpp
15007+++ b/samplecode/CreatingDebugData.cpp
15008@@ -1,45 +1,45 @@
15009-// C++ Libraries
15010-#include <stdio.h>
15011-#include <iostream>
15012-#include <string>
15013-
15014-// OpenCV Libraries
15015-#include <opencv/cxcore.h>
15016-#include "opencv2/highgui/highgui.hpp"
15017-
15018-// OpenARK Libraries
15019-#include "PMDCamera.h"
15020-#include "Visualizer.h"
15021-#include "Util.h"
15022-
15023-int main() {
15024- clock_t starttime = clock();
15025- DepthCamera* pmd = new PMDCamera();
15026- int frame = 0;
15027-
15028- while (true)
15029- {
15030- pmd->update();
15031-
15032- /**** Start: Write Frames to File ****/
15033- std::string filename = "img" + std::to_string(frame) + ".yml";
15034- pmd->writeImage(filename);
15035- std::cout << filename << std::endl;
15036- /**** End: Write Frames to File ****/
15037-
15038- pmd->removeNoise();
15039- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15040-
15041- /**** Start: Loop Break Condition ****/
15042- int c = cvWaitKey(1);
15043- if (c == 'q' || c == 'Q' || c == 27) {
15044- break;
15045- }
15046- /**** End: Loop Break Condition ****/
15047- frame++;
15048-
15049- }
15050-
15051- pmd->destroyInstance();
15052- return 0;
15053+// C++ Libraries
15054+#include <stdio.h>
15055+#include <iostream>
15056+#include <string>
15057+
15058+// OpenCV Libraries
15059+#include <opencv/cxcore.h>
15060+#include "opencv2/highgui/highgui.hpp"
15061+
15062+// OpenARK Libraries
15063+#include "PMDCamera.h"
15064+#include "Visualizer.h"
15065+#include "Util.h"
15066+
15067+int main() {
15068+ clock_t starttime = clock();
15069+ DepthCamera* pmd = new PMDCamera();
15070+ int frame = 0;
15071+
15072+ while (true)
15073+ {
15074+ pmd->update();
15075+
15076+ /**** Start: Write Frames to File ****/
15077+ std::string filename = "img" + std::to_string(frame) + ".yml";
15078+ pmd->writeImage(filename);
15079+ std::cout << filename << std::endl;
15080+ /**** End: Write Frames to File ****/
15081+
15082+ pmd->removeNoise();
15083+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15084+
15085+ /**** Start: Loop Break Condition ****/
15086+ int c = cvWaitKey(1);
15087+ if (c == 'q' || c == 'Q' || c == 27) {
15088+ break;
15089+ }
15090+ /**** End: Loop Break Condition ****/
15091+ frame++;
15092+
15093+ }
15094+
15095+ pmd->destroyInstance();
15096+ return 0;
15097 }
15098\ No newline at end of file
15099diff --git a/samplecode/HandTracking.cpp b/samplecode/HandTracking.cpp
15100index 7e0a203..e6e03c4 100644
15101--- a/samplecode/HandTracking.cpp
15102+++ b/samplecode/HandTracking.cpp
15103@@ -1,51 +1,51 @@
15104-// C++ Libraries
15105-#include <stdio.h>
15106-#include <iostream>
15107-#include <string>
15108-
15109-// OpenCV Libraries
15110-#include <opencv/cxcore.h>
15111-#include "opencv2/highgui/highgui.hpp"
15112-
15113-// OpenARK Libraries
15114-#include "PMDCamera.h"
15115-#include "Visualizer.h"
15116-#include "Hand.h"
15117-#include "Plane.h"
15118-#include "Util.h"
15119-
15120-int main() {
15121- DepthCamera* pmd = new PMDCamera(false);
15122- int frame = 0;
15123-
15124- while (true)
15125- {
15126- // Load in the debug data
15127- std::string filename = "..//OpenARK_Datasets//HandDataSet1//img" + std::to_string(frame) + ".yml";
15128- if (!pmd->readImage(filename))
15129- break;
15130-
15131- // Remove noise on the frame
15132- pmd->removeNoise();
15133- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15134-
15135- // Find the right hand
15136- Hand right_hand = Hand(pmd->getClusters());
15137-
15138- // Show the hand
15139- cv::imshow("Hand", Visualizer::visualizeHand(pmd->getXYZMap(), right_hand.pointer_finger_ij, right_hand.shape_centroid_ij));
15140-
15141-
15142- /**** Start: Loop Break Condition ****/
15143- int c = cvWaitKey(1);
15144- if (c == 'q' || c == 'Q' || c == 27) {
15145- break;
15146- }
15147- /**** End: Loop Break Condition ****/
15148-
15149- frame++;
15150- }
15151-
15152- pmd->destroyInstance();
15153- return 0;
15154+// C++ Libraries
15155+#include <stdio.h>
15156+#include <iostream>
15157+#include <string>
15158+
15159+// OpenCV Libraries
15160+#include <opencv/cxcore.h>
15161+#include "opencv2/highgui/highgui.hpp"
15162+
15163+// OpenARK Libraries
15164+#include "PMDCamera.h"
15165+#include "Visualizer.h"
15166+#include "Hand.h"
15167+#include "Plane.h"
15168+#include "Util.h"
15169+
15170+int main() {
15171+ DepthCamera* pmd = new PMDCamera(false);
15172+ int frame = 0;
15173+
15174+ while (true)
15175+ {
15176+ // Load in the debug data
15177+ std::string filename = "..//OpenARK_Datasets//HandDataSet1//img" + std::to_string(frame) + ".yml";
15178+ if (!pmd->readImage(filename))
15179+ break;
15180+
15181+ // Remove noise on the frame
15182+ pmd->removeNoise();
15183+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15184+
15185+ // Find the right hand
15186+ Hand right_hand = Hand(pmd->getClusters());
15187+
15188+ // Show the hand
15189+ cv::imshow("Hand", Visualizer::visualizeHand(pmd->getXYZMap(), right_hand.pointer_finger_ij, right_hand.shape_centroid_ij));
15190+
15191+
15192+ /**** Start: Loop Break Condition ****/
15193+ int c = cvWaitKey(1);
15194+ if (c == 'q' || c == 'Q' || c == 27) {
15195+ break;
15196+ }
15197+ /**** End: Loop Break Condition ****/
15198+
15199+ frame++;
15200+ }
15201+
15202+ pmd->destroyInstance();
15203+ return 0;
15204 }
15205\ No newline at end of file
15206diff --git a/samplecode/HandandPlane.cpp b/samplecode/HandandPlane.cpp
15207index 6efd71b..33bdd11 100644
15208--- a/samplecode/HandandPlane.cpp
15209+++ b/samplecode/HandandPlane.cpp
15210@@ -1,65 +1,65 @@
15211-// C++ Libraries
15212-#include <stdio.h>
15213-#include <iostream>
15214-#include <string>
15215-
15216-// OpenCV Libraries
15217-#include <opencv/cxcore.h>
15218-#include "opencv2/highgui/highgui.hpp"
15219-
15220-// OpenARK Libraries
15221-#include "PMDCamera.h"
15222-#include "Visualizer.h"
15223-#include "Hand.h"
15224-#include "Plane.h"
15225-#include "Util.h"
15226-
15227-int main() {
15228- DepthCamera* pmd = new PMDCamera(false);
15229- int frame = 0;
15230-
15231- while (true)
15232- {
15233- // Load in the debug data
15234- std::string filename = "..//OpenARK_Datasets//ClusterDataSet1//img" + std::to_string(frame) + ".yml";
15235- if (!pmd->readImage(filename))
15236- break;
15237-
15238- // Remove noise on the frame
15239- pmd->removeNoise();
15240- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15241-
15242- // Find the plane
15243- Plane plane = Plane::Plane(pmd->getXYZMap());
15244- Visualizer::visualizeCloud(plane.getDownCloud());
15245- cv::imshow("Plane Regression", Visualizer::visualizePlaneRegression(pmd->getXYZMap(), plane.getPlaneEquation(), plane.R_SQUARED_DISTANCE_THRESHOLD));
15246-
15247- // Remove the plane
15248- pmd->removePoints(plane.getPlaneIndicies());
15249- cv::imshow("Hand Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15250- pmd->computeClusters(0.02, 500);
15251-
15252- // Find the right hand
15253- Hand right_hand = Hand(pmd->getClusters());
15254-
15255- // Show the hand
15256- cv::imshow("Hand", Visualizer::visualizeHand(pmd->getXYZMap(), right_hand.pointer_finger_ij, right_hand.shape_centroid_ij));
15257- if (right_hand.touchObject(plane.getPlaneEquation(), plane.R_SQUARED_DISTANCE_THRESHOLD * 3) == true)
15258- {
15259- printf("Touched Plane\n");
15260- }
15261-
15262-
15263- /**** Start: Loop Break Condition ****/
15264- int c = cvWaitKey(1);
15265- if (c == 'q' || c == 'Q' || c == 27) {
15266- break;
15267- }
15268- /**** End: Loop Break Condition ****/
15269-
15270- frame++;
15271- }
15272-
15273- pmd->destroyInstance();
15274- return 0;
15275+// C++ Libraries
15276+#include <stdio.h>
15277+#include <iostream>
15278+#include <string>
15279+
15280+// OpenCV Libraries
15281+#include <opencv/cxcore.h>
15282+#include "opencv2/highgui/highgui.hpp"
15283+
15284+// OpenARK Libraries
15285+#include "PMDCamera.h"
15286+#include "Visualizer.h"
15287+#include "Hand.h"
15288+#include "Plane.h"
15289+#include "Util.h"
15290+
15291+int main() {
15292+ DepthCamera* pmd = new PMDCamera(false);
15293+ int frame = 0;
15294+
15295+ while (true)
15296+ {
15297+ // Load in the debug data
15298+ std::string filename = "..//OpenARK_Datasets//ClusterDataSet1//img" + std::to_string(frame) + ".yml";
15299+ if (!pmd->readImage(filename))
15300+ break;
15301+
15302+ // Remove noise on the frame
15303+ pmd->removeNoise();
15304+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15305+
15306+ // Find the plane
15307+ Plane plane = Plane::Plane(pmd->getXYZMap());
15308+ Visualizer::visualizeCloud(plane.getDownCloud());
15309+ cv::imshow("Plane Regression", Visualizer::visualizePlaneRegression(pmd->getXYZMap(), plane.getPlaneEquation(), plane.R_SQUARED_DISTANCE_THRESHOLD));
15310+
15311+ // Remove the plane
15312+ pmd->removePoints(plane.getPlaneIndicies());
15313+ cv::imshow("Hand Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15314+ pmd->computeClusters(0.02, 500);
15315+
15316+ // Find the right hand
15317+ Hand right_hand = Hand(pmd->getClusters());
15318+
15319+ // Show the hand
15320+ cv::imshow("Hand", Visualizer::visualizeHand(pmd->getXYZMap(), right_hand.pointer_finger_ij, right_hand.shape_centroid_ij));
15321+ if (right_hand.touchObject(plane.getPlaneEquation(), plane.R_SQUARED_DISTANCE_THRESHOLD * 3) == true)
15322+ {
15323+ printf("Touched Plane\n");
15324+ }
15325+
15326+
15327+ /**** Start: Loop Break Condition ****/
15328+ int c = cvWaitKey(1);
15329+ if (c == 'q' || c == 'Q' || c == 27) {
15330+ break;
15331+ }
15332+ /**** End: Loop Break Condition ****/
15333+
15334+ frame++;
15335+ }
15336+
15337+ pmd->destroyInstance();
15338+ return 0;
15339 }
15340\ No newline at end of file
15341diff --git a/samplecode/LoadingDebugData.cpp b/samplecode/LoadingDebugData.cpp
15342index 51e1e93..d0a382b 100644
15343--- a/samplecode/LoadingDebugData.cpp
15344+++ b/samplecode/LoadingDebugData.cpp
15345@@ -1,44 +1,44 @@
15346-// C++ Libraries
15347-#include <stdio.h>
15348-#include <iostream>
15349-#include <string>
15350-
15351-// OpenCV Libraries
15352-#include <opencv/cxcore.h>
15353-#include "opencv2/highgui/highgui.hpp"
15354-
15355-// OpenARK Libraries
15356-#include "PMDCamera.h"
15357-#include "Visualizer.h"
15358-#include "Util.h"
15359-
15360-int main() {
15361- DepthCamera* pmd = new PMDCamera(false); // Initiatize with use_live_sensor = false
15362- int frame = 0;
15363-
15364- while (true)
15365- {
15366- // Read in each individual frame from file
15367- std::string filename = "..//OpenARK_Datasets//HandDataSet2//img" + std::to_string(frame) + ".yml";
15368- if (!pmd->readImage(filename))
15369- break;
15370-
15371- // Remove nosie from the frame
15372- pmd->removeNoise();
15373-
15374- // Display the resultant image
15375- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15376-
15377- /**** Start: Loop Break Condition ****/
15378- int c = cvWaitKey(1);
15379- if (c == 'q' || c == 'Q' || c == 27) {
15380- break;
15381- }
15382- /**** End: Loop Break Condition ****/
15383-
15384- frame++;
15385- }
15386-
15387- pmd->destroyInstance();
15388- return 0;
15389+// C++ Libraries
15390+#include <stdio.h>
15391+#include <iostream>
15392+#include <string>
15393+
15394+// OpenCV Libraries
15395+#include <opencv/cxcore.h>
15396+#include "opencv2/highgui/highgui.hpp"
15397+
15398+// OpenARK Libraries
15399+#include "PMDCamera.h"
15400+#include "Visualizer.h"
15401+#include "Util.h"
15402+
15403+int main() {
15404+ DepthCamera* pmd = new PMDCamera(false); // Initiatize with use_live_sensor = false
15405+ int frame = 0;
15406+
15407+ while (true)
15408+ {
15409+ // Read in each individual frame from file
15410+ std::string filename = "..//OpenARK_Datasets//HandDataSet2//img" + std::to_string(frame) + ".yml";
15411+ if (!pmd->readImage(filename))
15412+ break;
15413+
15414+ // Remove nosie from the frame
15415+ pmd->removeNoise();
15416+
15417+ // Display the resultant image
15418+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15419+
15420+ /**** Start: Loop Break Condition ****/
15421+ int c = cvWaitKey(1);
15422+ if (c == 'q' || c == 'Q' || c == 27) {
15423+ break;
15424+ }
15425+ /**** End: Loop Break Condition ****/
15426+
15427+ frame++;
15428+ }
15429+
15430+ pmd->destroyInstance();
15431+ return 0;
15432 }
15433\ No newline at end of file
15434diff --git a/samplecode/SensorIO.cpp b/samplecode/SensorIO.cpp
15435index 6abf574..d569ff8 100644
15436--- a/samplecode/SensorIO.cpp
15437+++ b/samplecode/SensorIO.cpp
15438@@ -1,41 +1,41 @@
15439-// C++ Libraries
15440-#include <stdio.h>
15441-#include <iostream>
15442-#include <string>
15443-
15444-// OpenCV Libraries
15445-#include <opencv/cxcore.h>
15446-#include "opencv2/highgui/highgui.hpp"
15447-
15448-// OpenARK Libraries
15449-#include "PMDCamera.h"
15450-#include "Visualizer.h"
15451-#include "Util.h"
15452-
15453-int main() {
15454- DepthCamera* pmd = new PMDCamera();
15455- int frame = 0;
15456-
15457- while (true)
15458- {
15459- // Update the current frame
15460- pmd->update();
15461-
15462- // REmove the current frame
15463- pmd->removeNoise();
15464-
15465- // Visualize the XYZ Map
15466- cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15467-
15468- /**** Start: Loop Break Condition ****/
15469- int c = cvWaitKey(1);
15470- if (c == 'q' || c == 'Q' || c == 27) {
15471- break;
15472- }
15473- /**** End: Loop Break Condition ****/
15474- frame++;
15475- }
15476-
15477- pmd->destroyInstance();
15478- return 0;
15479+// C++ Libraries
15480+#include <stdio.h>
15481+#include <iostream>
15482+#include <string>
15483+
15484+// OpenCV Libraries
15485+#include <opencv/cxcore.h>
15486+#include "opencv2/highgui/highgui.hpp"
15487+
15488+// OpenARK Libraries
15489+#include "PMDCamera.h"
15490+#include "Visualizer.h"
15491+#include "Util.h"
15492+
15493+int main() {
15494+ DepthCamera* pmd = new PMDCamera();
15495+ int frame = 0;
15496+
15497+ while (true)
15498+ {
15499+ // Update the current frame
15500+ pmd->update();
15501+
15502+ // REmove the current frame
15503+ pmd->removeNoise();
15504+
15505+ // Visualize the XYZ Map
15506+ cv::imshow("XYZ Map", Visualizer::visualizeXYZMap(pmd->getXYZMap()));
15507+
15508+ /**** Start: Loop Break Condition ****/
15509+ int c = cvWaitKey(1);
15510+ if (c == 'q' || c == 'Q' || c == 27) {
15511+ break;
15512+ }
15513+ /**** End: Loop Break Condition ****/
15514+ frame++;
15515+ }
15516+
15517+ pmd->destroyInstance();
15518+ return 0;
15519 }
15520\ No newline at end of file