예제 #1
0
/* Make match lists symmetric */
void BaseApp::MakeMatchListsSymmetric() 
{
    unsigned int num_images = GetNumImages();

    std::vector<MatchIndex> matches;

    for (unsigned int i = 0; i < num_images; i++) {
        MatchAdjList::const_iterator iter;
        for (iter = m_matches.Begin(i); iter != m_matches.End(i); iter++) {
            // unsigned int i = iter->first;
            unsigned int j = iter->m_index; // iter->second;

            if (j <= i)
                continue;

            assert(ImagesMatch(i, j));   

            // MatchIndex idx = *iter; 
            MatchIndex idx = GetMatchIndex(i, j);
            MatchIndex idx_rev = GetMatchIndex(j, i);
            // int num_matches = (int) m_match_lists[idx].size();

            const std::vector<KeypointMatch> &list = iter->m_match_list;
            unsigned int num_matches = list.size();

            // m_match_lists[idx_rev].clear();
            m_matches.SetMatch(idx_rev);
            m_matches.ClearMatch(idx_rev);

            for (unsigned int k = 0; k < num_matches; k++) {
                KeypointMatch m1, m2;
		
                m1 = list[k];
                
                m2.m_idx1 = m1.m_idx2;
                m2.m_idx2 = m1.m_idx1;

                // m_match_lists[idx_rev].push_back(m2);
                m_matches.AddMatch(idx_rev, m2);
            }

            matches.push_back(idx);
        }
    }
    
    unsigned int num_matches = matches.size();

    for (unsigned int i = 0; i < num_matches; i++) {
        unsigned int img1 = matches[i].first;
        unsigned int img2 = matches[i].second;
        SetMatch(img2, img1);
    }

    matches.clear();
}
/* Compute epipolar geometry between all matching images */
void BundlerApp::ComputeEpipolarGeometry(bool removeBadMatches, 
                                         int new_image_start) 
{
    unsigned int num_images = GetNumImages();
    
    m_transforms.clear();

    std::vector<MatchIndex> remove;

    for (unsigned int i = 0; i < num_images; i++) {
        MatchAdjList::iterator iter;

        for (iter = m_matches.Begin(i); iter != m_matches.End(i); iter++) {
            unsigned int j = iter->m_index; // first;

            assert(ImagesMatch(i, j));

            MatchIndex idx = GetMatchIndex(i, j);
            MatchIndex idx_rev = GetMatchIndex(j, i);

            bool connect12 = 
                ComputeEpipolarGeometry(i, j, removeBadMatches);

            if (!connect12) {
                if (removeBadMatches) {
                    // RemoveMatch(i, j);
                    // RemoveMatch(j, i);
                    remove.push_back(idx);
                    remove.push_back(idx_rev);

                    // m_match_lists[idx].clear();
                    // m_match_lists.erase(idx);

                    m_transforms.erase(idx);
                    m_transforms.erase(idx_rev);
                }
            } else {
                matrix_transpose(3, 3, 
                                 m_transforms[idx].m_fmatrix, 
                                 m_transforms[idx_rev].m_fmatrix);
            }
        }
    }

    int num_removed = (int) remove.size();
    
    for (int i = 0; i < num_removed; i++) {
        int img1 = remove[i].first;
        int img2 = remove[i].second;

        // RemoveMatch(img1, img2);
        m_matches.RemoveMatch(GetMatchIndex(img1, img2));
    }
}
예제 #3
0
void BaseApp::WriteMatchTable(const char *append) 
{
    int num_images = GetNumImages();

    char buf[256];
    sprintf(buf, "nmatches%s.txt", append);
    FILE *f0 = fopen(buf, "w");

    sprintf(buf, "matches%s.txt", append);
    FILE *f1 = fopen(buf, "w");
    
    if (f0 == NULL || f1 == NULL) {
        printf("[WriteMatchTable] "
               "Error opening files for writing.\n");
        return;
    }

    fprintf(f0, "%d\n", num_images);

    for (int i = 0; i < num_images; i++) {
        for (int j = 0; j < num_images; j++) {
            if (i >= j) {
                fprintf(f0, "0 ");
                fprintf(f1, "\n");
            } else {
                if (ImagesMatch(i, j)) {
                    MatchIndex idx = GetMatchIndex(i, j);
                    std::vector<KeypointMatch> &list = 
                        m_matches.GetMatchList(idx);

                    unsigned int num_matches = list.size();

                    fprintf(f0, "%d ", num_matches);
                    
                    for (unsigned int k = 0; k < num_matches; k++) {
                        KeypointMatch m = list[k];
                        fprintf(f1, "%d %d ", m.m_idx1, m.m_idx2);    
                    }
                    fprintf(f1, "\n");
                } else {
                    fprintf(f0, "0 ");
                }
            }
        }

        fprintf(f0, "\n");
    }

    fclose(f0);
    fclose(f1);
}
void BundlerApp::ComputeGeometricConstraints(bool overwrite, 
                                             int new_image_start) 
{
    int num_images = GetNumImages();

    /* Read information from files if they exist */
    const char *filename = "constraints.txt";
    if (!overwrite && FileExists(filename)) {
		ReadGeometricConstraints(filename);
        return;
    } else {
        LoadMatches();

        if (num_images < 40000) 
            WriteMatchTable(".prune");

        if (!m_skip_fmatrix || !m_skip_homographies || 
            m_keypoint_border_width > 0 || m_keypoint_border_bottom > 0)
            LoadKeys(false);

        if (m_keypoint_border_width > 0) {
            for (int i = 0; i < num_images; i++) {
                for (int j = i+1; j < num_images; j++) {
                    if (!ImagesMatch(i, j))
                        continue;

                    RemoveMatchesNearBorder(i, j, m_keypoint_border_width);
                }
            }
        }

        if (m_keypoint_border_bottom > 0) {
            for (int i = 0; i < num_images; i++) {
                for (int j = i+1; j < num_images; j++) {
                    if (!ImagesMatch(i, j))
                        continue;

                    RemoveMatchesNearBottom(i, j, m_keypoint_border_bottom);
                }
            }
        }

        if (!m_skip_fmatrix) {
            ComputeEpipolarGeometry(true, new_image_start);
        }

        if (!m_skip_homographies) {
            ComputeTransforms(false, new_image_start);
        }

		MakeMatchListsSymmetric();

        if (num_images < 40000)
            WriteMatchTable(".ransac");

        // RemoveAllMatches();
		ComputeTracks(new_image_start);

        // ClearMatches();
        RemoveAllMatches();
        // SetMatchesFromTracks();

#if 1
        /* Set match flags */
        int num_tracks = (int) m_track_data.size();
        for (int i = 0; i < num_tracks; i++) {
            TrackData &track = m_track_data[i];
            int num_views = (int) track.m_views.size();

            for (int j = 0; j < num_views; j++) {
                int img1 = track.m_views[j].first;

                assert(img1 >= 0 && img1 < num_images);

                for (int k = j+1; k < num_views; k++) {
                    int img2 = track.m_views[k].first;

                    assert(img2 >= 0 && img2 < num_images);
                    
                    SetMatch(img1, img2);
                    SetMatch(img2, img1);
                }
            }
        }
#endif

        WriteGeometricConstraints(filename);

        if (num_images < 40000)
            WriteMatchTable(".corresp");
    }
}
/* Compute rigid transforms between all matching images */
void BundlerApp::ComputeTransforms(bool removeBadMatches, int new_image_start) 
{
    unsigned int num_images = GetNumImages();

    m_transforms.clear();

    for (unsigned int i = 0; i < num_images; i++) {
        MatchAdjList::iterator iter;
        for (iter = m_matches.Begin(i); iter != m_matches.End(i); iter++) {
            unsigned int j = iter->m_index;

            assert(ImagesMatch(i, j));

            MatchIndex idx = GetMatchIndex(i, j);
            MatchIndex idx_rev = GetMatchIndex(j, i);

            m_transforms[idx] = TransformInfo();
            m_transforms[idx_rev] = TransformInfo();

            bool connect12 = ComputeTransform(i, j, removeBadMatches);

            if (!connect12) {
                if (removeBadMatches) {
                    // RemoveMatch(i, j);
                    // RemoveMatch(j, i);

                    // m_match_lists[idx].clear();
                    m_matches.RemoveMatch(idx);
                    m_matches.RemoveMatch(idx_rev);
                    // m_match_lists.erase(idx);

                    m_transforms.erase(idx);
                    m_transforms.erase(idx_rev);
                }
            } else {
                matrix_invert(3, m_transforms[idx].m_H, 
                              m_transforms[idx_rev].m_H);
            }
        }
    }

    /* Print the inlier ratios */
    FILE *f = fopen("pairwise_scores.txt", "w");
    
    for (unsigned int i = 0; i < num_images; i++) {
        MatchAdjList::iterator iter;

        for (iter = m_matches.Begin(i); iter != m_matches.End(i); iter++) {
            unsigned int j = iter->m_index; // first;
 
            assert(ImagesMatch(i, j));

            // MatchIndex idx = *iter;
            MatchIndex idx = GetMatchIndex(i, j);
            fprintf(f, "%d %d %0.5f\n", i, j, 
                    m_transforms[idx].m_inlier_ratio);
        }
    }

    fclose(f);
}