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,7 +140,7 @@ class gl_spider : public virtual gl_texture<T>
140 setMatrix(); //create the transformation matrix. 140 setMatrix(); //create the transformation matrix.
141 glCallList(dList+1); //move the templates to p, d, m. 141 glCallList(dList+1); //move the templates to p, d, m.
142 int best = getCost(ptexbufferID, numSamplesPos); //find min cost. 142 int best = getCost(ptexbufferID, numSamplesPos); //find min cost.
143 - std::cerr << best << std::endl; 143 +// std::cerr << best << std::endl;
144 stim::vec<float> next( //find next position. 144 stim::vec<float> next( //find next position.
145 pV[best][0], 145 pV[best][0],
146 pV[best][1], 146 pV[best][1],
stim/grids/image_stack.h
1 #ifndef STIM_IMAGE_STACK_H 1 #ifndef STIM_IMAGE_STACK_H
2 #define STIM_IMAGE_STACK_H 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 namespace stim{ 9 namespace stim{
10 10
@@ -48,7 +48,7 @@ public: @@ -48,7 +48,7 @@ public:
48 } 48 }
49 49
50 //load the first image and set all of the image_stack properties 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 stim::image<T> I(file_list[0].str()); 52 stim::image<T> I(file_list[0].str());
53 53
54 //set the image resolution and number of channels 54 //set the image resolution and number of channels
@@ -63,7 +63,7 @@ public: @@ -63,7 +63,7 @@ public:
63 //load and copy each image into the grid 63 //load and copy each image into the grid
64 for(unsigned int i = 0; i<R[3]; i++){ 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 //load the image 67 //load the image
68 stim::image<T> I(file_list[i].str()); 68 stim::image<T> I(file_list[i].str());
69 69
@@ -73,8 +73,15 @@ public: @@ -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 /// @param file_name is the name of the image file to be created 85 /// @param file_name is the name of the image file to be created
79 /// @param i is the page to be saved 86 /// @param i is the page to be saved
80 void save_image(std::string file_name, unsigned int i){ 87 void save_image(std::string file_name, unsigned int i){
@@ -83,10 +90,11 @@ public: @@ -83,10 +90,11 @@ public:
83 stim::image<T> I; 90 stim::image<T> I;
84 91
85 //retrieve the interlaced data from the image - store it in the grid 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 I.save(file_name); 95 I.save(file_name);
89 } 96 }
  97 +
90 ///Sets the dimensions of the image in each direction 98 ///Sets the dimensions of the image in each direction
91 ///Voxel-size. 99 ///Voxel-size.
92 /// @param x size in the x direction 100 /// @param x size in the x direction
@@ -100,8 +108,24 @@ public: @@ -100,8 +108,24 @@ public:
100 S[2] = y; 108 S[2] = y;
101 S[3] = z; 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 /// @param file_mask is the mask describing how the file names will be saved (ex. image????.bmp) 129 /// @param file_mask is the mask describing how the file names will be saved (ex. image????.bmp)
106 void save_images(std::string file_mask){ 130 void save_images(std::string file_mask){
107 131
stim/image/image.h
@@ -112,8 +112,13 @@ public: @@ -112,8 +112,13 @@ public:
112 } 112 }
113 113
114 /// Destructor - clear memory 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 stim::image<T> operator=(const stim::image<T>& I){ 124 stim::image<T> operator=(const stim::image<T>& I){
@@ -133,11 +138,28 @@ public: @@ -133,11 +138,28 @@ public:
133 exit(1); 138 exit(1);
134 } 139 }
135 allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image 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 if(C() == 3) //if this is a 3-color image, OpenCV uses BGR interleaving 159 if(C() == 3) //if this is a 3-color image, OpenCV uses BGR interleaving
140 set_interleaved_bgr(cv_ptr, X(), Y()); 160 set_interleaved_bgr(cv_ptr, X(), Y());
  161 +
  162 +// cvImage.deallocate();
141 } 163 }
142 164
143 //save a file 165 //save a file
@@ -151,16 +173,18 @@ public: @@ -151,16 +173,18 @@ public:
151 get_interleaved_bgr(buffer); 173 get_interleaved_bgr(buffer);
152 cv::Mat cvImage((int)Y(), (int)X(), cv_type(), buffer); 174 cv::Mat cvImage((int)Y(), (int)X(), cv_type(), buffer);
153 cv::imwrite(filename, cvImage); 175 cv::imwrite(filename, cvImage);
  176 + cvImage.release();
  177 + free(buffer);
154 } 178 }
155 179
156 //create an image from an interleaved buffer 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 memcpy(img, buffer, bytes()); 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 for(size_t c = 0; c < C(); c++){ //copy directly 188 for(size_t c = 0; c < C(); c++){ //copy directly
165 for(size_t y = 0; y < Y(); y++){ 189 for(size_t y = 0; y < Y(); y++){
166 for(size_t x = 0; x < X(); x++){ 190 for(size_t x = 0; x < X(); x++){
@@ -329,6 +353,34 @@ public: @@ -329,6 +353,34 @@ public:
329 return r; //return the inverted image 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 image<T> srgb2lab(){ 384 image<T> srgb2lab(){
333 std::cout<<"ERROR stim::image::srgb2lab - function has been broken, re-implement."<<std::endl; 385 std::cout<<"ERROR stim::image::srgb2lab - function has been broken, re-implement."<<std::endl;
334 exit(1); 386 exit(1);
@@ -346,6 +398,7 @@ public: @@ -346,6 +398,7 @@ public:
346 exit(1); 398 exit(1);
347 } 399 }
348 400
  401 +
349 // leila's code for non_interleaving data in 3D 402 // leila's code for non_interleaving data in 3D
350 //create an data set from an interleaved buffer 403 //create an data set from an interleaved buffer
351 void set_interleaved3(T* buffer, size_t width, size_t height, size_t depth, size_t channels = 3){ 404 void set_interleaved3(T* buffer, size_t width, size_t height, size_t depth, size_t channels = 3){