Commit 627eed8df6c5094b4678fc129722edd37c0999b5
1 parent
18fad6bc
added a GUI for displaying networks
Showing
3 changed files
with
387 additions
and
28 deletions
Show diff stats
CMakeLists.txt
... | ... | @@ -21,6 +21,10 @@ endif(NOT STIM_INCLUDE_DIRS) |
21 | 21 | #find BOOST |
22 | 22 | find_package(Boost REQUIRED) |
23 | 23 | |
24 | +#find the GLUT library for visualization | |
25 | +find_package(OpenGL REQUIRED) | |
26 | +find_package(GLUT REQUIRED) | |
27 | + | |
24 | 28 | #find the pthreads package |
25 | 29 | find_package(Threads) |
26 | 30 | |
... | ... | @@ -37,8 +41,10 @@ if ( MSVC ) |
37 | 41 | endif ( MSVC ) |
38 | 42 | |
39 | 43 | include_directories( |
44 | + ${OpenGL_INCLUDE_DIRS} | |
45 | + ${GLUT_INCLUDE_DIR} | |
40 | 46 | ${STIM_INCLUDE_DIRS} |
41 | - ${ANN_INCLUDE_DIR} | |
47 | + ${ANN_INCLUDE_DIR} | |
42 | 48 | ${Boost_INCLUDE_DIR} |
43 | 49 | ) |
44 | 50 | |
... | ... | @@ -54,8 +60,10 @@ add_executable(netmets |
54 | 60 | |
55 | 61 | #set the link libraries |
56 | 62 | target_link_libraries(netmets |
63 | + ${OpenGL_LIBRARIES} | |
64 | + ${GLUT_LIBRARIES} | |
57 | 65 | ${CMAKE_THREAD_LIBS_INIT} |
58 | - ${ANN_LIBRARY} | |
66 | + ${ANN_LIBRARY} | |
59 | 67 | ${X11_LIBRARIES} |
60 | 68 | ) |
61 | 69 | ... | ... |
1 | +#.rst: | |
2 | +# FindGLUT | |
3 | +# -------- | |
4 | +# | |
5 | +# try to find glut library and include files. | |
6 | +# | |
7 | +# IMPORTED Targets | |
8 | +# ^^^^^^^^^^^^^^^^ | |
9 | +# | |
10 | +# This module defines the :prop_tgt:`IMPORTED` targets: | |
11 | +# | |
12 | +# ``GLUT::GLUT`` | |
13 | +# Defined if the system has GLUT. | |
14 | +# | |
15 | +# Result Variables | |
16 | +# ^^^^^^^^^^^^^^^^ | |
17 | +# | |
18 | +# This module sets the following variables: | |
19 | +# | |
20 | +# :: | |
21 | +# | |
22 | +# GLUT_INCLUDE_DIR, where to find GL/glut.h, etc. | |
23 | +# GLUT_LIBRARIES, the libraries to link against | |
24 | +# GLUT_FOUND, If false, do not try to use GLUT. | |
25 | +# | |
26 | +# Also defined, but not for general use are: | |
27 | +# | |
28 | +# :: | |
29 | +# | |
30 | +# GLUT_glut_LIBRARY = the full path to the glut library. | |
31 | +# GLUT_Xmu_LIBRARY = the full path to the Xmu library. | |
32 | +# GLUT_Xi_LIBRARY = the full path to the Xi Library. | |
33 | + | |
34 | +#============================================================================= | |
35 | +# Copyright 2001-2009 Kitware, Inc. | |
36 | +# | |
37 | +# Distributed under the OSI-approved BSD License (the "License"); | |
38 | +# see accompanying file Copyright.txt for details. | |
39 | +# | |
40 | +# This software is distributed WITHOUT ANY WARRANTY; without even the | |
41 | +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
42 | +# See the License for more information. | |
43 | +#============================================================================= | |
44 | +# (To distribute this file outside of CMake, substitute the full | |
45 | +# License text for the above reference.) | |
46 | + | |
47 | +if (WIN32) | |
48 | + find_path( GLUT_INCLUDE_DIR NAMES GL/glut.h | |
49 | + PATHS $ENV{GLUT_ROOT_PATH}/include ) | |
50 | + find_library( GLUT_glut_LIBRARY NAMES glut glut32 freeglut | |
51 | + PATHS | |
52 | + ${OPENGL_LIBRARY_DIR} | |
53 | + $ENV{GLUT_ROOT_PATH}/lib | |
54 | + ) | |
55 | +else () | |
56 | + | |
57 | + if (APPLE) | |
58 | + find_path(GLUT_INCLUDE_DIR glut.h ${OPENGL_LIBRARY_DIR}) | |
59 | + find_library(GLUT_glut_LIBRARY GLUT DOC "GLUT library for OSX") | |
60 | + find_library(GLUT_cocoa_LIBRARY Cocoa DOC "Cocoa framework for OSX") | |
61 | + | |
62 | + if(GLUT_cocoa_LIBRARY AND NOT TARGET GLUT::Cocoa) | |
63 | + add_library(GLUT::Cocoa UNKNOWN IMPORTED) | |
64 | + # Cocoa should always be a Framework, but we check to make sure. | |
65 | + if(GLUT_cocoa_LIBRARY MATCHES "/([^/]+)\\.framework$") | |
66 | + set_target_properties(GLUT::Cocoa PROPERTIES | |
67 | + IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}/${CMAKE_MATCH_1}") | |
68 | + else() | |
69 | + set_target_properties(GLUT::Cocoa PROPERTIES | |
70 | + IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}") | |
71 | + endif() | |
72 | + endif() | |
73 | + else () | |
74 | + | |
75 | + if (BEOS) | |
76 | + | |
77 | + set(_GLUT_INC_DIR /boot/develop/headers/os/opengl) | |
78 | + set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86) | |
79 | + | |
80 | + else() | |
81 | + | |
82 | + find_library( GLUT_Xi_LIBRARY Xi | |
83 | + /usr/openwin/lib | |
84 | + ) | |
85 | + | |
86 | + find_library( GLUT_Xmu_LIBRARY Xmu | |
87 | + /usr/openwin/lib | |
88 | + ) | |
89 | + | |
90 | + if(GLUT_Xi_LIBRARY AND NOT TARGET GLUT::Xi) | |
91 | + add_library(GLUT::Xi UNKNOWN IMPORTED) | |
92 | + set_target_properties(GLUT::Xi PROPERTIES | |
93 | + IMPORTED_LOCATION "${GLUT_Xi_LIBRARY}") | |
94 | + endif() | |
95 | + | |
96 | + if(GLUT_Xmu_LIBRARY AND NOT TARGET GLUT::Xmu) | |
97 | + add_library(GLUT::Xmu UNKNOWN IMPORTED) | |
98 | + set_target_properties(GLUT::Xmu PROPERTIES | |
99 | + IMPORTED_LOCATION "${GLUT_Xmu_LIBRARY}") | |
100 | + endif() | |
101 | + | |
102 | + endif () | |
103 | + | |
104 | + find_path( GLUT_INCLUDE_DIR GL/glut.h | |
105 | + /usr/include/GL | |
106 | + /usr/openwin/share/include | |
107 | + /usr/openwin/include | |
108 | + /opt/graphics/OpenGL/include | |
109 | + /opt/graphics/OpenGL/contrib/libglut | |
110 | + ${_GLUT_INC_DIR} | |
111 | + ) | |
112 | + | |
113 | + find_library( GLUT_glut_LIBRARY glut | |
114 | + /usr/openwin/lib | |
115 | + ${_GLUT_glut_LIB_DIR} | |
116 | + ) | |
117 | + | |
118 | + unset(_GLUT_INC_DIR) | |
119 | + unset(_GLUT_glut_LIB_DIR) | |
120 | + | |
121 | + endif () | |
122 | + | |
123 | +endif () | |
124 | + | |
125 | +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_glut_LIBRARY GLUT_INCLUDE_DIR) | |
126 | + | |
127 | +if (GLUT_FOUND) | |
128 | + # Is -lXi and -lXmu required on all platforms that have it? | |
129 | + # If not, we need some way to figure out what platform we are on. | |
130 | + set( GLUT_LIBRARIES | |
131 | + ${GLUT_glut_LIBRARY} | |
132 | + ${GLUT_Xmu_LIBRARY} | |
133 | + ${GLUT_Xi_LIBRARY} | |
134 | + ${GLUT_cocoa_LIBRARY} | |
135 | + ) | |
136 | + | |
137 | + if(NOT TARGET GLUT::GLUT) | |
138 | + add_library(GLUT::GLUT UNKNOWN IMPORTED) | |
139 | + set_target_properties(GLUT::GLUT PROPERTIES | |
140 | + INTERFACE_INCLUDE_DIRECTORIES "${GLUT_INCLUDE_DIR}") | |
141 | + if(GLUT_glut_LIBRARY MATCHES "/([^/]+)\\.framework$") | |
142 | + set_target_properties(GLUT::GLUT PROPERTIES | |
143 | + IMPORTED_LOCATION "${GLUT_glut_LIBRARY}/${CMAKE_MATCH_1}") | |
144 | + else() | |
145 | + set_target_properties(GLUT::GLUT PROPERTIES | |
146 | + IMPORTED_LOCATION "${GLUT_glut_LIBRARY}") | |
147 | + endif() | |
148 | + | |
149 | + if(TARGET GLUT::Xmu) | |
150 | + set_property(TARGET GLUT::GLUT APPEND | |
151 | + PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Xmu) | |
152 | + endif() | |
153 | + | |
154 | + if(TARGET GLUT::Xi) | |
155 | + set_property(TARGET GLUT::GLUT APPEND | |
156 | + PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Xi) | |
157 | + endif() | |
158 | + | |
159 | + if(TARGET GLUT::Cocoa) | |
160 | + set_property(TARGET GLUT::GLUT APPEND | |
161 | + PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Cocoa) | |
162 | + endif() | |
163 | + endif() | |
164 | + | |
165 | + #The following deprecated settings are for backwards compatibility with CMake1.4 | |
166 | + set (GLUT_LIBRARY ${GLUT_LIBRARIES}) | |
167 | + set (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIR}) | |
168 | +endif() | |
169 | + | |
170 | +mark_as_advanced( | |
171 | + GLUT_INCLUDE_DIR | |
172 | + GLUT_glut_LIBRARY | |
173 | + GLUT_Xmu_LIBRARY | |
174 | + GLUT_Xi_LIBRARY | |
175 | + ) | ... | ... |
main.cpp
... | ... | @@ -2,44 +2,220 @@ |
2 | 2 | #include <string> |
3 | 3 | #include <fstream> |
4 | 4 | #include <algorithm> |
5 | -#include <stim/biomodels/network.h> | |
6 | 5 | |
6 | +//OpenGL includes | |
7 | +#include <GL/glut.h> | |
8 | + | |
9 | +//STIM includes | |
10 | +#include <stim/visualization/gl_network.h> | |
11 | +#include <stim/visualization/gl_aabb.h> | |
12 | +#include <stim/parser/arguments.h> | |
13 | +#include <stim/visualization/camera.h> | |
14 | + | |
15 | +//ANN includes | |
7 | 16 | #include <ANN/ANN.h> |
17 | + | |
18 | +//BOOST includes | |
8 | 19 | #include <boost/tuple/tuple.hpp> |
9 | -using namespace stim; | |
10 | -//template <typename T> | |
11 | -network<float>* network1; | |
12 | 20 | |
21 | +stim::gl_aabb<float> bb; | |
22 | +stim::camera cam; | |
23 | + | |
24 | +stim::gl_network<float> GT; | |
25 | +stim::gl_network<float> T; | |
26 | + | |
27 | +//hard-coded parameters | |
28 | +float resample_rate = 0.5; | |
29 | + | |
30 | +//mouse position tracking | |
31 | +int mouse_x; | |
32 | +int mouse_y; | |
33 | + | |
34 | +void glut_render(void) { | |
35 | + | |
36 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
37 | + | |
38 | + glMatrixMode(GL_MODELVIEW); | |
39 | + glLoadIdentity(); | |
40 | + stim::vec<float> eye = cam.getPosition(); | |
41 | + stim::vec<float> focus = cam.getLookAt(); | |
42 | + stim::vec<float> up = cam.getUp(); | |
43 | + | |
44 | + gluLookAt(eye[0], eye[1], eye[2], focus[0], focus[1], focus[2], up[0], up[1], up[2]); | |
45 | + | |
46 | + | |
47 | + | |
48 | + // render the bounding box | |
49 | + glColor3f(0.0, 0.0, 1.0); | |
50 | + glBegin(GL_LINE_LOOP); | |
51 | + bb.glPointsCW(); | |
52 | + glEnd(); | |
53 | + | |
54 | + //render the GT network (red) | |
55 | + glColor3f(1.0, 0.0, 0.0); | |
56 | + GT.glCenterline(); | |
57 | + | |
58 | + //render the T network (green) | |
59 | + glColor3f(0.0, 1.0, 0.0); | |
60 | + T.glCenterline(); | |
61 | + | |
62 | + glutSwapBuffers(); | |
63 | +} | |
64 | + | |
65 | +// defines camera motion based on mouse dragging | |
66 | +void glut_motion(int x, int y){ | |
67 | + float factor = 0.01; | |
68 | + | |
69 | + float theta = factor * (mouse_x - x); | |
70 | + float phi = factor * (y - mouse_y); | |
71 | + | |
72 | + cam.OrbitFocus(theta, phi); | |
73 | + | |
74 | + mouse_x = x; | |
75 | + mouse_y = y; | |
76 | + | |
77 | + glutPostRedisplay(); | |
78 | +} | |
79 | + | |
80 | +// sets the mouse position when clicked | |
81 | +void glut_mouse(int button, int state, int x, int y){ | |
82 | + mouse_x = x; | |
83 | + mouse_y = y; | |
84 | +} | |
85 | + | |
86 | +// re-calculates the projection matrix if the window is reshaped | |
87 | +void glut_reshape(int x, int y){ | |
88 | + | |
89 | + glMatrixMode(GL_PROJECTION); | |
90 | + glLoadIdentity(); | |
91 | + glViewport(0, 0, x, y); | |
92 | + float aspect = (float)x / (float)y; | |
93 | + gluPerspective(60, aspect, 0.1, 1000000); | |
94 | + | |
95 | +} | |
96 | + | |
97 | +void advertise(){ | |
98 | + //output advertisement | |
99 | + std::cout<<std::endl<<std::endl; | |
100 | + std::cout<<"========================================================================="<<std::endl; | |
101 | + std::cout<<"Thank you for using the NetMets network comparison tool!"<<std::endl; | |
102 | + std::cout<<"Scalable Tissue Imaging and Modeling (STIM) Lab, University of Houston"<<std::endl; | |
103 | + std::cout<<"Developers: Pranathi Vemuri, David Mayerich"<<std::endl; | |
104 | + std::cout<<"Source: https://git.stim.ee.uh.edu/segmentation/netmets"<<std::endl; | |
105 | + std::cout<<"========================================================================="<<std::endl<<std::endl; | |
106 | + | |
107 | + std::cout<<"usage: netmets file1 file2 --sigma 10"<<std::endl; | |
108 | + std::cout<<" compare two files with a tolerance of 10 (units defined by the network)"<<std::endl; | |
109 | + std::cout<<" netmets file1 --gui"<<std::endl<<std::endl; | |
110 | + std::cout<<" load a file and display it using OpenGL"<<std::endl; | |
111 | + | |
112 | +} | |
113 | + | |
114 | +void compare(float sigma){ | |
115 | + | |
116 | + // compare ground truth with truth and viceversa | |
117 | + stim::network<float> cGT = GT.compare(T, sigma); | |
118 | + stim::network<float> cT = T.compare(GT, sigma); | |
119 | + | |
120 | + //calculate the metrics | |
121 | + float FPR = cGT.average(1); | |
122 | + float FNR = cT.average(1); | |
123 | + // print false alarms and misses | |
124 | + std::cout << "FNR: " << FPR << std::endl; | |
125 | + std::cout << "FPR: " << FNR << std::endl; | |
126 | +} | |
127 | + | |
128 | +void glut_initialize(){ | |
129 | + float factor = 1.2; | |
130 | + | |
131 | + // init GLUT and create Window | |
132 | + int myargc = 1; | |
133 | + char* myargv[1]; | |
134 | + myargv [0]=strdup ("netmets"); | |
135 | + | |
136 | + glutInit(&myargc, myargv); | |
137 | + glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); | |
138 | + glutInitWindowPosition(100,100); | |
139 | + glutInitWindowSize(320,320); | |
140 | + glutCreateWindow("Lighthouse3D- GLUT Tutorial"); | |
141 | + | |
142 | + | |
143 | + // register callbacks | |
144 | + glutDisplayFunc(glut_render); | |
145 | + glutMouseFunc(glut_mouse); | |
146 | + glutMotionFunc(glut_motion); | |
147 | + glutReshapeFunc(glut_reshape); | |
148 | + | |
149 | + //set up the camera | |
150 | + stim::vec<float> c = bb.center(); | |
151 | + //place the camera along the z-axis at a distance determined by the network size along x and y | |
152 | + cam.setPosition(c + stim::vec<float>(0, 0, factor * std::max(bb.size()[0], bb.size()[1]))); | |
153 | + cam.LookAt(c[0], c[1], c[2]); //look at the center | |
154 | + | |
155 | +} | |
156 | + | |
157 | +void display(){ | |
158 | + | |
159 | + | |
160 | + //generate a bounding volume | |
161 | + bb = GT.boundingbox(); | |
162 | + | |
163 | + std::cout<<bb.str()<<std::endl; | |
164 | + | |
165 | + std::cout<<"center: "<<bb.center().str()<<std::endl; | |
166 | + std::cout<<"size: "<<bb.size().str()<<std::endl; | |
167 | + | |
168 | + //create the GLUT window and set callback functions | |
169 | + glut_initialize(); | |
170 | + | |
171 | + glut_reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)); | |
172 | + | |
173 | + std::cout<<cam.str()<<std::endl; | |
174 | + | |
175 | + // enter GLUT event processing cycle | |
176 | + glutMainLoop(); | |
177 | +} | |
13 | 178 | |
14 | 179 | int main(int argc, char* argv[]) |
15 | 180 | { |
16 | - if(argc < 4){ | |
17 | - std::cout<<"Please specify a ground truth and test case"<<std::endl; | |
181 | + //create an instance of arglist | |
182 | + stim::arglist args; | |
183 | + | |
184 | + //add arguments | |
185 | + args.add("help", "prints this help"); | |
186 | + args.add("sigma", "force a sigma value to specify the tolerance of the network comparison", "10"); | |
187 | + args.add("gui", "display the network or network comparison using OpenGL"); | |
188 | + | |
189 | + //parse the user arguments | |
190 | + args.parse(argc, argv); | |
191 | + | |
192 | + //test for help | |
193 | + if(args["help"].is_set() || args.nargs() == 0){ | |
194 | + advertise(); | |
195 | + std::cout<<args.str(); | |
18 | 196 | exit(1); |
19 | 197 | } |
20 | 198 | |
21 | - float resample_rate = 0.1; | |
199 | + //if one file is specified, load it as the ground truth | |
200 | + if(args.nargs() >= 1){ | |
201 | + GT.load_obj(args.arg(0)); | |
202 | + } | |
22 | 203 | |
23 | - float sigma = atof(argv[3]); | |
24 | - stim::network<float> GT;stim::network<float> T; | |
25 | - // load obj files to 3D network class | |
26 | - | |
27 | - //load the ground truth and test case networks | |
28 | - GT.load_obj(argv[1]); | |
29 | - T.load_obj(argv[2]); | |
204 | + //if two files are provided, compare them | |
205 | + if(args.nargs() == 2){ | |
206 | + float sigma = args["sigma"].as_float(); //get the sigma value from the user | |
207 | + T.load_obj(args.arg(1)); //load the second (test) network | |
30 | 208 | |
31 | - // resample the loaded networks | |
32 | - stim::network<float> resampled_GT; | |
33 | - stim::network<float> resampled_T; | |
209 | + GT = GT.resample(resample_rate * sigma); //resample both networks based on the sigma value | |
210 | + T = T.resample(resample_rate * sigma); | |
34 | 211 | |
35 | - resampled_GT = GT.resample(sigma * resample_rate); | |
36 | - resampled_T = T.resample(sigma * resample_rate); | |
212 | + compare(sigma); //run the comparison algorithm | |
213 | + } | |
37 | 214 | |
38 | - // compare ground truth with truth and viceversa | |
39 | - float gFPR, gFNR; | |
40 | - gFPR = resampled_GT.compare(resampled_T, sigma); | |
41 | - gFNR = resampled_T.compare(resampled_GT, sigma); | |
42 | - // print false alarms and misses | |
43 | - std::cout << "False postive rate is " << gFPR << std::endl; | |
44 | - std::cout << "False negative rate is " << gFNR << std::endl; | |
215 | + //if a GUI is requested, display the network using OpenGL | |
216 | + if(args["gui"].is_set()) | |
217 | + display(); | |
218 | + | |
219 | + | |
220 | + | |
45 | 221 | } |
46 | 222 | \ No newline at end of file | ... | ... |