Commit 00eb682565259cb617d3c9e675fe609204d58290
Merge branch 'master' of git.stim.ee.uh.edu:codebase/stimlib
Showing
12 changed files
with
558 additions
and
18 deletions
Show diff stats
1 | +# - Try to find ANN | |
2 | +# Once done this will define | |
3 | +# | |
4 | +# ANN_FOUND - system has ANN | |
5 | +# ANN_INCLUDE_DIR - the ANN include directory | |
6 | +# ANN_LIBRARY - Link these to use ANN | |
7 | +# | |
8 | + | |
9 | +IF (ANN_INCLUDE_DIRS) | |
10 | + # Already in cache, be silent | |
11 | + SET(ANN_FIND_QUIETLY TRUE) | |
12 | +ENDIF (ANN_INCLUDE_DIRS) | |
13 | + | |
14 | +FIND_PATH( ANN_INCLUDE_DIR ANN/ANN.h | |
15 | + PATHS "/usr/include" "C:/libs/ANN/include") | |
16 | + | |
17 | +if( WIN32 ) | |
18 | + | |
19 | + set(ANN_LIBRARY $ENV{ANN_PATH}\\ANN.lib) | |
20 | + set(ANN_INCLUDE_DIR $ENV{ANN_PATH}) | |
21 | + | |
22 | + | |
23 | + # Store the library dir. May be used for linking to dll! | |
24 | + # GET_FILENAME_COMPONENT( ANN_LIBRARY_DIR ${ANN_LIBRARY} PATH ) | |
25 | + | |
26 | + find_package_handle_standard_args(ANN DEFAULT_MSG ANN_INCLUDE_DIR) | |
27 | + | |
28 | +else (WIN32) | |
29 | + | |
30 | + FIND_LIBRARY( ANN_LIBRARY | |
31 | + NAMES ann ANN | |
32 | + PATHS /lib /usr/lib /usr/lib64 /usr/local/lib ) | |
33 | + | |
34 | +endif( WIN32) | |
35 | + | |
36 | + | |
37 | +IF (ANN_INCLUDE_DIR AND ANN_LIBRARY) | |
38 | + SET(ANN_FOUND TRUE) | |
39 | +ELSE (ANN_INCLUDE_DIR AND ANN_LIBRARY) | |
40 | + SET( ANN_FOUND FALSE ) | |
41 | +ENDIF (ANN_INCLUDE_DIR AND ANN_LIBRARY) | |
42 | + | ... | ... |
FindSTIM.cmake renamed to cmake/FindSTIM.cmake
1 | +#ifndef STIM_NETWORK_H | |
2 | +#define STIM_NETWORK_H | |
3 | + | |
4 | +#include <stim/math/vector.h> | |
5 | +#include <stim/visualization/obj.h> | |
6 | +#include <list> | |
7 | +#include <ANN/ANN.h> | |
8 | + | |
9 | +namespace stim{ | |
10 | + | |
11 | +/** This class provides an interface for dealing with biological networks. | |
12 | + * It takes the following aspects into account: | |
13 | + * 1) Network geometry and centerlines | |
14 | + * 2) Network connectivity (a graph structure can be extracted) | |
15 | + * 3) Network surface structure (the surface is represented as a triangular mesh and referenced to the centerline) | |
16 | + */ | |
17 | + | |
18 | +template<typename T> | |
19 | +class network{ | |
20 | + | |
21 | + //helper classes | |
22 | + /// Stores information about a geometric point on the network centerline (including point position and radius) | |
23 | + //template<typename T> | |
24 | + class point : public stim::vec<T>{ | |
25 | + | |
26 | + public: | |
27 | + T r; | |
28 | + | |
29 | + point() : stim::vec<T>(){} | |
30 | + | |
31 | + //casting constructor | |
32 | + point(stim::vec<T> rhs) : stim::vec<T>(rhs){} | |
33 | + }; | |
34 | + | |
35 | + //template<typename T> | |
36 | + class t_node; | |
37 | + class fiber; | |
38 | + | |
39 | + //create typedefs for the iterators to simplify the network code | |
40 | + typedef typename std::list< fiber >::iterator fiber_i; | |
41 | + typedef typename std::list< t_node >::iterator t_node_i; | |
42 | + | |
43 | + /// Stores information about a single capillary (a length of vessel between two branch or end points) | |
44 | + //template<typename T> | |
45 | + class fiber{ | |
46 | + | |
47 | + public: | |
48 | + std::list< point > P; //geometric point positions | |
49 | + | |
50 | + typename std::list< t_node >::iterator n[2]; //indices to terminal nodes | |
51 | + unsigned int id; | |
52 | + | |
53 | + public: | |
54 | + | |
55 | + /// Calculate the length of the fiber and return it. | |
56 | + T length(){ | |
57 | + | |
58 | + point p0, p1; | |
59 | + T l = 0; //initialize the length to zero | |
60 | + | |
61 | + //for each point | |
62 | + typename std::list< point >::iterator i; //create a point iterator | |
63 | + for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber | |
64 | + | |
65 | + if(i == P.begin()) //if this is the first point, just store it | |
66 | + p1 = *i; | |
67 | + else{ //if this is any other point | |
68 | + p0 = p1; //shift p1->p0 | |
69 | + p1 = *i; //set p1 to the new point | |
70 | + l += (p1 - p0).len(); //add the length of p1 - p0 to the running sum | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + return l; //return the length | |
75 | + } | |
76 | + | |
77 | + T radius(T& length){ | |
78 | + | |
79 | + point p0, p1; //temporary variables to store point positions | |
80 | + T r0, r1; //temporary variables to store radii at points | |
81 | + T l, r; //temporary variable to store the length and average radius of a fiber segment | |
82 | + T length_sum = 0; //initialize the length to zero | |
83 | + T radius_sum = 0; //initialize the radius sum to zero | |
84 | + | |
85 | + //for each point | |
86 | + typename std::list< point >::iterator i; //create a point iterator | |
87 | + for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber | |
88 | + | |
89 | + if(i == P.begin()){ //if this is the first point, just store it | |
90 | + p1 = *i; | |
91 | + r1 = i->r; | |
92 | + } | |
93 | + else{ //if this is any other point | |
94 | + p0 = p1; //shift p1->p0 and r1->r0 | |
95 | + r0 = r1; | |
96 | + p1 = *i; //set p1 to the new point | |
97 | + r1 = i->r; //and r1 | |
98 | + | |
99 | + l = (p1 - p0).len(); //calculate the length of the p0-p1 segment | |
100 | + r = (r0 + r1) / 2; //calculate the average radius of the segment | |
101 | + | |
102 | + radius_sum += r * l; //add the radius scaled by the length to a running sum | |
103 | + length_sum += l; //add the length of p1 - p0 to the running sum | |
104 | + } | |
105 | + } | |
106 | + | |
107 | + length = length_sum; //store the total length | |
108 | + return radius_sum / length; //return the average radius of the fiber | |
109 | + } | |
110 | + | |
111 | + std::string str(){ | |
112 | + std::stringstream ss; | |
113 | + | |
114 | + //create an iterator for the point list | |
115 | + typename std::list<point>::iterator i; | |
116 | + for(i = P.begin(); i != P.end(); i++){ | |
117 | + ss<<i->str()<<" r = "<<i->r<<std::endl; | |
118 | + } | |
119 | + | |
120 | + return ss.str(); | |
121 | + } | |
122 | + }; | |
123 | + | |
124 | + /// Terminal node for a capillary. This is analogous to a graph vertex and contains a list of edge indices. | |
125 | + //template<typename T> | |
126 | + class t_node{ | |
127 | + | |
128 | + public: | |
129 | + | |
130 | + unsigned int id; | |
131 | + | |
132 | + //lists of edge indices for capillaries | |
133 | + //the "in" and "out" just indicate how the geometry is defined: | |
134 | + // edges in the "in" list are geometrically oriented such that the terminal node is last | |
135 | + // edges in the "out" list are geometrically oriented such that the terminal node is first | |
136 | + std::list< fiber_i > in; //edge indices for incoming capillaries | |
137 | + std::list< fiber_i > out; //edge indices for outgoing capillaries | |
138 | + | |
139 | + std::string str(){ | |
140 | + | |
141 | + std::stringstream ss; | |
142 | + | |
143 | + ss<<id<<": "; //output the node ID | |
144 | + | |
145 | + //output the IDs for both lists | |
146 | + typename std::list< fiber_i >::iterator f; | |
147 | + | |
148 | + for(f = in.begin(); f != in.end(); f++){ | |
149 | + | |
150 | + if(f != in.begin()) | |
151 | + ss<<", "; | |
152 | + ss<<(*f)->n[0]->id; | |
153 | + } | |
154 | + | |
155 | + //if there are nodes in both lists, separate them by a comma | |
156 | + if(out.size() > 0 && in.size() > 0) | |
157 | + ss<<", "; | |
158 | + | |
159 | + for(f = out.begin(); f != out.end(); f++){ | |
160 | + | |
161 | + if(f != out.begin()) | |
162 | + ss<<", "; | |
163 | + ss<<(*f)->n[1]->id; | |
164 | + } | |
165 | + | |
166 | + | |
167 | + return ss.str(); | |
168 | + | |
169 | + | |
170 | + | |
171 | + } | |
172 | + }; | |
173 | + | |
174 | + | |
175 | + | |
176 | + | |
177 | +protected: | |
178 | + | |
179 | + //list of terminal nodes | |
180 | + std::list<t_node> N; | |
181 | + | |
182 | + //list of fibers | |
183 | + std::list<fiber> F; | |
184 | + | |
185 | + /// Sets a unique ID for each terminal node and fiber | |
186 | + void set_names(){ | |
187 | + | |
188 | + unsigned int i; | |
189 | + | |
190 | + i = 0; | |
191 | + for(t_node_i ti = N.begin(); ti != N.end(); ti++) | |
192 | + ti->id = i++; | |
193 | + | |
194 | + i = 0; | |
195 | + for(fiber_i fi = F.begin(); fi != F.end(); fi++) | |
196 | + fi->id = i++; | |
197 | + } | |
198 | + | |
199 | +public: | |
200 | + | |
201 | + std::string str(){ | |
202 | + | |
203 | + | |
204 | + //assign names to elements of the network | |
205 | + set_names(); | |
206 | + | |
207 | + //create a stringstream for output | |
208 | + std::stringstream ss; | |
209 | + | |
210 | + //output the nodes | |
211 | + ss<<"Nodes----------------------------"<<std::endl; | |
212 | + for(t_node_i i = N.begin(); i != N.end(); i++){ | |
213 | + ss<<i->str()<<std::endl; | |
214 | + } | |
215 | + | |
216 | + //output the fibers | |
217 | + ss<<std::endl<<"Fibers---------------------------"<<std::endl; | |
218 | + | |
219 | + T length, radius; | |
220 | + //output every fiber | |
221 | + for(fiber_i f = F.begin(); f != F.end(); f++){ | |
222 | + | |
223 | + //calculate the length and average radius | |
224 | + radius = f->radius(length); | |
225 | + | |
226 | + //output the IDs of the terminal nodes | |
227 | + ss<<f->n[0]->id<<" -- "<<f->n[1]->id<<": length = "<<length<<", average radius = "<<radius<<std::endl; | |
228 | + } | |
229 | + | |
230 | + return ss.str(); | |
231 | + } | |
232 | + | |
233 | + /// Load a network from an OBJ object | |
234 | + void load( stim::obj<T> object){ | |
235 | + | |
236 | + //get the number of vertices in the object | |
237 | + unsigned int nV = object.numV(); | |
238 | + | |
239 | + //allocate an array of pointers to nodes, which will be used to preserve connectivity | |
240 | + //initiate all values to T.end() | |
241 | + std::vector< t_node_i > node_hash(nV, N.end()); | |
242 | + | |
243 | + unsigned int nL = object.numL(); //get the number of lines in the OBJ | |
244 | + | |
245 | + //for each line in the OBJ structure | |
246 | + for(unsigned int li = 0; li < nL; li++){ | |
247 | + | |
248 | + F.push_back(fiber()); //push a new fiber onto the fiber list | |
249 | + | |
250 | + fiber_i f = --(F.end()); //get an iterator to the new fiber | |
251 | + | |
252 | + //----------Handle the terminating nodes for the fiber | |
253 | + | |
254 | + //get the indices of the line vertices | |
255 | + std::vector< unsigned int > Li = object.getL_Vi(li); | |
256 | + unsigned int i0 = Li.front() - 1; | |
257 | + unsigned int i1 = Li.back() - 1; | |
258 | + | |
259 | + //deal with the first end point of the capillary | |
260 | + if(node_hash[i0] != N.end()){ //if the node has been used before | |
261 | + (*f).n[0] = node_hash[i0]; //assign the node to the new capillary | |
262 | + (*node_hash[i0]).out.push_back(f); //add an out pointer to the existing node | |
263 | + } | |
264 | + else{ //otherwise | |
265 | + N.push_back(t_node()); //create a new node and add it to the node list | |
266 | + t_node_i t = --(N.end()); //get an iterator to the new node | |
267 | + node_hash[i0] = t; //add a pointer to the new node to the hash list | |
268 | + (*f).n[0] = t; //add a pointer to the new node to the capillary | |
269 | + (*t).out.push_back(f); //add a pointer to the capillary to the new node | |
270 | + } | |
271 | + | |
272 | + //deal with the last end point of the capillary | |
273 | + if(node_hash[i1] != N.end()){ | |
274 | + (*f).n[1] = node_hash[i1]; | |
275 | + (*node_hash[i1]).in.push_back(f); | |
276 | + } | |
277 | + else{ | |
278 | + N.push_back(t_node()); | |
279 | + t_node_i t = --(N.end()); | |
280 | + node_hash[i1] = t; //add the new node to the hash list | |
281 | + (*f).n[1] = t; | |
282 | + (*t).in.push_back(f); | |
283 | + } | |
284 | + | |
285 | + //-------------Handle the geometric points for the fiber | |
286 | + std::vector< vec<T> > L = object.getL_V(li); | |
287 | + std::vector< vec<T> > R = object.getL_VT(li); | |
288 | + | |
289 | + unsigned int nP = L.size(); //get the number of geometric points in the fiber | |
290 | + //for each vertex in the fiber | |
291 | + for(unsigned int pi = 0; pi < nP; pi++){ | |
292 | + point p = (point)L[pi]; //move the geometric coordinates into a point structure | |
293 | + p.r = R[pi][0]; //store the radius | |
294 | + f->P.push_back(p); //push the point onto the current fiber | |
295 | + } | |
296 | + } | |
297 | + | |
298 | + } //end load() | |
299 | + | |
300 | + /// This function returns the information necessary for a simple graph-based physical (ex. fluid) simulation. | |
301 | + | |
302 | + /// @param n0 is a array which will contain the list of source nodes | |
303 | + /// @param n1 is a array which will contain the list of destination nodes | |
304 | + /// @param length is a array containing the lengths of fibers in the network | |
305 | + /// @param radius is a array containing the average radii of fibers in the network | |
306 | + void build_simgraph(std::vector<unsigned int>& n0, std::vector<unsigned int>& n1, std::vector<T>& length, std::vector<T>& radius){ | |
307 | + | |
308 | + //determine the number of fibers in the network | |
309 | + unsigned int nF = F.size(); | |
310 | + | |
311 | + //allocate the necessary space to store the fiber information | |
312 | + n0.resize(nF); | |
313 | + n1.resize(nF); | |
314 | + length.resize(nF); | |
315 | + radius.resize(nF); | |
316 | + | |
317 | + //assign names (identifiers) to the network components | |
318 | + set_names(); | |
319 | + | |
320 | + //fill the arrays | |
321 | + unsigned int i = 0; | |
322 | + T l, r; | |
323 | + for(fiber_i f = F.begin(); f != F.end(); f++){ | |
324 | + n0[i] = f->n[0]->id; //get the identifiers for the first and second nodes for the current fiber | |
325 | + n1[i] = f->n[1]->id; | |
326 | + | |
327 | + r = f->radius(l); //get the length and radius of the capillary (calculated at the same time) | |
328 | + | |
329 | + radius[i] = r; //store the radius in the output array | |
330 | + length[i] = l; //store the length in the output array | |
331 | + | |
332 | + i++; //increment the array index | |
333 | + } | |
334 | + | |
335 | + | |
336 | + } | |
337 | + | |
338 | +}; | |
339 | + | |
340 | +}; //end namespace stim | |
341 | + | |
342 | + | |
343 | +#endif | ... | ... |
stim/envi/bil.h
... | ... | @@ -826,7 +826,7 @@ public: |
826 | 826 | } |
827 | 827 | |
828 | 828 | ///Saves to disk only those spectra corresponding to mask values != 0 |
829 | - bool sift_mask(std::string outfile, unsigned char* p){ | |
829 | + bool sift(std::string outfile, unsigned char* p){ | |
830 | 830 | // Assume X() = X, Y() = Y, Z() = Z. |
831 | 831 | std::ofstream target(outfile.c_str(), std::ios::binary); |
832 | 832 | ... | ... |
stim/envi/binary.h
... | ... | @@ -100,7 +100,7 @@ public: |
100 | 100 | /// @param filename is the name of the binary file |
101 | 101 | /// @param r is a STIM vector specifying the size of the binary file along each dimension |
102 | 102 | /// @param h is the length (in bytes) of any header file (default zero) |
103 | - bool open(std::string filename, vec<unsigned int, D> r, unsigned int h = 0){ | |
103 | + bool open(std::string filename, vec<unsigned int> r, unsigned int h = 0){ | |
104 | 104 | |
105 | 105 | for(unsigned int i = 0; i < D; i++) //set the dimensions of the binary file object |
106 | 106 | R[i] = r[i]; |
... | ... | @@ -117,7 +117,7 @@ public: |
117 | 117 | /// @param filename is the name of the binary file to be created |
118 | 118 | /// @param r is a STIM vector specifying the size of the file along each dimension |
119 | 119 | /// @offset specifies how many bytes to offset the file (used to leave room for a header) |
120 | - bool create(std::string filename, vec<unsigned int, D> r, unsigned int offset = 0){ | |
120 | + bool create(std::string filename, vec<unsigned int> r, unsigned int offset = 0){ | |
121 | 121 | |
122 | 122 | std::ofstream target(filename.c_str(), std::ios::binary); |
123 | 123 | ... | ... |
stim/envi/bip.h
... | ... | @@ -836,8 +836,8 @@ public: |
836 | 836 | } |
837 | 837 | |
838 | 838 | |
839 | - ///Saves to disk only those spectra corresponding to mask values != 0 | |
840 | - bool sift_mask(std::string outfile, unsigned char* p){ | |
839 | + /// Saves to disk only those spectra corresponding to mask values != 0 | |
840 | + bool sift(std::string outfile, unsigned char* p){ | |
841 | 841 | // Assume X() = X, Y() = Y, Z() = Z. |
842 | 842 | std::ofstream target(outfile.c_str(), std::ios::binary); |
843 | 843 | ... | ... |
stim/envi/bsq.h
... | ... | @@ -759,8 +759,8 @@ public: |
759 | 759 | return true; |
760 | 760 | } |
761 | 761 | |
762 | - ///Saves to disk only those spectra corresponding to mask values != 0 | |
763 | - bool sift_mask(std::string outfile, unsigned char* p){ | |
762 | + /// Saves to disk only those spectra corresponding to mask values != 0 | |
763 | + bool sift(std::string outfile, unsigned char* p){ | |
764 | 764 | std::ofstream target(outfile.c_str(), std::ios::binary); |
765 | 765 | // open a band (XY plane) |
766 | 766 | unsigned XY = X() * Y(); //Number of XY pixels |
... | ... | @@ -788,6 +788,57 @@ public: |
788 | 788 | return true; |
789 | 789 | } |
790 | 790 | |
791 | + /// Generates a spectral image from a matrix of spectral values in lexicographic order and a mask | |
792 | + bool unsift(std::string outfile, unsigned char* p, unsigned int samples, unsigned int lines){ | |
793 | + | |
794 | + //create a binary output stream | |
795 | + std::ofstream target(outfile.c_str(), std::ios::binary); | |
796 | + | |
797 | + //make sure that there's only one line | |
798 | + if(Y() != 1){ | |
799 | + std::cout<<"ERROR in stim::bsq::sift() - number of lines does not equal 1"<<std::endl; | |
800 | + return false; | |
801 | + } | |
802 | + | |
803 | + std::cout<<"started sifting"<<std::endl; | |
804 | + | |
805 | + //get the number of pixels and bands in the input image | |
806 | + unsigned int P = X(); //Number of pixels | |
807 | + unsigned int B = Z(); //number of bands | |
808 | + unsigned int XY = samples * lines; //total number of pixels in an unsifted image | |
809 | + | |
810 | + // allocate memory for a sifted band | |
811 | + T * sifted = (T*)malloc(P * sizeof(T)); //allocate memory for a band | |
812 | + | |
813 | + //allocate memory for an unsifted band image | |
814 | + T* unsifted = (T*) malloc(XY * sizeof(T)); | |
815 | + | |
816 | + //for each band | |
817 | + for(unsigned int b = 0; b < B; b++){ | |
818 | + | |
819 | + //set the unsifted index value to zero | |
820 | + unsigned int i = 0; | |
821 | + | |
822 | + //retrieve the sifted band (masked pixels only) | |
823 | + band_index(sifted, b); | |
824 | + | |
825 | + //for each pixel in the final image (treat it as a 1D image) | |
826 | + for(unsigned int xi = 0; xi < XY; xi++){ | |
827 | + if( p[xi] == 0 ) | |
828 | + unsifted[xi] = 0; | |
829 | + else{ | |
830 | + unsifted[xi] = sifted[i]; | |
831 | + i++; | |
832 | + } | |
833 | + } | |
834 | + | |
835 | + //write the band image to disk | |
836 | + target.write(reinterpret_cast<const char*>(unsifted), sizeof(T) * XY); | |
837 | + } | |
838 | + | |
839 | + return true; | |
840 | + } | |
841 | + | |
791 | 842 | |
792 | 843 | /// Calculate the mean band value (average along B) at each pixel location. |
793 | 844 | ... | ... |
stim/envi/envi.h
... | ... | @@ -373,32 +373,48 @@ public: |
373 | 373 | } |
374 | 374 | |
375 | 375 | /// sift-mask saves in an array only those spectra corresponding to nonzero values of the mask. |
376 | - bool sift_mask(std::string outfile, unsigned char* p) | |
376 | + bool sift(std::string outfile, unsigned char* p) | |
377 | 377 | { |
378 | 378 | |
379 | + //calculate the number of non-zero values in the mask | |
380 | + unsigned int nnz = 0; | |
381 | + unsigned int npixels = header.lines * header.samples; | |
382 | + for(unsigned int i = 0; i < npixels; i++) | |
383 | + if( p[i] > 0 ) nnz++; | |
384 | + | |
385 | + //create a new header | |
386 | + envi_header new_header = header; | |
387 | + | |
388 | + //set the number of lines to 1 (this is a matrix with 1 line and N samples) | |
389 | + new_header.lines = 1; | |
390 | + new_header.samples = nnz; | |
391 | + new_header.save(outfile + ".hdr"); | |
392 | + | |
393 | + std::cout<<"Saved: "<<outfile+".hdr"<<std::endl; | |
394 | + | |
379 | 395 | if (header.interleave == envi_header::BSQ){ //if the infile is bsq file |
380 | 396 | if (header.data_type == envi_header::float32) |
381 | - return ((bsq<float>*)file)->sift_mask(outfile, p); | |
397 | + return ((bsq<float>*)file)->sift(outfile, p); | |
382 | 398 | else if (header.data_type == envi_header::float64) |
383 | - return ((bsq<double>*)file)->sift_mask(outfile, p); | |
399 | + return ((bsq<double>*)file)->sift(outfile, p); | |
384 | 400 | else |
385 | 401 | std::cout << "ERROR: unidentified data type" << std::endl; |
386 | 402 | } |
387 | 403 | |
388 | 404 | else if (header.interleave == envi_header::BIL){ //if the infile is bil file |
389 | 405 | if (header.data_type == envi_header::float32) |
390 | - return ((bil<float>*)file)->sift_mask(outfile, p); | |
406 | + return ((bil<float>*)file)->sift(outfile, p); | |
391 | 407 | else if (header.data_type == envi_header::float64) |
392 | - return ((bil<double>*)file)->sift_mask(outfile, p); | |
408 | + return ((bil<double>*)file)->sift(outfile, p); | |
393 | 409 | else |
394 | 410 | std::cout << "ERROR: unidentified data type" << std::endl; |
395 | 411 | } |
396 | 412 | |
397 | 413 | else if (header.interleave == envi_header::BIP){ //if the infile is bip file |
398 | 414 | if (header.data_type == envi_header::float32) |
399 | - return ((bip<float>*)file)->sift_mask(outfile, p); | |
415 | + return ((bip<float>*)file)->sift(outfile, p); | |
400 | 416 | else if (header.data_type == envi_header::float64) |
401 | - return ((bip<double>*)file)->sift_mask(outfile, p); | |
417 | + return ((bip<double>*)file)->sift(outfile, p); | |
402 | 418 | else |
403 | 419 | std::cout << "ERROR: unidentified data type" << std::endl; |
404 | 420 | } |
... | ... | @@ -407,9 +423,48 @@ public: |
407 | 423 | std::cout << "ERROR: unidentified file type" << std::endl; |
408 | 424 | exit(1); |
409 | 425 | } |
426 | + | |
427 | + | |
410 | 428 | return false; |
411 | 429 | } |
412 | 430 | |
431 | + bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){ | |
432 | + | |
433 | + //create a new header | |
434 | + envi_header new_header = header; | |
435 | + | |
436 | + //set the number of lines and samples in the output file (that's all that changes) | |
437 | + new_header.lines = lines; | |
438 | + new_header.samples = samples; | |
439 | + new_header.save(outfile + ".hdr"); | |
440 | + | |
441 | + | |
442 | + if (header.interleave == envi_header::BSQ){ //if the infile is bsq file | |
443 | + if (header.data_type == envi_header::float32) | |
444 | + return ((bsq<float>*)file)->unsift(outfile, mask, samples, lines); | |
445 | + else if (header.data_type == envi_header::float64) | |
446 | + return ((bsq<double>*)file)->unsift(outfile, mask, samples, lines); | |
447 | + else | |
448 | + std::cout << "ERROR: unidentified data type" << std::endl; | |
449 | + } | |
450 | + | |
451 | + else if (header.interleave == envi_header::BIL){ //if the infile is bil file | |
452 | + | |
453 | + std::cout << "ERROR in stim::envi::unsift - BIL files aren't supported yet" << std::endl; | |
454 | + } | |
455 | + | |
456 | + else if (header.interleave == envi_header::BIP){ //if the infile is bip file | |
457 | + | |
458 | + std::cout << "ERROR in stim::envi::unsift - BIP files aren't supported yet" << std::endl; | |
459 | + } | |
460 | + | |
461 | + else{ | |
462 | + std::cout << "ERROR: unidentified file type" << std::endl; | |
463 | + exit(1); | |
464 | + } | |
465 | + | |
466 | + } | |
467 | + | |
413 | 468 | /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array. |
414 | 469 | |
415 | 470 | /// @param lb1 is the label value for the left baseline point for the first peak (numerator) | ... | ... |
stim/image/image.h
... | ... | @@ -28,6 +28,11 @@ public: |
28 | 28 | img.load(filename.c_str()); |
29 | 29 | } |
30 | 30 | |
31 | + /// Constructor initializes an image to a given size | |
32 | + image(unsigned int x, unsigned int y = 1, unsigned int z = 1){ | |
33 | + img = cimg_library::CImg<T>(x, y, z); | |
34 | + } | |
35 | + | |
31 | 36 | //Load an image from a file |
32 | 37 | void load(std::string filename){ |
33 | 38 | img.load(filename.c_str()); |
... | ... | @@ -72,6 +77,17 @@ public: |
72 | 77 | data[x * C + c] = ptr[c * X + x]; |
73 | 78 | } |
74 | 79 | |
80 | + image<T> channel(unsigned int c){ | |
81 | + | |
82 | + //create a new image | |
83 | + image<T> single; | |
84 | + | |
85 | + single.img = img.channel(c); | |
86 | + | |
87 | + return single; | |
88 | + | |
89 | + } | |
90 | + | |
75 | 91 | unsigned int channels(){ |
76 | 92 | return (unsigned int)img.spectrum(); |
77 | 93 | } | ... | ... |
stim/math/mathvec.h renamed to stim/math/vector.h
stim/visualization/colormap.h
... | ... | @@ -287,7 +287,7 @@ static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T |
287 | 287 | } |
288 | 288 | |
289 | 289 | template<class T> |
290 | -static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale)//, bool positive = false) | |
290 | +static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale) | |
291 | 291 | { |
292 | 292 | //computes the max and min range automatically |
293 | 293 | |
... | ... | @@ -329,13 +329,13 @@ static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, u |
329 | 329 | } |
330 | 330 | |
331 | 331 | template<typename T> |
332 | -static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, colormapType cm = cmGrayscale, bool positive = false) | |
332 | +static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, colormapType cm = cmGrayscale) | |
333 | 333 | { |
334 | 334 | //allocate a color buffer |
335 | 335 | unsigned char* cpuBuffer = (unsigned char*) malloc(sizeof(unsigned char) * 3 * x_size * y_size); |
336 | 336 | |
337 | 337 | //do the mapping |
338 | - cpu2cpu<T>(cpuSource, cpuBuffer, x_size * y_size, cm, positive); | |
338 | + cpu2cpu<T>(cpuSource, cpuBuffer, x_size * y_size, cm); | |
339 | 339 | |
340 | 340 | //copy the buffer to an image |
341 | 341 | buffer2image(cpuBuffer, fileDest, x_size, y_size); | ... | ... |
stim/visualization/obj.h
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | #include <fstream> |
7 | 7 | #include <stdlib.h> |
8 | 8 | #include <stim/parser/parser.h> |
9 | -#include <stim/math/mathvec.h> | |
9 | +#include <stim/math/vector.h> | |
10 | 10 | |
11 | 11 | namespace stim{ |
12 | 12 | |
... | ... | @@ -600,9 +600,42 @@ public: |
600 | 600 | } |
601 | 601 | |
602 | 602 | return l; |
603 | + } | |
604 | + | |
605 | + /// Returns a vector containing the list of texture coordinates associated with each point of a line. | |
606 | + | |
607 | + /// @param i is the index of the desired line | |
608 | + std::vector< stim::vec<T> > getL_VT(unsigned int i){ | |
609 | + | |
610 | + //get the number of points in the specified line | |
611 | + unsigned int nP = L[i].size(); | |
612 | + | |
613 | + //create a vector of points | |
614 | + std::vector< stim::vec<T> > l; | |
615 | + | |
616 | + //set the size of the vector | |
617 | + l.resize(nP); | |
618 | + | |
619 | + //copy the points from the point list to the stim vector | |
620 | + unsigned int pi; | |
621 | + for(unsigned int p = 0; p < nP; p++){ | |
622 | + | |
623 | + //get the index of the geometry point | |
624 | + pi = L[i][p][1] - 1; | |
625 | + | |
626 | + //get the coordinates of the current point | |
627 | + stim::vec<T> newP = VT[pi]; | |
628 | + | |
629 | + //copy the point into the vector | |
630 | + l[p] = newP; | |
631 | + } | |
632 | + | |
633 | + return l; | |
603 | 634 | |
604 | 635 | } |
605 | 636 | |
637 | + | |
638 | + | |
606 | 639 | }; |
607 | 640 | |
608 | 641 | ... | ... |