image_stack.h
3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#ifndef STIM_IMAGE_STACK_H
#define STIM_IMAGE_STACK_H
#include "../parser/wildcards.h"
#include "../parser/filename.h"
#include "../grids/grid.h"
#include "../image/image.h"
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<typename T>
class image_stack : public virtual stim::grid<T, 4>{
enum image_type {stimAuto, stimMono, stimRGB, stimRGBA};
protected:
using stim::grid<T, 4>::S;
using stim::grid<T, 4>::R;
using stim::grid<T, 4>::ptr;
using stim::grid<T, 4>::samples;
using stim::grid<T, 4>::read;
public:
///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);
//if the file path is relative, update it with the current working directory
if(file_path.is_relative()){
stim::filename wd = stim::filename::cwd();
file_path = wd.get_relative(file_mask);
}
//get the list of files
std::vector<stim::filename> 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."<<std::endl;
exit(1);
}
//load the first image and set all of the image_stack properties
std::cout<<"File to Load: "<<file_list[0].str()<<std::endl;
stim::image<T> I(file_list[0].str());
//set the image resolution and number of channels
R.push(I.channels());
R.push(I.width());
R.push(I.height());
R.push(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<R[3]; i++){
std::cout<<"File to Load: "<<file_list[i].str()<<std::endl;
//load the image
stim::image<T> I(file_list[i].str());
//retrieve the interlaced data from the image - store it in the grid
I.data_interleaved(&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){
//create an image
stim::image<T> I;
//retrieve the interlaced data from the image - store it in the grid
I.set_interleaved(&ptr[ i * R[0] * R[1] * R[2] ], R[1], R[2], R[0]);
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;
}
///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);
//if the file path is relative, update it with the current working directory
if(file_path.is_relative()){
stim::filename wd = stim::filename::cwd();
file_path = wd.get_relative(file_mask);
}
//create a list of file names
std::vector<std::string> file_list = stim::wildcards::increment(file_path.str(), 0, R[3]-1, 1);
for(int i=0; i<R[3]; i++)
save_image(file_list[i], i);
}
/// Returns the pixel at the specified point
T get(unsigned int x, unsigned int y, unsigned int z, unsigned int c = 0){
return ptr[z * R[0] * R[1] * R[2] + y * R[0] * R[1] + x * R[0] + c];
}
void read(std::string file, unsigned int X, unsigned int Y, unsigned int Z, unsigned int C = 1, unsigned int header = 0){
read(file, stim::vec<unsigned long>(C, X, Y, Z), header);
}
T* data(){
return ptr;
}
};
}
#endif