Commit ae05c3e48657bbd5c1bc3ac2154a6760be2a2ce1
1 parent
84bae1ab
Found an error with the image.h class. Not sure how to fix, but it is pretty ser…
…ious. Since using openCV uses it's own mechanics internally, memcpy does not create a copy correctly and hence when loading multiple images with 1 in memory at a time, the previously loaded image data is never released leading to OOM errors
Showing
3 changed files
with
96 additions
and
19 deletions
Show diff stats
stim/gl/gl_spider.h
... | ... | @@ -140,7 +140,7 @@ class gl_spider : public virtual gl_texture<T> |
140 | 140 | setMatrix(); //create the transformation matrix. |
141 | 141 | glCallList(dList+1); //move the templates to p, d, m. |
142 | 142 | int best = getCost(ptexbufferID, numSamplesPos); //find min cost. |
143 | - std::cerr << best << std::endl; | |
143 | +// std::cerr << best << std::endl; | |
144 | 144 | stim::vec<float> next( //find next position. |
145 | 145 | pV[best][0], |
146 | 146 | pV[best][1], | ... | ... |
stim/grids/image_stack.h
1 | 1 | #ifndef STIM_IMAGE_STACK_H |
2 | 2 | #define STIM_IMAGE_STACK_H |
3 | 3 | |
4 | -#include "../parser/wildcards.h" | |
5 | -#include "../parser/filename.h" | |
6 | -#include "../grids/grid.h" | |
7 | -#include "../image/image.h" | |
4 | +#include <stim/parser/wildcards.h> | |
5 | +#include <stim/parser/filename.h> | |
6 | +#include <stim/grids/grid.h> | |
7 | +#include <stim/image/image.h> | |
8 | 8 | |
9 | 9 | namespace stim{ |
10 | 10 | |
... | ... | @@ -48,7 +48,7 @@ public: |
48 | 48 | } |
49 | 49 | |
50 | 50 | //load the first image and set all of the image_stack properties |
51 | - std::cout<<"File to Load: "<<file_list[0].str()<<std::endl; | |
51 | +// std::cout<<"File to Load: "<<file_list[0].str()<<std::endl; | |
52 | 52 | stim::image<T> I(file_list[0].str()); |
53 | 53 | |
54 | 54 | //set the image resolution and number of channels |
... | ... | @@ -63,7 +63,7 @@ public: |
63 | 63 | //load and copy each image into the grid |
64 | 64 | for(unsigned int i = 0; i<R[3]; i++){ |
65 | 65 | |
66 | - std::cout<<"File to Load: "<<file_list[i].str()<<std::endl; | |
66 | +// std::cout<<"File to Load: "<<file_list[i].str()<<std::endl; | |
67 | 67 | //load the image |
68 | 68 | stim::image<T> I(file_list[i].str()); |
69 | 69 | |
... | ... | @@ -73,8 +73,15 @@ public: |
73 | 73 | } |
74 | 74 | } |
75 | 75 | |
76 | - ///Saves a single page to an image file | |
76 | + ///Inserts image I into slot i. | |
77 | + /// @param stim::image<T> I; image to insert. | |
78 | + /// @int I, where to place the image. | |
79 | + void insert_image(stim::image<T> I, int i) | |
80 | + { | |
81 | + I.get_interleaved_rgb(&ptr[i *R[0] *R[1] *R[2] ]); | |
82 | + } | |
77 | 83 | |
84 | + ///Saves a single page to an image file | |
78 | 85 | /// @param file_name is the name of the image file to be created |
79 | 86 | /// @param i is the page to be saved |
80 | 87 | void save_image(std::string file_name, unsigned int i){ |
... | ... | @@ -83,10 +90,11 @@ public: |
83 | 90 | stim::image<T> I; |
84 | 91 | |
85 | 92 | //retrieve the interlaced data from the image - store it in the grid |
86 | - I.set_interleaved(&ptr[ i * R[0] * R[1] * R[2] ], R[1], R[2], R[0]); | |
93 | + I.set_interleaved_rgb(&ptr[ i * R[0] * R[1] * R[2] ], R[1], R[2], R[0]); | |
87 | 94 | |
88 | 95 | I.save(file_name); |
89 | 96 | } |
97 | + | |
90 | 98 | ///Sets the dimensions of the image in each direction |
91 | 99 | ///Voxel-size. |
92 | 100 | /// @param x size in the x direction |
... | ... | @@ -100,8 +108,24 @@ public: |
100 | 108 | S[2] = y; |
101 | 109 | S[3] = z; |
102 | 110 | } |
103 | - ///Saves the entire stack to a set of images | |
104 | 111 | |
112 | + ///set dimensions of the grid. | |
113 | + /// @param channels, number of channels in each image. | |
114 | + /// @param width, number of pixels in width each image. | |
115 | + /// @param height, number of pixels in height. | |
116 | + /// @param depth, number of pixels in depth. | |
117 | + void init(int channels, int width, int height, int depth) | |
118 | + { | |
119 | + R.resize(4); | |
120 | + R[0] = channels; | |
121 | + R[1] = width; | |
122 | + R[2] = height; | |
123 | + R[3] = depth; | |
124 | + | |
125 | + ptr = (T*)malloc(sizeof(T) * samples()); | |
126 | + } | |
127 | + | |
128 | + ///Saves the entire stack to a set of images | |
105 | 129 | /// @param file_mask is the mask describing how the file names will be saved (ex. image????.bmp) |
106 | 130 | void save_images(std::string file_mask){ |
107 | 131 | ... | ... |
stim/image/image.h
... | ... | @@ -112,8 +112,13 @@ public: |
112 | 112 | } |
113 | 113 | |
114 | 114 | /// Destructor - clear memory |
115 | - ~image(){ | |
116 | - free(img); | |
115 | +// ~image(){ | |
116 | +// free(img); | |
117 | +// } | |
118 | + | |
119 | + void clear_exp(){ //clears all image data | |
120 | + unalloc(); | |
121 | + | |
117 | 122 | } |
118 | 123 | |
119 | 124 | stim::image<T> operator=(const stim::image<T>& I){ |
... | ... | @@ -133,11 +138,28 @@ public: |
133 | 138 | exit(1); |
134 | 139 | } |
135 | 140 | allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image |
136 | - T* cv_ptr = (T*)cvImage.data; | |
137 | - if(C() == 1) //if this is a single-color image, just copy the data | |
138 | - memcpy(img, cv_ptr, bytes()); | |
141 | + T* cv_ptr = (T*) cvImage.data; | |
142 | + if(C() == 1) | |
143 | + { | |
144 | + //if this is a single-color image, just copy the data | |
145 | +/* | |
146 | + THIS DOES NOT WORK PROPERLY. | |
147 | + YOU CANNOT DO MEMCPY LIKE THIS BECAUSE IT CORRUPTS THE POINTREF MECHANIC IN OPENCV AND NEVER ACTUALLY CREATES A DEEP COPY BUT TAKES UP THE MEMORY. | |
148 | + TO TEST run and compile pseudocode | |
149 | + stim::image<unsigned char> I; | |
150 | + for(int i = 0; i < file_list.size(); i++) | |
151 | + I.load(file_list[i].srt()) | |
152 | + | |
153 | + | |
154 | + You will run out of memory. | |
155 | +*/ | |
156 | + memcpy(img, cv_ptr, bytes()); | |
157 | +// img = cvImage.data; | |
158 | + } | |
139 | 159 | if(C() == 3) //if this is a 3-color image, OpenCV uses BGR interleaving |
140 | 160 | set_interleaved_bgr(cv_ptr, X(), Y()); |
161 | + | |
162 | +// cvImage.deallocate(); | |
141 | 163 | } |
142 | 164 | |
143 | 165 | //save a file |
... | ... | @@ -151,16 +173,18 @@ public: |
151 | 173 | get_interleaved_bgr(buffer); |
152 | 174 | cv::Mat cvImage((int)Y(), (int)X(), cv_type(), buffer); |
153 | 175 | cv::imwrite(filename, cvImage); |
176 | + cvImage.release(); | |
177 | + free(buffer); | |
154 | 178 | } |
155 | 179 | |
156 | 180 | //create an image from an interleaved buffer |
157 | - void set_interleaved_rgb(T* buffer, size_t width, size_t height){ | |
158 | - allocate(width, height, 3); | |
181 | + void set_interleaved_rgb(T* buffer, size_t width, size_t height, size_t channels = 3){ | |
182 | + allocate(width, height, channels); | |
159 | 183 | memcpy(img, buffer, bytes()); |
160 | 184 | } |
161 | 185 | |
162 | - void set_interleaved_bgr(T* buffer, size_t width, size_t height){ | |
163 | - allocate(width, height, 3); | |
186 | + void set_interleaved_bgr(T* buffer, size_t width, size_t height, size_t channels = 3){ | |
187 | + allocate(width, height, channels); | |
164 | 188 | for(size_t c = 0; c < C(); c++){ //copy directly |
165 | 189 | for(size_t y = 0; y < Y(); y++){ |
166 | 190 | for(size_t x = 0; x < X(); x++){ |
... | ... | @@ -329,6 +353,34 @@ public: |
329 | 353 | return r; //return the inverted image |
330 | 354 | } |
331 | 355 | |
356 | + ///crops the image from x1 to x0 and y1 to y0 and returns a new (smaller) image. | |
357 | + ///Untested | |
358 | + image<T> crop(int x0, int x1, int y0, int y1) | |
359 | + { | |
360 | + | |
361 | + image<T> ret(x1-x0, y1-y0, C()); | |
362 | + int newWidth = x1-x0; | |
363 | + int destidx, srcidx; | |
364 | +// for(int i = 0; i < (y1-y0); i++) | |
365 | + { | |
366 | + destidx = i*newWidth*C(); ///destination index one per each row | |
367 | + srcidx = ((i+(y0))*X()+x0)*C(); ///source index, one per each row. | |
368 | + ret.set_interleaved_rgb(img[srcidx], newWidth, y1-y0, C()); | |
369 | + memcpy(&ret.img[destidx], &buffer[srcidx], sizeof(T)*newWidth*C()); | |
370 | + } | |
371 | + | |
372 | +// for(int i = 0; i < (x1 -x0); i++) | |
373 | +// { | |
374 | +// for(int j = 0; j < (y1 - y0); j++) | |
375 | +// { | |
376 | +// destidx = j*newWidth*C() + i; | |
377 | +// srcidx = ((i+(y0))*X() +x0)*C() + i; | |
378 | +// ret.img[destidx] = img[srcidx]; | |
379 | +// } | |
380 | +// } | |
381 | + return ret; | |
382 | + } | |
383 | + | |
332 | 384 | image<T> srgb2lab(){ |
333 | 385 | std::cout<<"ERROR stim::image::srgb2lab - function has been broken, re-implement."<<std::endl; |
334 | 386 | exit(1); |
... | ... | @@ -346,6 +398,7 @@ public: |
346 | 398 | exit(1); |
347 | 399 | } |
348 | 400 | |
401 | + | |
349 | 402 | // leila's code for non_interleaving data in 3D |
350 | 403 | //create an data set from an interleaved buffer |
351 | 404 | void set_interleaved3(T* buffer, size_t width, size_t height, size_t depth, size_t channels = 3){ | ... | ... |