[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 2003 by Gunnar Kedenburg */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 00037 #ifndef VIGRA_MULTI_IMPEX_HXX 00038 #define VIGRA_MULTI_IMPEX_HXX 00039 00040 #include <memory> 00041 #include <iomanip> 00042 #include <sstream> 00043 #include <iostream> 00044 #include <string> 00045 #include <fstream> 00046 00047 #include "config.hxx" 00048 #include "basicimageview.hxx" 00049 #include "impex.hxx" 00050 #include "multi_array.hxx" 00051 #include "multi_pointoperators.hxx" 00052 00053 #ifdef _MSC_VER 00054 # include <direct.h> 00055 #else 00056 # include <unistd.h> 00057 #endif 00058 00059 namespace vigra { 00060 00061 /** \addtogroup VolumeImpex Import/export of volume data. 00062 */ 00063 00064 //@{ 00065 00066 /** \brief Argument object for the function importVolume(). 00067 00068 See \ref importVolume() for usage example. This object can be used 00069 to define the properties of a volume data set to be read from disk. 00070 Sorry, no \ref detailedDocumentation() available yet. 00071 00072 <b>\#include</b> <<a href="imageinfo_8hxx-source.html">vigra/multi_impex.hxx</a>><br> 00073 Namespace: vigra 00074 **/ 00075 class VolumeImportInfo 00076 { 00077 public: 00078 typedef ImageImportInfo::PixelType PixelType; 00079 00080 /// type of volume size returned by shape() 00081 typedef MultiArrayShape<3>::type ShapeType; 00082 00083 /// provided for backwards-compatibility (deprecated) 00084 typedef ShapeType size_type; 00085 00086 /// 3D resolution type returned by resolution() 00087 typedef TinyVector<float, 3> Resolution; 00088 00089 VIGRA_EXPORT VolumeImportInfo(const std::string &filename); 00090 VIGRA_EXPORT VolumeImportInfo(const std::string &baseName, const std::string &extension); 00091 00092 VIGRA_EXPORT ShapeType shape() const; 00093 00094 /** Get width of the volume. 00095 **/ 00096 VIGRA_EXPORT MultiArrayIndex width() const; 00097 00098 /** Get height of the volume. 00099 **/ 00100 VIGRA_EXPORT MultiArrayIndex height() const; 00101 00102 /** Get depth of the volume. 00103 **/ 00104 VIGRA_EXPORT MultiArrayIndex depth() const; 00105 00106 /** 00107 * resolution() contains the alignment and resolution of the 00108 * volume. resolution()[0] is the x increment in a left-handed 00109 * world coordinate system of one unstrided step in the volume 00110 * memory. The [1] and [2] elements contain the y resp. z 00111 * increments of the strided row resp. slice steps in the 00112 * volume. 00113 * 00114 * EXAMPLES: (1.f, 1.f, 4.f) means that the slices are four 00115 * times thicker than the x/y resolution. 00116 * (1.f, -1.f, 1.f) means that the volume coordinate system is 00117 * right-handed. 00118 */ 00119 VIGRA_EXPORT Resolution resolution() const; 00120 00121 /** Query the pixel type of the image. 00122 00123 Possible values are: 00124 <DL> 00125 <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char) 00126 <DT>"INT16"<DD> 16-bit signed integer (short) 00127 <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short) 00128 <DT>"INT32"<DD> 32-bit signed integer (long) 00129 <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long) 00130 <DT>"FLOAT"<DD> 32-bit floating point (float) 00131 <DT>"DOUBLE"<DD> 64-bit floating point (double) 00132 </DL> 00133 **/ 00134 VIGRA_EXPORT const char * getPixelType() const; 00135 00136 /** Query the pixel type of the image. 00137 00138 Same as getPixelType(), but the result is returned as a 00139 ImageImportInfo::PixelType enum. This is useful to implement 00140 a switch() on the pixel type. 00141 00142 Possible values are: 00143 <DL> 00144 <DT>UINT8<DD> 8-bit unsigned integer (unsigned char) 00145 <DT>INT16<DD> 16-bit signed integer (short) 00146 <DT>UINT16<DD> 16-bit unsigned integer (unsigned short) 00147 <DT>INT32<DD> 32-bit signed integer (long) 00148 <DT>UINT32<DD> 32-bit unsigned integer (unsigned long) 00149 <DT>FLOAT<DD> 32-bit floating point (float) 00150 <DT>DOUBLE<DD> 64-bit floating point (double) 00151 </DL> 00152 **/ 00153 VIGRA_EXPORT PixelType pixelType() const; 00154 00155 VIGRA_EXPORT MultiArrayIndex numBands() const; 00156 VIGRA_EXPORT bool isGrayscale() const; 00157 VIGRA_EXPORT bool isColor() const; 00158 00159 // get base file name without path, image index, and extension 00160 VIGRA_EXPORT const std::string &name() const; 00161 00162 VIGRA_EXPORT const std::string &description() const; 00163 00164 template <class T, class Stride> 00165 void importImpl(MultiArrayView <3, T, Stride> &volume) const; 00166 00167 protected: 00168 void getVolumeInfoFromFirstSlice(const std::string &filename); 00169 00170 size_type shape_; 00171 Resolution resolution_; 00172 //PixelType pixelType_; 00173 int numBands_; 00174 00175 std::string path_, name_, description_, pixelType_; 00176 00177 std::string rawFilename_; 00178 std::string baseName_, extension_; 00179 std::vector<std::string> numbers_; 00180 }; 00181 00182 /********************************************************/ 00183 /* */ 00184 /* VolumeExportInfo */ 00185 /* */ 00186 /********************************************************/ 00187 00188 /** \brief Argument object for the function exportVolume(). 00189 00190 See \ref exportVolume() for usage example. This object must be used 00191 to define the properties of a volume to be written to disk. 00192 00193 <b>\#include</b> <<a href="imageinfo_8hxx-source.html">vigra/imageinfo.hxx</a>><br> 00194 Namespace: vigra 00195 **/ 00196 class VolumeExportInfo 00197 { 00198 public: 00199 /** Construct VolumeExportInfo object. 00200 00201 The volume will be stored in a by-slice manner, where the number of slices 00202 equals the depth of the volume. The file names will be enumerated like 00203 <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc. 00204 (the actual number of zeros depends on the depth). If the target image type 00205 does not support the source voxel type, all slices will be mapped 00206 simultaneously to the appropriate target range. 00207 The file type will be guessed from the extension unless overridden 00208 by \ref setFileType(). Recognized extensions: '.bmp', '.gif', 00209 '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras', 00210 '.tif', '.tiff', '.xv', '.hdr'. 00211 JPEG support requires libjpeg, PNG support requires libpng, and 00212 TIFF support requires libtiff. 00213 **/ 00214 VIGRA_EXPORT VolumeExportInfo( const char * name_base, const char * name_ext ); 00215 VIGRA_EXPORT ~VolumeExportInfo(); 00216 00217 /** Set volume file name base. 00218 00219 **/ 00220 VIGRA_EXPORT VolumeExportInfo & setFileNameBase(const char * name_base); 00221 /** Set volume file name extension. 00222 00223 The file type will be guessed from the extension unless overridden 00224 by \ref setFileType(). Recognized extensions: '.bmp', '.gif', 00225 '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras', 00226 '.tif', '.tiff', '.xv', '.hdr'. 00227 JPEG support requires libjpeg, PNG support requires libpng, and 00228 TIFF support requires libtiff. 00229 **/ 00230 VIGRA_EXPORT VolumeExportInfo & setFileNameExt(const char * name_ext); 00231 VIGRA_EXPORT const char * getFileNameBase() const; 00232 VIGRA_EXPORT const char * getFileNameExt() const; 00233 00234 /** Store volume as given file type. 00235 00236 This will override any type guessed 00237 from the file name's extension. Recognized file types: 00238 00239 <DL> 00240 <DT>"BMP"<DD> Microsoft Windows bitmap image file. 00241 <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit color. 00242 <DT>"JPEG"<DD> Joint Photographic Experts Group JFIF format; 00243 compressed 24-bit color (only available if libjpeg is installed). 00244 <DT>"PNG"<DD> Portable Network Graphic 00245 (only available if libpng is installed). 00246 <DT>"PBM"<DD> Portable bitmap format (black and white). 00247 <DT>"PGM"<DD> Portable graymap format (gray scale). 00248 <DT>"PNM"<DD> Portable anymap. 00249 <DT>"PPM"<DD> Portable pixmap format (color). 00250 <DT>"SUN"<DD> SUN Rasterfile. 00251 <DT>"TIFF"<DD> Tagged Image File Format. 00252 (only available if libtiff is installed.) 00253 <DT>"VIFF"<DD> Khoros Visualization image file. 00254 </DL> 00255 00256 With the exception of TIFF, VIFF, PNG, and PNM all file types store 00257 1 byte (gray scale and mapped RGB) or 3 bytes (RGB) per 00258 pixel. 00259 00260 PNG can store UInt8 and UInt16 values, and supports 1 and 3 channel 00261 images. One additional alpha channel is also supported. 00262 00263 PNM can store 1 and 3 channel images with UInt8, UInt16 and UInt32 00264 values in each channel. 00265 00266 TIFF and VIFF are aditionally able to store short and long 00267 integers (2 or 4 bytes) and real values (32 bit float and 00268 64 bit double) without conversion. So you will need to use 00269 TIFF or VIFF if you need to store images with high 00270 accuracy (the appropriate type to write is automatically 00271 derived from the image type to be exported). However, many 00272 other programs using TIFF (e.g. ImageMagick) have not 00273 implemented support for those pixel types. So don't be 00274 surprised if the generated TIFF is not readable in some 00275 cases. If this happens, export the image as 'unsigned 00276 char' or 'RGBValue<unsigned char>' by calling 00277 \ref ImageExportInfo::setPixelType(). 00278 00279 Support to reading and writing ICC color profiles is 00280 provided for TIFF, JPEG, and PNG images. 00281 **/ 00282 VIGRA_EXPORT VolumeExportInfo & setFileType( const char * ); 00283 VIGRA_EXPORT const char * getFileType() const; 00284 00285 /** Set compression type. 00286 00287 Recognized strings: "" (no compression), "LZW", 00288 "RunLength", "1" ... "100". A number is interpreted as the 00289 compression quality for JPEG compression. JPEG compression is 00290 supported by the JPEG and TIFF formats. "LZW" is only available 00291 if libtiff was installed with LZW enabled. By default, libtiff came 00292 with LZW disabled due to Unisys patent enforcement. In this case, 00293 VIGRA stores the image uncompressed. 00294 00295 Valid Compression for TIFF files: 00296 JPEG jpeg compression, call setQuality as well! 00297 RLE runlength compression 00298 LZW lzw compression 00299 DEFLATE deflate compression 00300 **/ 00301 VIGRA_EXPORT VolumeExportInfo & setCompression( const char * ); 00302 VIGRA_EXPORT const char * getCompression() const; 00303 00304 /** Set the pixel type of the volume file(s). Possible values are: 00305 <DL> 00306 <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char) 00307 <DT>"INT16"<DD> 16-bit signed integer (short) 00308 <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short) 00309 <DT>"INT32"<DD> 32-bit signed integer (long) 00310 <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long) 00311 <DT>"FLOAT"<DD> 32-bit floating point (float) 00312 <DT>"DOUBLE"<DD> 64-bit floating point (double) 00313 </DL> 00314 **/ 00315 VIGRA_EXPORT VolumeExportInfo & setPixelType( const char * ); 00316 00317 /** Get the pixel type of the images in the volume. Possible values are: 00318 <DL> 00319 <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char) 00320 <DT>"INT16"<DD> 16-bit signed integer (short) 00321 <DT>"INT32"<DD> 32-bit signed integer (long) 00322 <DT>"FLOAT"<DD> 32-bit floating point (float) 00323 <DT>"DOUBLE"<DD> 64-bit floating point (double) 00324 </DL> 00325 **/ 00326 VIGRA_EXPORT const char * getPixelType() const; 00327 00328 VIGRA_EXPORT VolumeExportInfo & setForcedRangeMapping(double fromMin, double fromMax, 00329 double toMin, double toMax); 00330 VIGRA_EXPORT bool hasForcedRangeMapping() const; 00331 VIGRA_EXPORT double getFromMin() const; 00332 VIGRA_EXPORT double getFromMax() const; 00333 VIGRA_EXPORT double getToMin() const; 00334 VIGRA_EXPORT double getToMax() const; 00335 00336 /** Set the volume resolution in horizontal direction 00337 **/ 00338 VIGRA_EXPORT VolumeExportInfo & setXResolution( float ); 00339 VIGRA_EXPORT float getXResolution() const; 00340 00341 /** Set the image resolution in vertical direction 00342 **/ 00343 VIGRA_EXPORT VolumeExportInfo & setYResolution( float ); 00344 VIGRA_EXPORT float getYResolution() const; 00345 00346 /** Set the image resolution in depth direction 00347 **/ 00348 VIGRA_EXPORT VolumeExportInfo & setZResolution( float ); 00349 VIGRA_EXPORT float getZResolution() const; 00350 00351 /** Set the position of the upper Left corner on a global 00352 canvas. 00353 00354 Currently only supported by TIFF and PNG files. 00355 00356 The offset is encoded in the XPosition and YPosition TIFF tags. 00357 00358 @param pos position of the upper left corner in pixels 00359 (must be >= 0) 00360 **/ 00361 // FIXME: mhanselm: we might want to support 3D positions 00362 VIGRA_EXPORT VolumeExportInfo & setPosition(const Diff2D & pos); 00363 00364 /** Get the position of the upper left corner on 00365 a global canvas. 00366 **/ 00367 // FIXME: mhanselm: we might want to support 3D positions 00368 VIGRA_EXPORT Diff2D getPosition() const; 00369 00370 /** 00371 ICC profiles (handled as raw data so far). 00372 see getICCProfile()/setICCProfile() 00373 **/ 00374 typedef ArrayVector<unsigned char> ICCProfile; 00375 00376 /** Returns a reference to the ICC profile. 00377 */ 00378 VIGRA_EXPORT const ICCProfile & getICCProfile() const; 00379 00380 /** Sets the ICC profile. 00381 ICC profiles are currently supported by TIFF, PNG and JPEG images. 00382 (Otherwise, the profile data is silently ignored.) 00383 **/ 00384 VIGRA_EXPORT VolumeExportInfo & setICCProfile(const ICCProfile & profile); 00385 00386 private: 00387 float m_x_res, m_y_res, m_z_res; 00388 00389 std::string m_filetype, m_filename_base, m_filename_ext, m_pixeltype, m_comp; 00390 Diff2D m_pos; 00391 ICCProfile m_icc_profile; 00392 double fromMin_, fromMax_, toMin_, toMax_; 00393 }; 00394 00395 namespace detail { 00396 00397 template <class DestIterator, class Shape, class T> 00398 inline void 00399 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<0>) 00400 { 00401 s.read((char*)buffer.begin(), shape[0]*sizeof(T)); 00402 00403 DestIterator dend = d + shape[0]; 00404 int k = 0; 00405 for(; d < dend; ++d, k++) 00406 { 00407 *d = buffer[k]; 00408 } 00409 } 00410 00411 template <class DestIterator, class Shape, class T, int N> 00412 void 00413 readVolumeImpl(DestIterator d, Shape const & shape, std::ifstream & s, ArrayVector<T> & buffer, MetaInt<N>) 00414 { 00415 DestIterator dend = d + shape[N]; 00416 for(; d < dend; ++d) 00417 { 00418 readVolumeImpl(d.begin(), shape, s, buffer, MetaInt<N-1>()); 00419 } 00420 } 00421 00422 } // namespace detail 00423 00424 template <class T, class Stride> 00425 void VolumeImportInfo::importImpl(MultiArrayView <3, T, Stride> &volume) const 00426 { 00427 vigra_precondition(this->shape() == volume.shape(), "importVolume(): Volume must be shaped according to VolumeImportInfo."); 00428 00429 if(rawFilename_.size()) 00430 { 00431 std::string dirName, baseName; 00432 char oldCWD[2048]; 00433 00434 #ifdef _MSC_VER 00435 if(_getcwd(oldCWD, 2048) == 0) 00436 { 00437 perror("getcwd"); 00438 vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd)."); 00439 } 00440 if(_chdir(path_.c_str())) 00441 { 00442 perror("chdir"); 00443 vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir)."); 00444 } 00445 #else 00446 if(getcwd(oldCWD, 2048) == 0) 00447 { 00448 perror("getcwd"); 00449 vigra_fail("VolumeImportInfo: Unable to query current directory (getcwd)."); 00450 } 00451 if(chdir(path_.c_str())) 00452 { 00453 perror("chdir"); 00454 vigra_fail("VolumeImportInfo: Unable to change to new directory (chdir)."); 00455 } 00456 #endif 00457 00458 std::ifstream s(rawFilename_.c_str(), std::ios::binary); 00459 vigra_precondition(s.good(), "RAW file could not be opened"); 00460 00461 ArrayVector<T> buffer(shape_[0]); 00462 detail::readVolumeImpl(volume.traverser_begin(), shape_, s, buffer, vigra::MetaInt<2>()); 00463 00464 //vigra_precondition(s.good(), "RAW file could not be opened"); 00465 //s.read((char*)volume.data(), shape_[0]*shape_[1]*shape_[2]*sizeof(T)); 00466 00467 #ifdef _MSC_VER 00468 if(_chdir(oldCWD)) 00469 perror("chdir"); 00470 #else 00471 if(chdir(oldCWD)) 00472 perror("chdir"); 00473 #endif 00474 00475 vigra_postcondition( 00476 volume.shape() == shape(), "imported volume has wrong size"); 00477 } 00478 else 00479 { 00480 for (unsigned int i = 0; i < numbers_.size(); ++i) 00481 { 00482 // build the filename 00483 std::string name = baseName_ + numbers_[i] + extension_; 00484 00485 // import the image 00486 ImageImportInfo info (name.c_str ()); 00487 00488 // generate a basic image view to the current layer 00489 MultiArrayView <2, T, Stride> view (volume.bindOuter (i)); 00490 vigra_precondition(view.shape() == info.shape(), 00491 "importVolume(): the images have inconsistent sizes."); 00492 00493 importImage (info, destImage(view)); 00494 } 00495 } 00496 } 00497 00498 00499 VIGRA_EXPORT void findImageSequence(const std::string &name_base, 00500 const std::string &name_ext, 00501 std::vector<std::string> & numbers); 00502 00503 /********************************************************/ 00504 /* */ 00505 /* importVolume */ 00506 /* */ 00507 /********************************************************/ 00508 00509 /** \brief Function for importing a 3D volume. 00510 00511 The data are expected to be stored in a by-slice manner, 00512 where the slices are enumerated from <tt>name_base+"[0-9]+"+name_ext</tt>. 00513 <tt>name_base</tt> may contain a path. All slice files with the same name base and 00514 extension are considered part of the same volume. Slice numbers must be non-negative, 00515 but can otherwise start anywhere and need not be successive. Slices will be read 00516 in ascending numerical (not lexicographic) order. All slices must have the 00517 same size. The <tt>volume</tt> will be reshaped to match the count and 00518 size of the slices found. 00519 00520 <b>\#include</b> 00521 <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>> 00522 00523 Namespace: vigra 00524 */ 00525 template <class T, class Allocator> 00526 void importVolume (MultiArray <3, T, Allocator> & volume, 00527 const std::string &name_base, 00528 const std::string &name_ext) 00529 { 00530 VolumeImportInfo info(name_base, name_ext); 00531 volume.reshape(info.shape()); 00532 00533 info.importImpl(volume); 00534 } 00535 00536 00537 /** \brief Function for importing a 3D volume. 00538 00539 The data can be given in two ways: 00540 00541 <UL> 00542 <LI> If the volume is stored in a by-slice manner (e.g. one image per slice), 00543 the <tt>filename</tt> can refer to an arbitrary image from the set. <tt>importVolume()</tt> 00544 then assumes that the slices are enumerated like <tt>name_base+"[0-9]+"+name_ext</tt>, 00545 where <tt>name_base</tt>, the index, and <tt>name_ext</tt> are determined automatically. 00546 All slice files with the same name base and extension are considered part of the same 00547 volume. Slice numbers must be non-negative, but can otherwise start anywhere and need 00548 not be successive. Slices will be read in ascending numerical (not lexicographic) order. 00549 All slices must have the same size. 00550 <li> Otherwise, <tt>importVolume()</tt> will try to read <tt>filename</tt> as an 00551 info text file with the following key-value pairs: 00552 <UL> 00553 <LI> name = [short descriptive name of the volume] (optional) 00554 <LI> filename = [absolute or relative path to raw voxel data file] (required) 00555 <li> gradfile = [absolute or relative path to gradient data file] (currently ignored) 00556 <li> description = [arbitrary description of the data set] (optional) 00557 <li> width = [positive integer] (required) 00558 <li> height = [positive integer] (required) 00559 <li> depth = [positive integer] (required) 00560 <li> datatype = [UNSIGNED_CHAR | UNSIGNED_BYTE] (default: UNSIGNED_CHAR) 00561 </UL> 00562 The voxel type is currently assumed to be binary compatible to the <tt>value_type T</TT> 00563 of the <tt>MuliArray</tt>. Lines starting with "#" are ignored. 00564 </UL> 00565 00566 In either case, the <tt>volume</tt> will be reshaped to match the count and 00567 size of the slices found. 00568 00569 <b>\#include</b> 00570 <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>> 00571 00572 Namespace: vigra 00573 */ 00574 template <class T, class Allocator> 00575 void importVolume(MultiArray <3, T, Allocator> &volume, 00576 const std::string &filename) 00577 { 00578 VolumeImportInfo info(filename); 00579 volume.reshape(info.shape()); 00580 00581 info.importImpl(volume); 00582 } 00583 00584 /** \brief Function for importing a 3D volume. 00585 00586 Read the volume data set <tt>info</tt> refers to. Explicit construction 00587 of the info object allows to allocate a <tt>volume</tt> object type whose 00588 <tt>value_type</tt> matches the voxel type of the stored data. 00589 The <tt>volume</tt> will be reshaped to match the count and 00590 size of the slices found. 00591 00592 <b>\#include</b> 00593 <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>> 00594 00595 Namespace: vigra 00596 */ 00597 template <class T, class Stride> 00598 void importVolume(VolumeImportInfo const & info, MultiArrayView <3, T, Stride> &volume) 00599 { 00600 info.importImpl(volume); 00601 } 00602 00603 namespace detail { 00604 00605 template <class T> 00606 void setRangeMapping(std::string const & pixeltype, 00607 FindMinMax<T> const & minmax, ImageExportInfo & info) 00608 { 00609 if(pixeltype == "UINT8") 00610 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 00611 (double)NumericTraits<UInt8>::min(), 00612 (double)NumericTraits<UInt8>::max()); 00613 else if(pixeltype == "INT16") 00614 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 00615 (double)NumericTraits<Int16>::min(), 00616 (double)NumericTraits<Int16>::max()); 00617 else if(pixeltype == "UINT16") 00618 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 00619 (double)NumericTraits<UInt16>::min(), 00620 (double)NumericTraits<UInt16>::max()); 00621 else if(pixeltype == "INT32") 00622 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 00623 (double)NumericTraits<Int32>::min(), 00624 (double)NumericTraits<Int32>::max()); 00625 else if(pixeltype == "UINT32") 00626 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 00627 (double)NumericTraits<UInt32>::min(), 00628 (double)NumericTraits<UInt32>::max()); 00629 else if(pixeltype == "FLOAT") 00630 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0); 00631 else if(pixeltype == "DOUBLE") 00632 info.setForcedRangeMapping((double)minmax.min, (double)minmax.max, 0.0, 1.0); 00633 } 00634 00635 template <class T, class Tag> 00636 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume, 00637 ImageExportInfo & info, VigraTrueType /* isScalar */) 00638 { 00639 std::string pixeltype = info.getPixelType(); 00640 bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()), 00641 TypeAsString<T>::result(), pixeltype); 00642 00643 if(downcast) 00644 { 00645 FindMinMax<T> minmax; 00646 inspectMultiArray(srcMultiArrayRange(volume), minmax); 00647 setRangeMapping(pixeltype, minmax, info); 00648 } 00649 } 00650 00651 template <class T, class Tag> 00652 void setRangeMapping(MultiArrayView <3, T, Tag> const & volume, 00653 ImageExportInfo & info, VigraFalseType /* isScalar */) 00654 { 00655 typedef typename T::value_type SrcComponent; 00656 std::string pixeltype = info.getPixelType(); 00657 bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), info.getFileType()), 00658 TypeAsString<SrcComponent>::result(), pixeltype); 00659 00660 if(downcast) 00661 { 00662 unsigned int bands = volume(0,0,0).size(); 00663 FindMinMax<SrcComponent> minmax; 00664 for(unsigned int i=0; i<bands; ++i) 00665 { 00666 VectorComponentValueAccessor<T> band(i); 00667 inspectMultiArray(srcMultiArrayRange(volume, band), minmax ); 00668 } 00669 setRangeMapping(pixeltype, minmax, info); 00670 } 00671 } 00672 00673 } // namespace detail 00674 00675 /********************************************************/ 00676 /* */ 00677 /* exportVolume */ 00678 /* */ 00679 /********************************************************/ 00680 00681 /** \brief Function for exporting a 3D volume. 00682 00683 The volume is exported in a by-slice manner, where the number of slices equals 00684 the depth of the volume. The file names will be enumerated like 00685 <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> etc. 00686 (the actual number of zeros depends on the depth). If the target image type 00687 does not support the source voxel type, all slices will be mapped simultaneously 00688 to the appropriate target range. 00689 00690 <b>\#include</b> 00691 <<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>> 00692 00693 Namespace: vigra 00694 */ 00695 template <class T, class Tag> 00696 void exportVolume (MultiArrayView <3, T, Tag> const & volume, 00697 const VolumeExportInfo & volinfo) 00698 { 00699 std::string name = std::string(volinfo.getFileNameBase()) + std::string(volinfo.getFileNameExt()); 00700 ImageExportInfo info(name.c_str()); 00701 info.setCompression(volinfo.getCompression()); 00702 info.setPixelType(volinfo.getPixelType()); 00703 detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScalar()); 00704 00705 const unsigned int depth = volume.shape (2); 00706 int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth))); 00707 for (unsigned int i = 0; i < depth; ++i) 00708 { 00709 00710 // build the filename 00711 std::stringstream stream; 00712 stream << std::setfill ('0') << std::setw (numlen) << i; 00713 std::string name_num; 00714 stream >> name_num; 00715 std::string name = std::string(volinfo.getFileNameBase()) + name_num + std::string(volinfo.getFileNameExt()); 00716 00717 MultiArrayView <2, T, Tag> view (volume.bindOuter (i)); 00718 00719 // export the image 00720 info.setFileName(name.c_str ()); 00721 exportImage(srcImageRange(view), info); 00722 } 00723 } 00724 00725 // for backward compatibility 00726 template <class T, class Tag> 00727 inline 00728 void exportVolume (MultiArrayView <3, T, Tag> const & volume, 00729 const std::string &name_base, 00730 const std::string &name_ext) 00731 { 00732 VolumeExportInfo volinfo(name_base.c_str(), name_ext.c_str()); 00733 exportVolume(volume, volinfo); 00734 } 00735 00736 //@} 00737 00738 } // namespace vigra 00739 00740 #endif // VIGRA_MULTI_IMPEX_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|