#ifndef STIM_IMAGE_STACK_H #define STIM_IMAGE_STACK_H #include #include #include #include namespace stim{ ///This class is used to load 3D grid data from stacks of images // The class uses a 4D grid object, where the first dimension is a color value. template class image_stack : public virtual stim::grid{ enum image_type {stimAuto, stimMono, stimRGB, stimRGBA}; protected: //using stim::grid::S; using stim::grid::R; using stim::grid::ptr; using stim::grid::read; public: //default constructor image_stack() : grid() { } /// Overloads grid::samples() to return the number of samples associated with a given spatial dimension /// this is necessary because R[0] stores the color size_t samples(size_t d){ return grid::samples(d + 1); } size_t samples(){ return R[1] * R[2] * R[3]; //return the number of spatial samples } /// Returns the number of color channels size_t channels(){ return R[0]; } /// Overloads grid::size() to return the size of the grid associated with a given spatial dimension F size(size_t d){ return grid::size(d + 1); } /// Sets the spacing between samples in the image stack void spacing(F sx, F sy, F sz){ grid::S[1] = sx; //set the sample spacing for the appropriate spatial dimension grid::S[2] = sy; grid::S[3] = sz; } F spacing(size_t d){ return grid::spacing(d + 1); } /// Overloads the spacing parameter to set the size of the grid associated with a given spatial dimension //void spacing(F sx, F sy = 1.0f, F sz = 1.0f){ // grid::spacing((F)1.0, sx, sy, sz); //} ///Load an image stack based on a file mask. Images are loaded in alphanumeric order /// @param file_mask is the mask describing images to be loaded void load_images(std::string file_mask){ stim::filename file_path(file_mask); //get the list of files std::vector file_list = file_path.get_list(); //if there are no matching files, exit if(file_list.size() == 0){ std::cout<<"STIM ERROR (image_stack): No matching files for loading a stack."< I(file_list[0].str()); //set the image resolution and number of channels R[0] = I.channels(); R[1] = I.width(); R[2] = I.height(); R[3] = file_list.size(); //allocate storage space ptr = (T*)malloc(sizeof(T) * samples()); //load and copy each image into the grid for(unsigned int i = 0; i I(file_list[i].str()); //load the image I.get_interleaved_rgb(&ptr[ i * R[0] * R[1] * R[2] ]); //retrieve the interlaced data from the image - store it in the grid } } ///Inserts image I into slot i. /// @param stim::image I; image to insert. /// @int I, where to place the image. void insert_image(stim::image I, int i){ I.get_interleaved_rgb(&ptr[i *R[0] *R[1] *R[2] ]); } ///Saves a single page to an image file /// @param file_name is the name of the image file to be created /// @param i is the page to be saved void save_image(std::string file_name, unsigned int i){ stim::image I; //create an image I.set_interleaved_rgb(&ptr[ i * R[0] * R[1] * R[2] ], R[1], R[2], R[0]); //retrieve the interlaced data from the image - store it in the grid I.save(file_name); } ///Sets the dimensions of the image in each direction ///Voxel-size. /// @param x size in the x direction /// @param y size in the y direction /// @param z size in the z direction void set_dim(float x, float y, float z) { S[0] = 1; S[1] = x; S[2] = y; S[3] = z; } ///set dimensions of the grid. /// @param channels, number of channels in each image. /// @param width, number of pixels in width each image. /// @param height, number of pixels in height. /// @param depth, number of pixels in depth. void init(int channels, int width, int height, int depth) { R.resize(4); R[0] = channels; R[1] = width; R[2] = height; R[3] = depth; ptr = (T*)malloc(sizeof(T) * samples()); } ///Saves the entire stack to a set of images /// @param file_mask is the mask describing how the file names will be saved (ex. image????.bmp) void save_images(std::string file_mask){ stim::filename file_path(file_mask); //create a list of file names std::vector file_list = stim::wildcards::increment(file_path.str(), 0, R[3]-1, 1); for(int i=0; i(C, X, Y, Z), header); } T* data(){ return ptr; } }; } #endif