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 "MultiMarkerInitializer.h"
00025
00026 using namespace std;
00027
00028 namespace alvar {
00029 using namespace std;
00030
00031 MultiMarkerInitializer::MultiMarkerInitializer(std::vector<int>& indices, int _filter_buffer_min, int _filter_buffer_max)
00032 : MultiMarker(indices), filter_buffer_min(_filter_buffer_min) {
00033
00034 marker_detected.resize(indices.size());
00035 pointcloud_filtered = new FilterMedian[indices.size()*4*3];
00036 for (size_t i=0; i<indices.size()*4*3; i++) {
00037 pointcloud_filtered[i].setWindowSize(_filter_buffer_max);
00038 }
00039
00040 MeasurementsReset();
00041 }
00042
00043 void MultiMarkerInitializer::MeasurementsAdd(MarkerIterator &begin, MarkerIterator &end) {
00044
00045 vector<MarkerMeasurement> new_measurements;
00046 for (MarkerIterator &i = begin.reset(); i != end; ++i) {
00047 const Marker* marker = *i;
00048 int index = get_id_index(marker->GetId());
00049 if (index == -1) continue;
00050 MarkerMeasurement m;
00051 m.SetId(marker->GetId());
00052 m.SetMarkerSize(marker->GetMarkerEdgeLength(), marker->GetRes(), marker->GetMargin());
00053 m.pose = marker->pose;
00054 m.marker_corners_img = i->marker_corners_img;
00055 new_measurements.push_back(m);
00056 marker_detected[index] = true;
00057 }
00058
00059
00060 for (MarkerIterator &i = begin.reset(); i != end; ++i) {
00061 const Marker* marker = *i;
00062 int id = marker->GetId();
00063 int index = get_id_index(id);
00064
00065
00066 if (index == 0 && marker_status[index] == 0)
00067 {
00068 Pose pose;
00069 CvPoint3D64f corners[4];
00070 PointCloudCorners3d(marker->GetMarkerEdgeLength(), pose, corners);
00071 for(size_t j = 0; j < 4; ++j) {
00072 int p_index = pointcloud_index(id, j);
00073 pointcloud[p_index] = corners[j];
00074 }
00075 marker_status[index] = 1;
00076 }
00077 }
00078
00079 measurements.push_back(new_measurements);
00080 }
00081
00082 void MultiMarkerInitializer::MeasurementsReset() {
00083 measurements.clear();
00084 PointCloudReset();
00085 fill(marker_status.begin(), marker_status.end(), 0);
00086 fill(marker_detected.begin(), marker_detected.end(), false);
00087
00088 for (size_t i=0; i<marker_indices.size()*4*3; i++) {
00089 pointcloud_filtered[i].reset();
00090 }
00091 }
00092
00093 int MultiMarkerInitializer::Initialize(Camera* cam) {
00094 for (bool found_new = true; found_new; ) {
00095 found_new = false;
00096
00097 for (MeasurementIterator mi = measurements.begin(); mi != measurements.end(); ++mi) {
00098 vector<MarkerMeasurement> &markers = *mi;
00099 Pose pose;
00100 MarkerIteratorImpl<MarkerMeasurement> m_begin(markers.begin());
00101 MarkerIteratorImpl<MarkerMeasurement> m_end(markers.end());
00102 double err = _GetPose(m_begin, m_end, cam, pose, NULL);
00103 if (err >= 0) {
00104
00105 found_new = updateMarkerPoses(markers, pose);
00106 }
00107 }
00108 }
00109
00110
00111 int n_detected = 0;
00112 for (unsigned int i = 0; i < marker_indices.size(); ++i) {
00113 cout << i << " " << marker_detected[i] << " " << marker_status[i] << "\n";
00114 if (marker_detected[i] && marker_status[i] != 0) ++n_detected;
00115 }
00116 return n_detected;
00117 }
00118
00119 bool MultiMarkerInitializer::updateMarkerPoses(vector<MarkerMeasurement> &markers, const Pose &pose) {
00120 bool found_new = false;
00121 for (vector<MarkerMeasurement>::iterator i = markers.begin(); i != markers.end(); ++i) {
00122 MarkerMeasurement &marker = *i;
00123 int id = marker.GetId();
00124 int index = get_id_index(id);
00125 if (index > 0 && !marker.globalPose) {
00126
00127 double cam_posed[16];
00128 double mar_posed[16];
00129 CvMat cam_mat = cvMat(4, 4, CV_64F, cam_posed);
00130 CvMat mar_mat = cvMat(4, 4, CV_64F, mar_posed);
00131 pose.GetMatrix(&cam_mat);
00132 marker.pose.GetMatrix(&mar_mat);
00133 cvInvert(&cam_mat, &cam_mat);
00134 cvMatMul(&cam_mat, &mar_mat, &mar_mat);
00135 marker.pose.SetMatrix(&mar_mat);
00136
00137 CvPoint3D64f corners[4];
00138 PointCloudCorners3d(marker.GetMarkerEdgeLength(), marker.pose, corners);
00139 for(size_t j = 0; j < 4; ++j) {
00140 CvPoint3D64f p;
00141 int p_index = pointcloud_index(id, j);
00142 p.x = pointcloud_filtered[3*p_index+0].next(corners[j].x);
00143 p.y = pointcloud_filtered[3*p_index+1].next(corners[j].y);
00144 p.z = pointcloud_filtered[3*p_index+2].next(corners[j].z);
00145 if (pointcloud_filtered[3*p_index+0].getCurrentSize() >= filter_buffer_min) {
00146 pointcloud[p_index] = p;
00147 marker_status[index] = 1;
00148 }
00149 }
00150 marker.globalPose = 1;
00151 found_new = true;
00152 }
00153 }
00154 return found_new;
00155 }
00156
00157 }