1 // This is brl/bseg/bvxm/grid/io/bvxm_slab_to_image.h
2 #ifndef bvxm_io_voxel_slab_h
3 #define bvxm_io_voxel_slab_h
4 //:
5 // \file
6 // \brief Converts slab to a vil_image
7 // \author Isabel Restrepo mir@lems.brown.edu
8 // \date June 26, 2009
9 // \verbatim
10 // Modifications
11 // <none yet>
12 // \endverbatim
13
14 #include <vector>
15 #include <iostream>
16 #include "../bvxm_voxel_slab.h"
17 #include <vnl/vnl_vector_fixed.h>
18 #include <vnl/vnl_float_3.h>
19 #include <vnl/vnl_float_4.h>
20 #include <vil/vil_image_view_base.h>
21 #include <vil/vil_image_view.h>
22 #include <vil/vil_pixel_format.h>
23 #include <vil/vil_save.h> // for debug saving
24 #ifdef _MSC_VER
25 # include <vcl_msvc_warnings.h>
26 #endif
27
28 class bvxm_slab_to_image
29 {
30 public:
31 //:Converts slab to a vil_image. Datatype is a vnl_vector_fixed
32 template<class T, unsigned N>
33 static bool slab_to_image(bvxm_voxel_slab<vnl_vector_fixed<T,N> > const &slab, vil_image_view_base_sptr image);
34
35 //Converts slab to a vil_image. Datatype is a scalar
36 template<class T>
37 static bool slab_to_image(bvxm_voxel_slab<T> const& slab, vil_image_view_base_sptr image);
38
39 //: Simple function to save a slab into an image. Used for debugging where the type of output image is not so important
40 template<class T>
41 static void write_slab_as_image(bvxm_voxel_slab<T> const& slab_in,std::string filename);
42
43 //: Simple function to save a slab into an image. Used for debugging where the type of output image is not so important
44 template<class T, unsigned N>
45 static void write_slab_as_image(bvxm_voxel_slab<vnl_vector_fixed<T,N> > const& slab_in,std::string filename);
46 };
47
48
49 //:Saves slab to a vil_image. Datatype is a vnl_vector_fixed
50 template<class T, unsigned N>
slab_to_image(bvxm_voxel_slab<vnl_vector_fixed<T,N>> const & slab,vil_image_view_base_sptr image)51 bool bvxm_slab_to_image::slab_to_image(bvxm_voxel_slab<vnl_vector_fixed<T,N> > const &slab, vil_image_view_base_sptr image)
52 {
53 // check image is preallocated to correct size
54 if ( (slab.nx() != image->ni()) || (slab.ny() != image->nj()) )
55 {
56 std::cerr << "error: slab and image are different sizes.\n";
57 return false;
58 }
59
60 // take care of pixel format issues. might want to specialize this function for rgb, etc
61 switch (image->pixel_format())
62 {
63 case VIL_PIXEL_FORMAT_BYTE:
64 if (image->nplanes() ==N)
65 {
66 if (vil_image_view<unsigned char> *img_view = dynamic_cast<vil_image_view<unsigned char>*>(image.ptr()))
67 {
68 std::vector<vil_image_view<unsigned char>::iterator> img_its;
69 for (unsigned p=0; p<N; ++p)
70 {
71 vil_image_view<unsigned char>::iterator plane_it = img_view->begin() + (p*img_view->planestep());
72 img_its.push_back(plane_it);
73 }
74
75 typename bvxm_voxel_slab<vnl_vector_fixed<T,N> >::const_iterator slab_it = slab.begin();
76 for (; slab_it != slab.end(); ++slab_it)
77 {
78 for (unsigned p=0; p<N; ++p)
79 {
80 *(img_its[p]) = (unsigned char)(((*slab_it)[p] * 127.0) + 0.5) + 127;
81 ++(img_its[p]);
82 }
83 }
84 }
85 else
86 {
87 std::cerr << "error in slab_to_image: failed to cast image_view_base to image_view\n";
88 return false;
89 }
90 }
91 else
92 {
93 std::cerr << "error in slab_to_image: incorrect number of image planes\n";
94 return false;
95 }
96 break;
97
98 case VIL_PIXEL_FORMAT_RGBA_BYTE:
99 if (image->nplanes() ==1)
100 {
101 if (vil_image_view<vil_rgba<unsigned char> > *img_view = dynamic_cast<vil_image_view<vil_rgba<unsigned char> >*>(image.ptr()))
102 {
103 vil_image_view<vil_rgba<unsigned char> >::iterator img_it = img_view->begin();
104 #if 0
105 for (unsigned p=0; p<N; ++p)
106 {
107 vil_image_view<vil_rgba<unsigned char> >::iterator plane_it = img_view->begin();
108 img_its.push_back(plane_it);
109 }
110 #endif
111 typename bvxm_voxel_slab<vnl_vector_fixed<T,N> >::const_iterator slab_it = slab.begin();
112 if (N != 4)
113 {
114 std::cerr << "error in slab_to_image: failed to cast image_view_base to image_view: N should be 4\n";
115 return false;
116 }
117 for (; slab_it != slab.end(); ++slab_it)
118 {
119 (*img_it) = vil_rgba<unsigned char>((unsigned char)(*slab_it)[0],
120 (unsigned char)(*slab_it)[1],
121 (unsigned char)(*slab_it)[2],
122 (unsigned char)std::floor((*slab_it)[3]));
123 #if 0
124 *(img_its[p]) = (unsigned char)(((*slab_it)[p] * 127.0) + 0.5) + 127;
125 std::cout<<(int)(*img_it).R()<<' '<<(int)((unsigned char)(*slab_it)[3])<<std::endl;
126 #endif
127 ++(img_it);
128 }
129 }
130 else
131 {
132 std::cerr << "error in slab_to_image: failed to cast image_view_base to image_view\n";
133 return false;
134 }
135 }
136 else
137 {
138 std::cerr << "error in slab_to_image: incorrect number of image planes\n";
139 return false;
140 }
141 break;
142
143 case VIL_PIXEL_FORMAT_FLOAT:
144 if (image->nplanes() ==N)
145 {
146 if (vil_image_view<float> *img_view = dynamic_cast<vil_image_view<float>*>(image.ptr()))
147 {
148 std::vector<vil_image_view<float>::iterator> img_its;
149 for (unsigned p=0; p<N; ++p)
150 {
151 vil_image_view<float>::iterator plane_it = img_view->begin() + (p*img_view->planestep());
152 img_its.push_back(plane_it);
153 }
154
155 typename bvxm_voxel_slab<vnl_vector_fixed<T,N> >::const_iterator slab_it = slab.begin();
156 for (; slab_it != slab.end(); ++slab_it)
157 {
158 for (unsigned p=0; p<N; ++p)
159 {
160 *(img_its[p]) = (float)((*slab_it)[p]);
161 ++(img_its[p]);
162 }
163 }
164 }
165 else
166 {
167 std::cerr << "error in slab_to_image: failed to cast image_view_base to image_view\n";
168 return false;
169 }
170 }
171 else
172 {
173 std::cerr << "error in slab_to_image: incorrect number of image planes\n";
174 return false;
175 }
176 break;
177
178 case VIL_PIXEL_FORMAT_RGB_BYTE:
179 if (image->nplanes() ==1)
180 {
181 if (vil_image_view<vil_rgb<unsigned char> > *img_view = dynamic_cast<vil_image_view<vil_rgb<unsigned char> >*>(image.ptr()))
182 {
183 vil_image_view<vil_rgb<unsigned char> >::iterator img_it = img_view->begin();
184
185 typename bvxm_voxel_slab<vnl_vector_fixed<T,N> >::const_iterator slab_it = slab.begin();
186 if (N != 3)
187 {
188 std::cerr << "error in slab_to_image: failed to cast image_view_base to image_view: N should be 3\n";
189 return false;
190 }
191 for (; slab_it != slab.end(); ++slab_it)
192 {
193 (*img_it) = vil_rgb<unsigned char>((unsigned char)((*slab_it)[0]*127+127),
194 (unsigned char)((*slab_it)[1]*127+127),
195 (unsigned char)((*slab_it)[2]*127+127));
196 ++(img_it);
197 }
198 }
199 else
200 {
201 std::cerr << "error in slab_to_image: failed to cast image_view_base to image_view\n";
202 return false;
203 }
204 }
205 else
206 {
207 std::cerr << "error in slab_to_image: incorrect number of image planes\n";
208 return false;
209 }
210 break;
211
212
213 default:
214 std::cerr << "img_to_slab: unsupported pixel type\n";
215 return false;
216 break;
217 }
218
219 return true;
220 }
221
222 template<>
223 bool bvxm_slab_to_image::slab_to_image(bvxm_voxel_slab<vnl_float_3> const& slab, vil_image_view_base_sptr image);
224
225 template<>
226 bool bvxm_slab_to_image::slab_to_image(bvxm_voxel_slab<vnl_float_4> const& slab, vil_image_view_base_sptr image);
227
228 template<class T>
slab_to_image(bvxm_voxel_slab<T> const & slab,vil_image_view_base_sptr image)229 bool bvxm_slab_to_image::slab_to_image(bvxm_voxel_slab<T> const& slab, vil_image_view_base_sptr image)
230 {
231 // check image is preallocated to correct size
232 if ( (slab.nx() != image->ni()) || (slab.ny() != image->nj()) )
233 {
234 std::cerr << "error: slab and image are different sizes.\n";
235 return false;
236 }
237
238 // take care of pixel format issues. might want to specialize this function for rgb, etc
239 switch (image->pixel_format())
240 {
241 case VIL_PIXEL_FORMAT_BYTE:
242 if (vil_image_view<unsigned char> *img_view = dynamic_cast<vil_image_view<unsigned char>*>(image.ptr()))
243 {
244 vil_image_view<unsigned char>::iterator img_it = img_view->begin();
245 typename bvxm_voxel_slab<T>::const_iterator slab_it = slab.begin();
246 for (; img_it != img_view->end(); ++img_it, ++slab_it) {
247 *img_it = (unsigned char)std::floor(((*slab_it)*255));
248 }
249 }
250 else
251 {
252 std::cerr << "error: failed to cast image_view_base to image_view\n";
253 return false;
254 }
255 break;
256
257 case VIL_PIXEL_FORMAT_FLOAT:
258 if (vil_image_view<float> *img_view = dynamic_cast<vil_image_view<float>*>(image.ptr()))
259 {
260 vil_image_view<float>::iterator img_it = img_view->begin();
261 typename bvxm_voxel_slab<T>::const_iterator slab_it = slab.begin();
262 for (; img_it != img_view->end(); ++img_it, ++slab_it) {
263 *img_it = (float)(*slab_it*255);
264 }
265 }
266 else
267 {
268 std::cerr << "error: failed to cast image_view_base to image_view\n";
269 return false;
270 }
271 break;
272
273 default:
274 std::cerr << "img_to_slab: unsupported pixel type\n";
275 return false;
276 break;
277 }
278
279 return true;
280 }
281
282 // used for debugging
283 template<class T, unsigned N>
write_slab_as_image(bvxm_voxel_slab<vnl_vector_fixed<T,N>> const & slab_in,std::string filename)284 void bvxm_slab_to_image::write_slab_as_image(bvxm_voxel_slab<vnl_vector_fixed<T,N> > const& slab_in,std::string filename)
285 {
286 vil_image_view<T> img(slab_in.nx(),slab_in.ny(),N);
287 std::vector<typename vil_image_view<T>::iterator> img_its;
288 for (unsigned p=0; p < N; ++p) {
289 typename vil_image_view<T>::iterator plane_it = img.begin() + (p*img.planestep());
290 img_its.push_back(plane_it);
291 }
292 typename bvxm_voxel_slab<vnl_vector_fixed<T,N> >::const_iterator slab_it = slab_in.begin();
293 for (; slab_it != slab_in.end(); ++slab_it) {
294 for (unsigned p=0; p<N; ++p) {
295 *(img_its[p]) = (*slab_it)[p];
296 ++(img_its[p]);
297 }
298 }
299 vil_save(img,filename.c_str());
300
301 return;
302 }
303
304 // used for debugging
305 template<class T>
write_slab_as_image(bvxm_voxel_slab<T> const & slab_in,std::string filename)306 void bvxm_slab_to_image::write_slab_as_image(bvxm_voxel_slab<T> const& slab_in,std::string filename)
307 {
308 vil_image_view<T> img(slab_in.nx(),slab_in.ny(),1);
309 typename vil_image_view<T>::iterator img_it = img.begin();
310 typename bvxm_voxel_slab<T>::const_iterator slab_it = slab_in.begin();
311 for (; img_it != img.end(); ++img_it, ++slab_it) {
312 *img_it = *slab_it;
313 }
314 vil_save(img,filename.c_str());
315
316 return;
317 }
318
319
320 #endif
321