//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;
    }
Пример #2
0
/**
 * 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();
    }