void stereoview::save_image(logger& l, const image_id_type& id, const QString& filepath, int quality) const { const option<QSize>& rs = rescale(); const auto stimg = access_stored_image(id).atomic(); const auto&& qimg = stimg->image(rs); l.msg(nfmt<5>("saving image ID:%1 with quality %2 at %3x%4 to file %5...") (id) (quality) (qimg.width()) (qimg.height()) (filepath)); if (!qimg.save(filepath, NULL, quality)) l.msg(nfmt<0>("ERROR: cannot save image to disk.")); }
void stereoview::parse_siftpp_keyfile(logger& l, progress_tracker&&, const image_id_type& id, const QString& filepath, const std::function<float(float)>& adapt_scale, const std::function<float(float)>& adapt_rot, const std::function<float(unsigned int)>& adapt_descr) { QString&& ins = read_file_for_parsing(filepath); QTextStream s(&ins); l.msg(nfmt<1>("parsing SIFT++ keyfile '%1' with 128-dimesional descriptor...") (filepath)); auto sl = access_stored_image(id).atomic(); auto& stimg = *sl; // get the number of features unsigned int n_keyp = 0; { std::ifstream siftfile(filepath.toStdString().c_str()); std::string dump; while(getline(siftfile,dump)) { ++n_keyp; } siftfile.close(); } // parse the .sift file stimg.keypoints.clear(); for (size_t cnt = 0; cnt < n_keyp; ++cnt) { if (is_parse_stream_past_end(s, filepath)) { l.msg(HERE(nfmt<2>("end of stream reached while parsing '%1': %2 keypoints stored") (filepath) (cnt))); return; } keypoint128 kp; float scale, rot; s >> kp.x >> kp.y >> scale >> rot; kp.scale = adapt_scale(scale); kp.rotation = adapt_rot(rot); for (size_t di = 0; di < 128; ++di) { unsigned int x; s >> x; kp.descriptor[di] = adapt_descr(x); } stimg.keypoints.append(kp); } // next feature }
void stereoview::parse_keyfile(logger& l, progress_tracker&& prog, const image_id_type& id, const QString& filepath, const std::function<float(float)>& adapt_scale, const std::function<float(float)>& adapt_rot, const std::function<float(float)>& adapt_descr) { QString&& ins = read_file_for_parsing(filepath); QTextStream s(&ins); unsigned int expected_keypoints, descr_dim; s >> expected_keypoints >> descr_dim; check_parse_stream_not_past_end(s, filepath); if (descr_dim != keypoint128::descriptor_dim) throw localized_runtime_error(HERE(nfmt<2>("descriptor dimension in keyfile '%1' is %2 while 128 was expected") (filepath) (descr_dim))); l.msg(nfmt<3>("parsing keyfile '%1': %2 keypoints with %3-dimesional descriptor...") (filepath) (expected_keypoints) (descr_dim)); { auto sl = access_stored_image(id).atomic(); auto& stimg = *sl; stimg.keypoints.clear(); auto stepper = prog.section(expected_keypoints); for (size_t i = 0; i < expected_keypoints; ++i) { keypoint128 kp; float scale, rot; s >> kp.y >> kp.x >> scale >> rot; kp.scale = adapt_scale(scale); kp.rotation = adapt_rot(rot); for (size_t di = 0; di < descr_dim; ++di) { float x; s >> x; kp.descriptor[di] = adapt_descr(x); } check_parse_stream_not_past_end(s, filepath); stimg.keypoints.append(kp); ++stepper; } } }
void stereoview::generate_keyfiles(logger& l, progress_tracker&& prog, const QVector<image_id_type>& imgids, const QDir& outdir, const QString& listfilepath, const std::function<QString(float)>& pretty_descr) const { QFile listf(listfilepath); if (!listf.open(QFile::WriteOnly | QIODevice::Text | QFile::Truncate)) throw localized_runtime_error(HERE(nfmt<1>("cannot open keyfile list file for writing: %1") (QFileInfo(listf).absoluteFilePath()))); QTextStream ls(&listf); auto imgstepper = prog.section(imgids.size()); foreach (const auto& id, imgids) { auto sl = access_stored_image(id).atomic(); const auto& kps = sl->keypoints; if (kps.isEmpty()) throw localized_invalid_argument(HERE(nfmt<1>("keypoints of image ID:%1 must be detected for tracking to make effect")(id))); const QString keyfilename = nfmt<1>("%1.key") (id); QFile f(outdir.absoluteFilePath(keyfilename)); if(!f.open(QFile::WriteOnly | QIODevice::Text | QFile::Truncate)) throw localized_runtime_error(HERE(nfmt<1>("cannot open keyfile for writing: %1") (QFileInfo(f).absoluteFilePath()))); l.msg(nfmt<2>("generating keyfile '%1' (%2 keypoints)...") (f.fileName()) (kps.size())); QTextStream s(&f); s << kps.size() << " " << keypoint128::descriptor_dim << uendl; auto kpstepper = imgstepper.sub().section(kps.size()); foreach (const auto& kp, kps) { s << kp.y << " " << kp.x << " " << kp.scale << " " << kp.rotation; for (size_t i = 0; i < keypoint128::descriptor_dim; ++i) { // follow indentation if (i % 20 == 0) s << uendl; s << " " << pretty_descr(kp.descriptor[i]); } s << uendl; ++kpstepper; }
static option<float> extract_focal_length_from_image(logger& l, const QString& path, float ccd_width) { //return some((3310.4 + 3325.5) / 2.); // dino ring return some(810.); // stereo experiments (ueye 640x512) float r; const auto&& c = extract_focal_length(path.toStdString().c_str(), &r, ccd_width); switch (c) { case FOCAL_LENGTH_OK: l.msg(nfmt<3>("EXIF chunk specifies focal length = %2 / CCD width = %3 for image file '%1'") (path) (r) (ccd_width)); return some(r); case FOCAL_LENGTH_INVALID_EXIF: l.critical(nfmt<1>("invalid EXIF chunk in image file '%1'") (path)); return none; case FOCAL_LENGTH_NO_CCD_DATA: l.critical(nfmt<1>("cannot find CCD data in image '%1'") (path)); return none; default: l.unexpected_error(HERE(nfmt<1>("unknown return code %1") (c))); return none; } }