Commit ae05c3e48657bbd5c1bc3ac2154a6760be2a2ce1

Authored by Pavel Govyadinov
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
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){
... ...