25 #include "PMDImageIO.hh"
30 #define UINT16_MAX (65535U)
33 #define DEPTH_MAX 65.535f
36 #define MODCOEFF_MAX 1000
37 #define MODCOEFF_MIN 0
43 TIFFExtendProc PMDImageIO::ParentExtender = NULL;
47 static const TIFFFieldInfo tiffFieldInfo[] =
48 {{ TIFFTAG_PRINCIPALPOINT, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM,
true,
true,
49 (
char*)(
"PrincipalPoint")},
50 { TIFFTAG_FOCALLENGTHX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM,
true,
true,
51 (
char*)(
"FocalLengthX") },
52 { TIFFTAG_ASPECTRATIO, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM,
true,
true,
53 (
char*)(
"AspectRatio") },
54 { TIFFTAG_UNDISTORTION, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM,
true,
true,
55 (
char*)(
"BougetUndistortion") },
56 { TIFFTAG_CAMERACENTER, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM,
true,
true,
57 (
char*)(
"CameraCenter") },
58 { TIFFTAG_CAMERAROTATION, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM,
true,
true,
59 (
char*)(
"CameraRotation") }
66 # define FUNCNAME __FUNCTION__
68 # define FUNCNAME __PRETTY_FUNCTION__
71 # define BIASERR(arg) { \
72 cerr<<std::flush<<"Error in "<<__FILE__<<":"<<__LINE__<<" : "<<FUNCNAME<<std::endl \
73 <<"\t"<<arg<<std::endl<<std::flush; \
78 int PMDImageIO::Save2DImage8Bit_(TIFF *tiffimage, uint8* Img2D,
82 TIFFSetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION,
"2D-Image");
84 TIFFSetField(tiffimage, TIFFTAG_IMAGEWIDTH, MetaData2D.
width);
85 TIFFSetField(tiffimage, TIFFTAG_IMAGELENGTH, MetaData2D.
height);
86 TIFFSetField(tiffimage, TIFFTAG_BITSPERSAMPLE, 8);
87 TIFFSetField(tiffimage, TIFFTAG_SAMPLESPERPIXEL, MetaData2D.
channels);
88 TIFFSetField(tiffimage, TIFFTAG_ROWSPERSTRIP, LinesPerStrip);
90 TIFFSetField(tiffimage, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
92 TIFFSetField(tiffimage, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
94 TIFFSetField(tiffimage, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
97 TIFFSetField(tiffimage, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
99 SaveMetaData_(tiffimage, MetaData2D);
102 unsigned char* ipt = Img2D;
104 for (
unsigned int i=0;
105 i< ceil((
double)MetaData2D.
height/(
double)LinesPerStrip); i++) {
106 int bytecount = MetaData2D.
width*LinesPerStrip*MetaData2D.
channels;
107 if ((i+1)*LinesPerStrip>MetaData2D.
height) {
108 bytecount = (MetaData2D.
height-i*LinesPerStrip)*
111 TIFFReadEncodedStrip(tiffimage, i, ipt, bytecount);
118 int PMDImageIO::Save2DImage16Bit_(TIFF *tiffimage, uint16* Img2D,
122 TIFFSetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION,
"2D-Image");
124 TIFFSetField(tiffimage, TIFFTAG_IMAGEWIDTH, MetaData2D.
width);
125 TIFFSetField(tiffimage, TIFFTAG_IMAGELENGTH, MetaData2D.
height);
126 TIFFSetField(tiffimage, TIFFTAG_BITSPERSAMPLE, 16);
127 TIFFSetField(tiffimage, TIFFTAG_SAMPLESPERPIXEL, MetaData2D.
channels);
128 TIFFSetField(tiffimage, TIFFTAG_ROWSPERSTRIP, LinesPerStrip);
130 TIFFSetField(tiffimage, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
132 TIFFSetField(tiffimage, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
134 TIFFSetField(tiffimage, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
137 TIFFSetField(tiffimage, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
139 SaveMetaData_(tiffimage, MetaData2D);
142 unsigned char* ipt = (
unsigned char*) Img2D;
144 for (
unsigned int i=0;
145 i< ceil((
double)MetaData2D.
height/(
double)LinesPerStrip); i++) {
146 int bytecount = MetaData2D.
width*LinesPerStrip*MetaData2D.
channels*2;
147 if ((i+1)*LinesPerStrip>MetaData2D.
height) {
148 bytecount = (MetaData2D.
height-i*LinesPerStrip)*
151 TIFFWriteEncodedStrip(tiffimage, i, ipt, bytecount);
158 int PMDImageIO::SaveDepthImage_(TIFF *tiffimage, uint16* ImgDepth,
162 TIFFSetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION,
"Depth-Image");
164 TIFFSetField(tiffimage, TIFFTAG_IMAGEWIDTH, MetaDataDepth.
width);
165 TIFFSetField(tiffimage, TIFFTAG_IMAGELENGTH, MetaDataDepth.
height);
166 TIFFSetField(tiffimage, TIFFTAG_BITSPERSAMPLE, 16);
167 TIFFSetField(tiffimage, TIFFTAG_SAMPLESPERPIXEL, 1);
168 TIFFSetField(tiffimage, TIFFTAG_ROWSPERSTRIP, LinesPerStrip);
170 TIFFSetField(tiffimage, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
171 TIFFSetField(tiffimage, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
173 TIFFSetField(tiffimage, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
175 SaveMetaData_(tiffimage, MetaDataDepth);
178 unsigned char* ipt = (
unsigned char*) ImgDepth;
179 for (
unsigned int i=0;
180 i< ceil((
double)MetaDataDepth.
height/(
double)LinesPerStrip); i++) {
181 int bytecount = MetaDataDepth.
width*LinesPerStrip*
183 if ((i+1)*LinesPerStrip>MetaDataDepth.
height) {
184 bytecount = (MetaDataDepth.
height-i*LinesPerStrip)*
187 TIFFWriteEncodedStrip(tiffimage, i, ipt, bytecount);
188 ipt+=MetaDataDepth.
width*LinesPerStrip*
195 int PMDImageIO::SaveModCoeffImage_(TIFF *tiffimage, uint16* ImgModCoeff,
199 TIFFSetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION,
200 "Modulation-Coefficients");
202 TIFFSetField(tiffimage, TIFFTAG_IMAGEWIDTH, MetaDataDepth.
width);
203 TIFFSetField(tiffimage, TIFFTAG_IMAGELENGTH, MetaDataDepth.
height);
204 TIFFSetField(tiffimage, TIFFTAG_BITSPERSAMPLE, 16);
205 TIFFSetField(tiffimage, TIFFTAG_SAMPLESPERPIXEL, 1);
206 TIFFSetField(tiffimage, TIFFTAG_ROWSPERSTRIP, LinesPerStrip);
208 TIFFSetField(tiffimage, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
209 TIFFSetField(tiffimage, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
211 TIFFSetField(tiffimage, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
215 SaveMetaData_(tiffimage, MetaDataDepth);
218 unsigned char* ipt = (
unsigned char*) ImgModCoeff;
219 for (
unsigned int i=0;
220 i< ceil((
double)MetaDataDepth.
height/(
double)LinesPerStrip); i++) {
221 int bytecount = MetaDataDepth.
width*LinesPerStrip*
223 if ((i+1)*LinesPerStrip>MetaDataDepth.
height) {
224 bytecount = (MetaDataDepth.
height-i*LinesPerStrip)*
227 TIFFWriteEncodedStrip(tiffimage, i, ipt, bytecount);
228 ipt+=MetaDataDepth.
width*LinesPerStrip*
235 int PMDImageIO::Save(
const std::string& FileName,
236 uint8* Img2D, uint16* ImgDepth,
243 int LinesPerStrip=10;
246 NewTagsInitialize_();
248 if((tiffimage = TIFFOpen(FileName.c_str(),
"w")) == NULL){
249 BIASERR(
"Could not open image for writing:" << FileName);
255 Save2DImage8Bit_(tiffimage, Img2D, MetaData2D, LinesPerStrip);
259 if (ImgDepth!=NULL) {
260 if (Img2D!=NULL) TIFFWriteDirectory(tiffimage);
261 SaveDepthImage_(tiffimage, ImgDepth, MetaDataDepth, LinesPerStrip);
266 if (ImgDepth!=NULL && ImgModCoeff!=NULL) {
268 TIFFWriteDirectory(tiffimage);
269 SaveModCoeffImage_(tiffimage, ImgModCoeff, MetaDataDepth, LinesPerStrip);
273 TIFFClose(tiffimage);
278 int PMDImageIO::Save(
const std::string& FileName,
279 uint16* Img2D, uint16* ImgDepth,
286 int LinesPerStrip=10;
289 NewTagsInitialize_();
291 if((tiffimage = TIFFOpen(FileName.c_str(),
"w")) == NULL){
292 BIASERR(
"Could not open image for writing:" << FileName);
298 Save2DImage16Bit_(tiffimage, Img2D, MetaData2D, LinesPerStrip);
302 if (ImgDepth!=NULL) {
303 if (Img2D!=NULL) TIFFWriteDirectory(tiffimage);
304 SaveDepthImage_(tiffimage, ImgDepth, MetaDataDepth, LinesPerStrip);
309 if (ImgDepth!=NULL && ImgModCoeff!=NULL) {
311 TIFFWriteDirectory(tiffimage);
312 SaveModCoeffImage_(tiffimage, ImgModCoeff, MetaDataDepth, LinesPerStrip);
316 TIFFClose(tiffimage);
322 int PMDImageIO::Load2DImage8Bit_(TIFF *tiffimage,
328 if((TIFFGetField(tiffimage, TIFFTAG_BITSPERSAMPLE, &bps) == 0) ||
330 BIASERR(
"Bits per Sample != 8!");
334 if(TIFFGetField(tiffimage, TIFFTAG_PHOTOMETRIC, &photo) == 0 ||
335 (photo != PHOTOMETRIC_RGB && photo != PHOTOMETRIC_MINISBLACK)){
336 BIASERR(
"Image has the wrong photometric interpretation! Trying PHOTOMETRIC_MINISBLACK.");
337 photo = PHOTOMETRIC_MINISBLACK;
341 LoadMetaData_(tiffimage, MetaData2D);
344 BIASERR(
"Wrong number of channels in 2D image!");
349 tsize_t stripSize = TIFFStripSize (tiffimage);
350 int stripMax = TIFFNumberOfStrips (tiffimage);
352 unsigned char *ipt =
new unsigned char[MetaData2D.
height*
357 for (
int i = 0; i < stripMax; i++){
362 if(TIFFReadEncodedStrip(tiffimage, i, ipt, stripSize)<0){
363 BIASERR(
"Load error on input strip number "<< i);
373 int PMDImageIO::Load2DImage16Bit_(TIFF *tiffimage,
379 if((TIFFGetField(tiffimage, TIFFTAG_BITSPERSAMPLE, &bps) == 0) ||
381 BIASERR(
"Bits per Sample != 16!");
385 if(TIFFGetField(tiffimage, TIFFTAG_PHOTOMETRIC, &photo) == 0 ||
386 (photo != PHOTOMETRIC_RGB && photo != PHOTOMETRIC_MINISBLACK)){
387 BIASERR(
"Image has the wrong photometric interpretation!");
391 LoadMetaData_(tiffimage, MetaData2D);
394 BIASERR(
"Wrong number of channels in 2D image!");
399 tsize_t stripSize = TIFFStripSize (tiffimage);
400 int stripMax = TIFFNumberOfStrips (tiffimage);
402 unsigned char *ipt =
new unsigned char[MetaData2D.
height*
405 Img2D = (uint16*)ipt;
407 for (
int i = 0; i < stripMax; i++){
412 if(TIFFReadEncodedStrip(tiffimage, i, ipt, stripSize)<0){
413 BIASERR(
"Load error on input strip number "<< i);
422 int PMDImageIO::LoadDepthImage_(TIFF *tiffimage,
428 if((TIFFGetField(tiffimage, TIFFTAG_BITSPERSAMPLE, &dbps) == 0) ||
430 BIASERR(
"Bits per Sample != 16!");
434 if(TIFFGetField(tiffimage, TIFFTAG_PHOTOMETRIC, &dphoto) == 0 ||
435 (dphoto != PHOTOMETRIC_MINISBLACK)){
436 BIASERR(
"Depth Image has the wrong photometric interpretation!");
440 LoadMetaData_(tiffimage, MetaDataDepth);
443 BIASERR(
"Wrong number of channels in Depth image!");
448 tsize_t stripSize = TIFFStripSize (tiffimage);
449 int stripMax = TIFFNumberOfStrips (tiffimage);
451 unsigned char* ipt =
new unsigned char[MetaDataDepth.
height*
454 ImgDepth = (uint16*)ipt;
455 for (
int i = 0; i < stripMax; i++){
457 stripSize = MetaDataDepth.
height*MetaDataDepth.
width*
458 MetaDataDepth.
channels*2-i*stripSize;
460 if(TIFFReadEncodedStrip(tiffimage, i, ipt, stripSize)<0){
461 BIASERR(
"Load error on input strip number "<< i);
470 int PMDImageIO::LoadModCoeffImage_(TIFF *tiffimage,
471 uint16* &ImgModCoeff,
476 if((TIFFGetField(tiffimage, TIFFTAG_BITSPERSAMPLE, &dbps) == 0) ||
478 BIASERR(
"Bits per Sample != 16!");
482 if(TIFFGetField(tiffimage, TIFFTAG_PHOTOMETRIC, &dphoto) == 0 ||
483 (dphoto != PHOTOMETRIC_MINISBLACK)){
484 BIASERR(
"Modulation Coefficients have the wrong photometric"
485 <<
"interpretation!");
489 LoadMetaData_(tiffimage, MetaDataDepth);
492 BIASERR(
"Wrong number of channels in Modulation Coefficients image!");
497 tsize_t stripSize = TIFFStripSize (tiffimage);
498 int stripMax = TIFFNumberOfStrips (tiffimage);
500 unsigned char* ipt =
new unsigned char[MetaDataDepth.
height*
503 ImgModCoeff = (uint16*)ipt;
504 for (
int i = 0; i < stripMax; i++){
506 stripSize = MetaDataDepth.
height*MetaDataDepth.
width*
507 MetaDataDepth.
channels*2-i*stripSize;
509 if(TIFFReadEncodedStrip(tiffimage, i, ipt, stripSize)<0){
510 BIASERR(
"Load error on input strip number "<< i);
519 int PMDImageIO::Load(
const std::string& FileName,
520 uint16* &Img2D, uint16* &ImgDepth,
521 uint16* &ImgModCoeff,
533 NewTagsInitialize_();
535 if((tiffimage = TIFFOpen(FileName.c_str(),
"r")) == NULL){
536 BIASERR(
"Could not open image for Loading:" << FileName);
542 if (TIFFGetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION, &descr) == 0) {
543 BIASERR(
"Image description is missing!");
547 if(strcmp(descr,
"2D-Image") == 0) {
548 if (Load2DImage16Bit_(tiffimage, Img2D, MetaData2D)<0)
552 if(strcmp(descr,
"Depth-Image") == 0) {
553 if (LoadDepthImage_(tiffimage, ImgDepth, MetaDataDepth)<0)
557 if(strcmp(descr,
"Modulation-Coefficients") == 0) {
558 if (LoadModCoeffImage_(tiffimage, ImgModCoeff, MetaDataDepth)<0)
562 }
while (TIFFReadDirectory(tiffimage)!=0);
565 TIFFClose(tiffimage);
570 int PMDImageIO::Load(
const std::string& FileName,
571 uint8* &Img2D, uint16* &ImgDepth,
572 uint16* &ImgModCoeff,
585 NewTagsInitialize_();
587 if((tiffimage = TIFFOpen(FileName.c_str(),
"r")) == NULL){
588 BIASERR(
"Could not open image for Loading:" << FileName);
594 if (TIFFGetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION, &descr) == 0) {
595 BIASERR(
"Image description is missing!");
599 if(strcmp(descr,
"2D-Image") == 0) {
600 if (Load2DImage8Bit_(tiffimage, Img2D, MetaData2D)<0)
604 if(strcmp(descr,
"Depth-Image") == 0) {
605 if (LoadDepthImage_(tiffimage, ImgDepth, MetaDataDepth)<0)
609 if(strcmp(descr,
"Modulation-Coefficients") == 0) {
610 if (LoadModCoeffImage_(tiffimage, ImgModCoeff, MetaDataDepth)<0)
614 }
while (TIFFReadDirectory(tiffimage)!=0);
617 TIFFClose(tiffimage);
622 #ifdef BIAS_HAVE_XML2
624 int PMDImageIO::LoadXML(
const std::string& FileName,
625 uint16* &Img2D, uint16* &ImgDepth,
626 uint16* &ImgModCoeff,
633 rootNode = myXML.
read(FileName);
634 if (rootNode==NULL) {
635 BIASERR(
"PMD-XML-File not found or parse error: " << FileName);
639 BIASERR(
"Root node has to be \"frame\" or \"sequence\"");
643 rootNode = myXML.
getChild(rootNode,
"frame");
644 if (rootNode==NULL) {
645 BIASERR(
"Root node \"sequence\" has no child \"frame\"");
649 return LoadXML(myXML, rootNode, Img2D, ImgDepth, ImgModCoeff, MetaData2D, MetaDataDepth);
653 int PMDImageIO::LoadXML(
XMLIO &myXML, xmlNodePtr &rootNode,
654 uint16* &Img2D, uint16* &ImgDepth,
655 uint16* &ImgModCoeff,
663 unsigned int width, height;
670 xmlNodePtr childNode;
672 childNode = myXML.
getChild(rootNode,
"grayscale");
673 if (childNode!=NULL) {
674 Img2D =
new uint16[width*height];
677 if (content.size()!=width*height) {
678 BIASERR(
"Error in XML-File!!");
681 for (
unsigned int i=0; i<content.size(); i++) {
682 *pI = (uint16)content[i];
687 childNode = myXML.
getChild(rootNode,
"distance");
688 if (childNode!=NULL) {
689 ImgDepth =
new uint16[width*height];
690 uint16* pI = ImgDepth;
692 if (content.size()!=width*height) {
693 BIASERR(
"Error in XML-File!!");
696 for (
unsigned int i=0; i<content.size(); i++) {
697 *pI = (uint16)content[i];
702 childNode = myXML.
getChild(rootNode,
"amplitude");
703 if (childNode!=NULL) {
704 ImgModCoeff =
new uint16[width*height];
705 uint16* pI = ImgModCoeff;
707 if (content.size()!=width*height) {
708 BIASERR(
"Error in XML-File!!");
711 for (
unsigned int i=0; i<content.size(); i++) {
712 *pI = (uint16)content[i];
717 MetaData2D.
width = MetaDataDepth.
width = width;
740 #endif // BIAS_HAVE_XML2
743 int PMDImageIO::Save(
const std::string& FileName,
751 uint16* dataDepth=NULL;
752 uint16* dataModCoeff=NULL;
755 BIASERR(
"2D-Data is necessary!");
764 BIASERR(
"The RGB or grey image has the wrong storage type, has to be" <<
777 BIASERR(
"The depth image has the wrong storage type, has to be" <<
783 dataDepth =
new uint16[MetaDataDepth.
width*MetaDataDepth.
height];
784 uint16* pDataDepth = dataDepth;
786 for (i=0; i<MetaDataDepth.
width*MetaDataDepth.
height;
787 i++, pDataDepthf++, pDataDepth++) {
788 *pDataDepth =DepthConvert_(*pDataDepthf);
793 BIASERR(
"The modulation coefficients image has the wrong storage" <<
794 "type, has to be ST_float");
800 BIASERR(
"The modulation coefficients image must have same size " <<
801 "and channels as the depth image");
805 dataModCoeff =
new uint16[MetaDataDepth.
width*MetaDataDepth.
height];
806 uint16* pDataModCoeff = dataModCoeff;
808 for (i=0; i<MetaDataDepth.
width*MetaDataDepth.
height;
809 i++, pDataModCoefff++, pDataModCoeff++) {
810 *pDataModCoeff = ModCoeffConvert_(*pDataModCoefff);
814 PMDImageIO::Save(FileName, data2D, dataDepth, dataModCoeff,
815 MetaData2D, MetaDataDepth);
817 if (dataDepth!=NULL)
delete [] dataDepth;
818 if (dataModCoeff!=NULL)
delete [] dataModCoeff;
825 int PMDImageIO::Load(
const std::string& FileName,
832 #ifdef BIAS_HAVE_XML2
833 if (strstr(FileName.c_str(),
".xml")!=NULL) {
834 return PMDImageIO::LoadFromXML(FileName, Img2D, ImgDepth, ImgModCoeff,
835 MetaData2D, MetaDataDepth);
838 return PMDImageIO::LoadFromTIFF(FileName, Img2D, ImgDepth, ImgModCoeff,
839 MetaData2D, MetaDataDepth);
840 #ifdef BIAS_HAVE_XML2
847 #ifdef BIAS_HAVE_XML2
849 int PMDImageIO::LoadFromXML(
const std::string& FileName,
857 uint16* data2d16=NULL;
858 uint16* dataDepth=NULL;
859 uint16* dataModCoeff=NULL;
861 if (PMDImageIO::LoadXML(FileName, data2d16, dataDepth, dataModCoeff,
862 MetaData2D, MetaDataDepth)<0) {
863 BIASERR(
"Could not Load XML-image.");
866 Grey16to8Bit_(data2d16, data2d,
868 return PostprocessData_(data2d, dataDepth, dataModCoeff,
869 Img2D, ImgDepth, ImgModCoeff,
870 MetaData2D, MetaDataDepth);
875 int PMDImageIO::LoadFromXML(
const std::string& FileName,
879 vector<PMDImageMetaData> &vecMetaData2D,
880 vector<PMDImageMetaData> &vecMetaDataDepth)
884 uint16* data2d16=NULL;
885 uint16* dataDepth=NULL;
886 uint16* dataModCoeff=NULL;
896 xmlNodePtr rootNode, childNode, tempChildNode;
897 rootNode = myXML.
read(FileName);
898 if (rootNode==NULL) {
899 BIASERR(
"PMD-XML-File not found or parse error: " << FileName);
904 while (childNode!=NULL) {
906 tempChildNode = childNode;
907 if (PMDImageIO::LoadXML(myXML, tempChildNode, data2d16, dataDepth, dataModCoeff,
908 MetaData2D, MetaDataDepth)<0)
910 BIASERR(
"Could not Load XML-image.");
913 Grey16to8Bit_(data2d16, data2d,
915 if (PostprocessData_(data2d, dataDepth, dataModCoeff,
916 Img2D, ImgDepth, ImgModCoeff,
917 MetaData2D, MetaDataDepth)<0)
919 BIASERR(
"Error writing images to BIAS::Image.");
922 vecImg2D.push_back(Img2D);
923 vecImgDepth.push_back(ImgDepth);
924 vecImgModCoeff.push_back(ImgModCoeff);
925 vecMetaData2D.push_back(MetaData2D);
926 vecMetaDataDepth.push_back(MetaDataDepth);
933 if (LoadFromXML(FileName, Img2D, ImgDepth, ImgModCoeff,
934 MetaData2D, MetaDataDepth))
936 BIASERR(
"Could not Load XML-image.");
939 vecImg2D.push_back(Img2D);
940 vecImgDepth.push_back(ImgDepth);
941 vecImgModCoeff.push_back(ImgModCoeff);
942 vecMetaData2D.push_back(MetaData2D);
943 vecMetaDataDepth.push_back(MetaDataDepth);
945 BIASERR(
"Root node has to be \"frame\" or \"sequence\"");
956 int PMDImageIO::LoadFromTIFF(
const std::string& FileName,
964 uint16* dataDepth=NULL;
965 uint16* dataModCoeff=NULL;
967 if (PMDImageIO::Load(FileName, data2d, dataDepth, dataModCoeff,
968 MetaData2D, MetaDataDepth)<0) {
969 BIASERR(
"Could not Load TIFF-image.");
972 return PostprocessData_(data2d, dataDepth, dataModCoeff,
973 Img2D, ImgDepth, ImgModCoeff,
974 MetaData2D, MetaDataDepth);
978 int PMDImageIO::LoadFromTXT(
int width,
int height,
979 const std::string& FileName2D,
980 const std::string& FileNameDepth,
981 const std::string& FileNameModCoeff,
988 ifstream in2D(FileName2D.c_str());
990 BIASERR(
"Error opening 2D file:"<<FileName2D);
993 ifstream inDepth(FileNameDepth.c_str());
995 BIASERR(
"Error opening Depth file:"<<FileNameDepth);
998 ifstream inModCoeff(FileNameModCoeff.c_str());
1000 BIASERR(
"Error opening ModCoeff file:"<<FileNameModCoeff);
1004 uint8* data2d = NULL;
1005 uint16* data2d16 =
new uint16[width*height];
1006 uint16* dataDepth =
new uint16[width*height];
1007 uint16* dataModCoeff =
new uint16[width*height];
1010 for (
int i=0; i<width*height; i++) {
1012 data2d16[i] = uint16(d);
1014 dataDepth[i] = uint16(d);
1016 dataModCoeff[i] = uint16(d);
1018 MetaDataDepth.
width = width;
1019 MetaDataDepth.
height = height;
1021 MetaDataDepth.
PrincipalX = (double)width/2.0;
1022 MetaDataDepth.
PrincipalY = (double)height/2.0;
1035 Grey16to8Bit_(data2d16, data2d,
1037 PostprocessData_(data2d, dataDepth, dataModCoeff,
1038 Img2D, ImgDepth, ImgModCoeff,
1039 MetaDataDepth, MetaDataDepth);
1050 int PMDImageIO::GetBitRep(
const std::string& FileName) {
1053 if((tiffimage = TIFFOpen(FileName.c_str(),
"r")) == NULL){
1054 BIASERR(
"Could not open image for Loading:" << FileName);
1060 if (TIFFGetField(tiffimage, TIFFTAG_IMAGEDESCRIPTION, &descr) == 0) {
1061 BIASERR(
"Image description is missing!");
1064 if(strcmp(descr,
"2D-Image") == 0) {
1066 if (TIFFGetField(tiffimage, TIFFTAG_BITSPERSAMPLE, &bps)<0) {
1072 }
while (TIFFReadDirectory(tiffimage)!=0);
1078 void PMDImageIO::Grey16to8Bit_(uint16* src, uint8* &dst,
1081 dst =
new unsigned char[size];
1085 for (
unsigned int i=0; i<size; i++) {
1086 if ((*p16)<min) min=*p16;
1087 if ((*p16)>max) max=*p16;
1092 for (
unsigned int i=0; i<size; i++) {
1093 (*p8) = (
unsigned char)((
double)((*p16)-min)/(
double)(max-min)*255.0);
1099 uint16 PMDImageIO::Convert_(
float val,
float lower,
float upper) {
1100 float step=(upper-lower)/UINT16_MAX;
1101 if (val < lower)
return 0;
1102 if (val > upper)
return UINT16_MAX;
1103 return (uint16)((val-lower)/step);
1106 float PMDImageIO::Convert_(uint16 val,
float lower,
float upper)
1108 float step=(upper-lower)/UINT16_MAX;
1109 return val*step+lower;
1114 uint16 PMDImageIO::DepthConvert_(
float depth) {
1115 return Convert_(depth, DEPTH_MIN, DEPTH_MAX);
1119 float PMDImageIO::DepthConvert_(uint16 depth) {
1120 return Convert_(depth, DEPTH_MIN, DEPTH_MAX);
1124 uint16 PMDImageIO::ModCoeffConvert_(
float modcoeff) {
1125 return Convert_(modcoeff, MODCOEFF_MIN, MODCOEFF_MAX);
1128 float PMDImageIO::ModCoeffConvert_(uint16 modcoeff) {
1129 return Convert_(modcoeff, MODCOEFF_MIN, MODCOEFF_MAX);
1133 int PMDImageIO::PostprocessData_(uint8* data2d, uint16* dataDepth,
1134 uint16* dataModCoeff,
1140 int ret=0, ret2=0, ret3=0;
1146 (
unsigned char*) data2d);
1147 if (ret!=0) BIASERR(
"Error Loading 2D image" << ret);
1157 if (dataDepth!=NULL) {
1158 float *dataDepthf =
new float[MetaDataDepth.
width*MetaDataDepth.
height];
1159 float *pDataDepthf = dataDepthf;
1160 uint16* pDataDepth = dataDepth;
1161 for (
unsigned int i=0; i<MetaDataDepth.
width*MetaDataDepth.
height;
1162 i++, pDataDepthf++, pDataDepth++) {
1163 *pDataDepthf = DepthConvert_(*pDataDepth);
1170 delete [] dataDepth;
1171 if (ret2!=0) BIASERR(
"Error Loading Depth image" << ret2);
1174 if (dataModCoeff!=NULL) {
1175 float *dataModCoefff =
new float[MetaDataDepth.
width*MetaDataDepth.
height];
1176 float *pDataModCoefff = dataModCoefff;
1177 uint16* pDataModCoeff = dataModCoeff;
1178 for (
unsigned int i=0; i<MetaDataDepth.
width*MetaDataDepth.
height;
1179 i++, pDataModCoefff++, pDataModCoeff++) {
1180 *pDataModCoefff = ModCoeffConvert_(*pDataModCoeff);
1187 delete [] dataModCoeff;
1188 if (ret3!=0) BIASERR(
"Error Loading Modulation Coefficients image"
1191 return ret+ret2+ret3;
1200 uint32 width, height;
1202 if(TIFFGetField(tiffimage, TIFFTAG_IMAGEWIDTH, &width) == 0){
1203 BIASERR(
"Image does not define its width");
1206 MetaData.
width = width;
1209 if(TIFFGetField(tiffimage, TIFFTAG_IMAGELENGTH, &height) == 0){
1210 BIASERR(
"Image does not define its height");
1213 MetaData.
height = height;
1216 if((TIFFGetField(tiffimage, TIFFTAG_SAMPLESPERPIXEL, &channels) == 0)){
1217 BIASERR(
"Wrong number of image planes!");
1223 if(TIFFGetField(tiffimage, TIFFTAG_PRINCIPALPOINT, &count, &cont) == 0 ||
1225 BIASERR(
"Error while Loading Principal point!");
1232 if(TIFFGetField(tiffimage, TIFFTAG_FOCALLENGTHX, &count, &cont) == 0 ||
1234 BIASERR(
"Error while Loading focal length!");
1240 if(TIFFGetField(tiffimage, TIFFTAG_ASPECTRATIO, &count, &cont) == 0 ||
1242 BIASERR(
"Error while Loading aspectratio!");
1248 if(TIFFGetField(tiffimage, TIFFTAG_UNDISTORTION, &count, &cont) == 0 ||
1250 BIASERR(
"Error while Loading bouget undistortion parameters!");
1259 if(TIFFGetField(tiffimage, TIFFTAG_CAMERACENTER, &count, &cont) == 0 ||
1261 BIASERR(
"Error while Loading camera center!");
1269 if(TIFFGetField(tiffimage, TIFFTAG_CAMERAROTATION, &count, &cont) == 0 ||
1271 BIASERR(
"Error while Loading camera rotation!");
1282 int PMDImageIO::SaveMetaData_(TIFF* tiffimage,
1286 TIFFSetField(tiffimage, TIFFTAG_PRINCIPALPOINT, 2, &princ);
1288 TIFFSetField(tiffimage, TIFFTAG_FOCALLENGTHX, 1, &f);
1290 TIFFSetField(tiffimage, TIFFTAG_ASPECTRATIO, 1, &a);
1291 TIFFSetField(tiffimage, TIFFTAG_UNDISTORTION, 4, &MetaData.
UndistCoeff);
1292 TIFFSetField(tiffimage, TIFFTAG_CAMERACENTER, 3, &MetaData.
CameraCenter);
1293 TIFFSetField(tiffimage, TIFFTAG_CAMERAROTATION, 3,
1300 void PMDImageIO::NewTagsInitialize_()
1302 static int first_time=1;
1310 ParentExtender = TIFFSetTagExtender(NewTagsCallback_);
1314 void PMDImageIO::NewTagsCallback_(TIFF *tif) {
1316 TIFFMergeFieldInfo(tif, tiffFieldInfo,
1317 sizeof(tiffFieldInfo)/
sizeof(tiffFieldInfo[0]));
1325 (*ParentExtender)(tif);
void Release()
reimplemented from ImageBase
xmlNodePtr getNextChild()
Get the next child of the parent specified in the last getFirstChild() call, the class remembers the ...
xmlNodePtr read(const std::string &Filename)
Read and parse an XML file from disk, DtD validation is not yet implemented.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
xmlNodePtr getChild(const xmlNodePtr ParentNode, const std::string &ChildName)
Get a child of a Parent node by specifying the childs name, NULL is returned if the ParentNode has no...
void SetColorModel(EColorModel Model)
int InitWithForeignData(unsigned int width, unsigned int height, unsigned int channels, void *data, const bool interleaved=true, const bool shouldRelease=true)
This is used to construct a BIAS::Image hull around existing image data.
unsigned int GetWidth() const
int getAttributeValueInt(const xmlAttrPtr Attribute) const
Wrapper class for reading and writing XML files based on the XML library libxml2. ...
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
unsigned int GetHeight() const
xmlNodePtr getFirstChild(const xmlNodePtr ParentNode)
Get the first child of a given parent, or NULL for no childs.
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
double getAttributeValueDouble(const xmlAttrPtr Attribute) const
std::vector< int > getNodeContentVectorInt(const xmlNodePtr Node) const
std::string getNodeName(const xmlNodePtr Node) const
Get the name of a given Node.
enum EStorageType GetStorageType() const