Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
00066
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
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
00106 found_new = updateMarkerPoses(markers, pose);
00107 }
00108 }
00109 }
00110
00111
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
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
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 }