//1. find interesting 2d points, 2. find their corresponding 3d points corresponding to the transformation defined by the "actor" //3. transform the 3d points to the original by using the inverse of the "actor" void vtkTimerCallbackSnapshot::process_image(const std::string & img_name, vtkRenderer * ren, vtkActor * actor, int ino) { //1. find interesting 2d location cv::Mat img = cv::imread(img_name); std::vector<cv::KeyPoint> kpts; cv::Mat descriptors_local, descriptors_local_good; cv::Ptr<cv::FeatureDetector> fdetector = cv::xfeatures2d::SIFT::create(); fdetector->detect(img, kpts); fdetector->compute(img, kpts, descriptors_local); //2. find the corresponding 3d points for each 2d location std::vector<std::pair<cv::Point3f, cv::KeyPoint> > pairs_local; for(size_t i = 0; i < kpts.size(); ++i) { //find 2d vtkSmartPointer<vtkPropPicker> picker = vtkSmartPointer<vtkPropPicker>::New(); picker->Pick(kpts[i].pt.x, img.rows - kpts[i].pt.y, 0, ren); //IMPORTANT: note that the y coordinate is converted from pixel coordinates to picking coordinates //find transformed 3d double * pos = picker->GetPickPosition(); //3 find original 3d vtkMatrix4x4 * curr_transform_inv = vtkMatrix4x4::New(); vtkMatrix4x4::Invert(actor->GetMatrix(), curr_transform_inv); double * pos_model = curr_transform_inv->MultiplyDoublePoint(pos); //std::cout << "2D position is: " << kpts[i].pt.x << " " << kpts[i].pt.x << std::endl; //std::cout << "3d position (world coordinates) is: " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl << endl; if(valid_3D_point(pos)) { pairs_local.push_back(std::make_pair(cv::Point3f(pos_model[0], pos_model[1], pos_model[2]), kpts[i])); descriptors_local_good.push_back(descriptors_local.row(i)); //updating extra globals! map_3d_2d[cv::Point3f(pos_model[0], pos_model[1], pos_model[2])] = kpts[i]; } } //updating globals pairs_3d_2d.insert(pairs_3d_2d.end(), pairs_local.begin(), pairs_local.end()); common_descriptors.push_back(descriptors_local_good); //writing a local set write_pairs(pairs_local, descriptors_local_good, input_dir + std::string("/local") + std::to_string(ino) + std::string(".pairs")); write_pairs_xml(pairs_local, descriptors_local_good, input_dir + std::string("/local") + std::to_string(ino) + std::string(".xml")); std::cout << "Processed view " << ino << std::endl; }
/** * Write an MVD out as text. If there are angle brackets or * ampersands in the text, these are automatically escaped * as entities * @param mvd the source multi-version document * @param dst the destination MVD JSON file * @param encoding the desired encoding of the output * (not that of the source mvd) * @param srcEncoding the encoding of the data in the MVD * @param pretty if true make some attempt at tidying the output * @throws an exception if it couldn't write the file or find a * serialiser */ int mvd_json_externalise( MVD *mvd, char *dst, char *encoding ) { int res = 1; dom_item *root = dom_object_create( "mvd" ); if ( root != NULL ) { char *desc = to_utf8( mvd_description(mvd), mvd_get_description_len(mvd) ); if ( desc != NULL ) { dom_attribute *attr = dom_attribute_create( "description", desc ); if ( attr != NULL ) { res = dom_add_attribute( root, attr ); if ( res ) res = dom_add_attribute( root, dom_attribute_create( "encoding", mvd_get_encoding(mvd)) ); if ( res ) res = write_versions( root, mvd ); if ( res ) res = write_pairs( root, mvd, mvd_get_encoding(mvd) ); if ( res ) { FILE *DST = fopen( dst, "w" ); if ( DST != NULL ) { res = dom_externalise( root, DST ); dom_item_dispose( root ); fclose( DST ); } else res = 0; } } else res = 0; } else res = 0; } else res = 0; return res; }
void vtkTimerCallbackSnapshot::Execute(vtkObject * caller, unsigned long eventId, void * vtkNotUsed(callData)) { vtkRenderWindowInteractor * iren = vtkRenderWindowInteractor::SafeDownCast(caller); if(!this->snap_mode) return; if(vtkCommand::TimerEvent == eventId) { ++this->snap_count_; } //no need to do extra processing if we have enough snaps if(this->snap_count_ >= NO_SNAPSHOTS) { this->snap_mode = false; //after getting all snaps, write everything together cout << "Processing finished... Writing the final descriptors" << endl; std::string filename = boost::filesystem::path(input_file).filename().replace_extension(feature_type + "." + output_extension).c_str(); fileutils::createTrainingDir(output_dir); write_pairs(pairs_3d_2d, common_descriptors, output_dir + "/" + filename); write_pairs_xml(pairs_3d_2d, common_descriptors, output_dir + "/" + filename); //delete and remove everything iren->TerminateApp(); pairs_3d_2d.clear(); } //MAIN CALLBACK, take snapshot, find features for the data from current actor process(iren, actor, renderer, snap_count_); //update data with the actor actor->RotateY(360 / NO_SNAPSHOTS); iren->GetRenderWindow()->Render(); }