00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _camera_image_io_h_
00026 #define _camera_image_io_h_
00027
00028 #include "claraty/image_io_factory.h"
00029 #include "claraty/camera_image.h"
00030 #include "claraty/rgb_image.h"
00031 #include "claraty/camera_model.h"
00032 #include "claraty/lock_frame.h"
00033 #include "claraty/string_util.h"
00034 #include "claraty/parse_block.h"
00035 #include "claraty/fdm_parse_tree.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 template <class T>
00048 bool save_camera_image(const std::string& filename,
00049 const Camera_Image<T>& img,
00050 const Parse_Block *extraHeader = NULL,
00051 const RGB_Image<T> *color_img = NULL)
00052 {
00053 Image_IO_Factory *io =
00054 (*Image_IO_Factory::factory)(string_suffix(filename));
00055 if (io == NULL) {
00056 std::cerr << "Unable to find helper class for saving images of type "
00057 << string_suffix(filename) << std::endl;
00058 return false;
00059 }
00060
00061 const int image_io_state_version = 2;
00062
00063 std::auto_ptr<Camera_Model> model(img.get_camera_model_ptr());
00064 std::string mRep = FDM_Parse_Tree::object_to_string(model);
00065 assert(model.get() == img.get_camera_model_ptr());
00066
00067 std::string fs_rep;
00068 if (model.get() == NULL || model->get_frame().is_empty()) {
00069 Framestore tmp("");
00070 fs_rep = FDM_Parse_Tree::object_to_string(tmp);
00071 } else
00072 fs_rep = FDM_Parse_Tree::object_to_string(model->get_frame().get_store());
00073
00074 model.release();
00075
00076 Parse_Block pb;
00077 if (extraHeader != NULL)
00078 pb = *extraHeader;
00079
00080 pb.add_entry("framestore", fs_rep);
00081 pb.add_entry("model", mRep);
00082 pb.add_entry("image_io_state_version", image_io_state_version);
00083 std::string pbString = pb.write_to_string();
00084
00085 bool raster_allocated = true;
00086 unsigned char *raster;
00087 int sig_bits;
00088
00089 if (color_img != NULL) {
00090 sig_bits = Image_IO_Factory::compute_sigbits(color_img->get_red_channel());
00091 raster = Image_IO_Factory::rasterize_image(*color_img);
00092 } else {
00093 sig_bits = Image_IO_Factory::compute_sigbits(img);
00094 raster = Image_IO_Factory::rasterize_image(img, raster_allocated);
00095 }
00096
00097 bool ok = io->save_image_bytes(filename, raster, img.nrows(), img.ncols(),
00098 sizeof(T), sig_bits, pbString,
00099 color_img != NULL);
00100 if (raster_allocated)
00101 delete [] raster;
00102
00103 delete io;
00104
00105 return ok;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 template <class T>
00117 bool load_camera_image(const std::string& filename,
00118 Camera_Image<T> *& img,
00119 Framestore *& fs,
00120 Parse_Block *header = NULL)
00121 {
00122 Image_IO_Factory *io =
00123 (*Image_IO_Factory::factory)(string_suffix(filename));
00124 if (io == NULL) {
00125 std::cerr << "Unable to find helper class for reading images of type "
00126 << string_suffix(filename) << std::endl;
00127 return false;
00128 }
00129
00130 img = NULL;
00131 fs = NULL;
00132
00133 unsigned char **rows;
00134 unsigned int nr, nc;
00135 std::string comments;
00136 int maxval;
00137 int bytes_per_pixel;
00138 bool color;
00139
00140 if (!io->load_image_bytes(filename, rows, nr, nc, comments, maxval,
00141 bytes_per_pixel, color)) {
00142 delete io;
00143 return false;
00144 }
00145 delete io;
00146
00147 Parse_Block parseBlock;
00148 Parse_Block *pb = header != NULL ? header : &parseBlock;
00149
00150 img = new Camera_Image<T>(nr, nc, NULL);
00151 img->set_maximum_value(maxval);
00152 Image_IO_Factory::move_raster_to_image(rows, bytes_per_pixel, *img, color);
00153
00154
00155
00156 std::string old_header = "model_and_framestore=";
00157 std::string::size_type pos = comments.find(old_header);
00158 if (pos != std::string::npos)
00159 comments = comments.substr(old_header.size());
00160
00161 if (!pb->read_from_string(comments)) {
00162 std::cerr << "unable to parse image header" << std::endl;
00163 return false;
00164 }
00165 std::string value;
00166
00167 if (!pb->get_entry("framestore", value)) {
00168 std::cerr << "missed framestore in image header" << std::endl;
00169 return false;
00170 }
00171
00172 if (pb->check_for_entry("image_io_state_version")) {
00173 fs = new Framestore;
00174 bool ok = FDM_Parse_Tree::string_to_object(*fs, value);
00175 if (!ok) {
00176 std::cerr << "missed framestore (fdm representation expected) "
00177 "in image header" << std::endl;
00178 return false;
00179 }
00180 } else {
00181 Parse_Block fsPb(value);
00182 fs = new Framestore(fsPb);
00183 }
00184
00185 if (!pb->get_entry("model", value)) {
00186 std::cerr << "missed model in image header" << std::endl;
00187 return false;
00188 }
00189
00190 std::istringstream mis(value);
00191 Camera_Model *model = Camera_Model::build_from_stream(mis, *fs);
00192
00193 if (model == NULL) {
00194 std::cerr << "unable to build model from stream" << std::endl;
00195 return false;
00196 } else {
00197 img->set_camera_model(model);
00198 delete model;
00199 }
00200 return true;
00201 }
00202
00203
00204
00205
00206
00207 template <class T>
00208 bool load_stereo_camera_images(const std::string& leftFile,
00209 const std::string& rightFile,
00210 Camera_Image<T>*& leftImg,
00211 Camera_Image<T>*& rightImg,
00212 Framestore *& fs, Parse_Block *leftHdr = NULL,
00213 const std::string& refFrame = "")
00214 {
00215 Framestore *fs1;
00216 leftImg = NULL;
00217 rightImg = NULL;
00218 bool ok = load_camera_image(leftFile, leftImg, fs, leftHdr);
00219 ok &= load_camera_image(rightFile, rightImg, fs1);
00220
00221 if (leftImg == NULL || rightImg == NULL || !ok)
00222 return false;
00223
00224
00225 const Camera_Model& rightCM = rightImg->get_camera_model();
00226 Camera_Model *rightCopy = rightCM.clone();
00227
00228 Frame_l rightFrame = rightCM.get_frame();
00229 Frame_l leftFrame = leftImg->get_camera_model().get_frame();
00230 if (rightFrame.get_name() == leftFrame.get_name() && refFrame != "") {
00231
00232
00233
00234
00235
00236
00237
00238 Frame_l leftRef = fs->lookup(refFrame);
00239 Frame_l rightRef = fs1->lookup(refFrame);
00240 if (leftRef.is_empty() || rightRef.is_empty()) {
00241 delete rightCopy;
00242 delete fs1;
00243 delete leftImg;
00244 delete rightImg;
00245 delete fs;
00246 leftImg = rightImg = NULL;
00247 fs = NULL;
00248 return false;
00249 }
00250 Location leftCamLoc = leftRef.location_of(leftFrame);
00251 Location rightCamLoc = rightRef.location_of(rightFrame);
00252 if (leftCamLoc.get_translation() !=
00253 rightCamLoc.get_translation() ||
00254 leftCamLoc.get_rotation() !=
00255 rightCamLoc.get_rotation()) {
00256
00257
00258
00259
00260
00261
00262 std::string newRtFrameName = rightFrame.get_name() + ".stereo.right";
00263 Frame_l newRightFrame =
00264 fs->add_frame(newRtFrameName.c_str(), &leftRef, rightCamLoc);
00265 rightCopy->set_frame(newRightFrame);
00266 rightImg->set_camera_model(rightCopy);
00267 delete rightCopy;
00268 delete fs1;
00269 return false;
00270 }
00271 }
00272
00273
00274
00275 Frame_l lfsrparent = fs->lookup(rightFrame.get_parent().get_name());
00276 Location rcmloc = rightFrame.get_location();
00277 Frame_l lfsrframe = fs->lookup(rightFrame.get_name());
00278 lfsrframe.change_parent(lfsrparent);
00279 lfsrframe.set_location(rcmloc);
00280 rightCopy->set_frame(lfsrframe);
00281 rightImg->set_camera_model(rightCopy);
00282
00283 delete rightCopy;
00284 delete fs1;
00285 return true;
00286 }
00287
00288 #endif