MultiMarkerInitializer.cpp
Go to the documentation of this file.
00001 /*
00002  * This file is part of ALVAR, A Library for Virtual and Augmented Reality.
00003  *
00004  * Copyright 2007-2012 VTT Technical Research Centre of Finland
00005  *
00006  * Contact: VTT Augmented Reality Team <alvar.info@vtt.fi>
00007  *          <http://www.vtt.fi/multimedia/alvar.html>
00008  *
00009  * ALVAR is free software; you can redistribute it and/or modify it under the
00010  * terms of the GNU Lesser General Public License as published by the Free
00011  * Software Foundation; either version 2.1 of the License, or (at your option)
00012  * any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful, but WITHOUT
00015  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00017  * for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public License
00020  * along with ALVAR; if not, see
00021  * <http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>.
00022  */
00023 
00024 #include "ar_track_alvar/MultiMarkerInitializer.h"
00025 #include <Eigen/StdVector>
00026 
00027 using namespace std;
00028 
00029 namespace alvar {
00030 using namespace std;
00031 
00032 MultiMarkerInitializer::MultiMarkerInitializer(std::vector<int>& indices, int _filter_buffer_min, int _filter_buffer_max)
00033         : MultiMarker(indices), filter_buffer_min(_filter_buffer_min) {
00034 
00035         marker_detected.resize(indices.size());
00036         pointcloud_filtered = new FilterMedian[indices.size()*4*3];
00037         for (size_t i=0; i<indices.size()*4*3; i++) {
00038                 pointcloud_filtered[i].setWindowSize(_filter_buffer_max);
00039         }
00040 
00041         MeasurementsReset();
00042 }
00043 
00044 void MultiMarkerInitializer::MeasurementsAdd(MarkerIterator &begin, MarkerIterator &end) {
00045         // copy markers into measurements.
00046         vector<MarkerMeasurement, Eigen::aligned_allocator<MarkerMeasurement> > new_measurements;
00047         for (MarkerIterator &i = begin.reset(); i != end; ++i) {
00048                 const Marker* marker = *i;
00049                 int index = get_id_index(marker->GetId()); 
00050                 if (index == -1) continue;
00051                 MarkerMeasurement m;
00052                 m.SetId(marker->GetId());
00053                 m.SetMarkerSize(marker->GetMarkerEdgeLength(), marker->GetRes(), marker->GetMargin());
00054                 m.pose = marker->pose;
00055                 m.marker_corners_img = i->marker_corners_img;
00056                 new_measurements.push_back(m);
00057                 marker_detected[index] = true;
00058         }
00059 
00060         // If we have seen the 0 marker the first time we push it into point could.
00061         for (MarkerIterator &i = begin.reset(); i != end; ++i) {
00062                 const Marker* marker = *i;
00063                 int id = marker->GetId();
00064                 int index = get_id_index(id);
00065                 // Initialize marker pose
00066                 //if (id == 0 && marker_status[index] == 0)
00067                 if (index == 0 && marker_status[index] == 0)
00068                 {
00069                         Pose pose;
00070                         CvPoint3D64f corners[4];
00071                         PointCloudCorners3d(marker->GetMarkerEdgeLength(), pose, corners);
00072                         for(size_t j = 0; j < 4; ++j) {
00073                                 int p_index = pointcloud_index(id, j);
00074                                 pointcloud[p_index] = corners[j];
00075                         }
00076                         marker_status[index] = 1;
00077                 }
00078         }
00079 
00080         measurements.push_back(new_measurements);
00081 }
00082 
00083 void MultiMarkerInitializer::MeasurementsReset() {
00084         measurements.clear();
00085         PointCloudReset();
00086         fill(marker_status.begin(), marker_status.end(), 0);
00087         fill(marker_detected.begin(), marker_detected.end(), false);
00088 
00089         for (size_t i=0; i<marker_indices.size()*4*3; i++) {
00090                 pointcloud_filtered[i].reset();
00091         }
00092 }
00093 
00094 int MultiMarkerInitializer::Initialize(Camera* cam) {
00095         for (bool found_new = true; found_new; ) {
00096                 found_new = false;
00097                 // Iterate through all measurements, try to compute Pose for each.
00098                 for (MeasurementIterator mi = measurements.begin(); mi != measurements.end(); ++mi) {
00099                         vector<MarkerMeasurement, Eigen::aligned_allocator<MarkerMeasurement> > &markers = *mi;
00100                         Pose pose;
00101                         MarkerIteratorImpl<MarkerMeasurement> m_begin(markers.begin());
00102                         MarkerIteratorImpl<MarkerMeasurement> m_end(markers.end());
00103                         double err = _GetPose(m_begin, m_end, cam, pose, NULL);
00104                         if (err >= 0) {
00105                                 // If pose is found, estimate marker poses for those that are still unkown.
00106                                 found_new = updateMarkerPoses(markers, pose);
00107                         }
00108                 }
00109         }
00110 
00111         // Check if every marker has been seen
00112         int n_detected = 0;
00113         for (unsigned int i = 0; i < marker_indices.size(); ++i) {
00114                 cout << i << " " << marker_detected[i] << " " << marker_status[i] << "\n";
00115                 if (marker_detected[i] && marker_status[i] != 0) ++n_detected;
00116         }
00117         return n_detected;
00118 }
00119 
00120 bool MultiMarkerInitializer::updateMarkerPoses(vector<MarkerMeasurement, Eigen::aligned_allocator<MarkerMeasurement> > &markers, const Pose &pose) {
00121         bool found_new = false;
00122         for (vector<MarkerMeasurement, Eigen::aligned_allocator<MarkerMeasurement> >::iterator i = markers.begin(); i != markers.end(); ++i) {
00123                 MarkerMeasurement &marker = *i;
00124                 int id = marker.GetId();
00125                 int index = get_id_index(id);
00126                 if (index > 0 && !marker.globalPose) {
00127                         // Compute absolute marker pose.
00128                         double cam_posed[16];
00129                         double mar_posed[16];
00130                         CvMat cam_mat = cvMat(4, 4, CV_64F, cam_posed);
00131                         CvMat mar_mat = cvMat(4, 4, CV_64F, mar_posed);
00132                         pose.GetMatrix(&cam_mat);
00133                         marker.pose.GetMatrix(&mar_mat);
00134                         cvInvert(&cam_mat, &cam_mat);
00135                         cvMatMul(&cam_mat, &mar_mat, &mar_mat);
00136                         marker.pose.SetMatrix(&mar_mat);
00137                         // Put marker into point cloud
00138                         CvPoint3D64f corners[4];
00139                         PointCloudCorners3d(marker.GetMarkerEdgeLength(), marker.pose, corners);
00140                         for(size_t j = 0; j < 4; ++j) {
00141                                 CvPoint3D64f p;
00142                                 int p_index = pointcloud_index(id, j);
00143                                 p.x = pointcloud_filtered[3*p_index+0].next(corners[j].x);
00144                                 p.y = pointcloud_filtered[3*p_index+1].next(corners[j].y);
00145                                 p.z = pointcloud_filtered[3*p_index+2].next(corners[j].z);
00146                                 if (pointcloud_filtered[3*p_index+0].getCurrentSize() >= filter_buffer_min) {
00147                                         pointcloud[p_index] = p;
00148                                         marker_status[index] = 1;
00149                                 }
00150                         }
00151                         marker.globalPose = 1;
00152                         found_new = true;
00153                 }
00154         }
00155         return found_new;
00156 }
00157 
00158 } // namespace alvar


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Thu Jun 6 2019 21:12:54