34 int MultiMarker::pointcloud_index(
int marker_id,
int marker_corner,
bool add_if_missing ) {
35 return (get_id_index(marker_id ,add_if_missing)*4)+marker_corner;
38 int MultiMarker::get_id_index(
int id,
bool add_if_missing )
40 for(
size_t i = 0; i < marker_indices.size(); ++i) {
41 if(marker_indices.at(i) == id)
44 if (!add_if_missing)
return -1;
45 marker_indices.push_back(
id);
46 marker_status.push_back(0);
47 return (marker_indices.size()-1);
50 void MultiMarker::Reset()
52 fill(marker_status.begin(), marker_status.end(), 0);
56 bool MultiMarker::SaveXML(
const char* fname) {
57 TiXmlDocument document;
58 document.LinkEndChild(
new TiXmlDeclaration(
"1.0",
"UTF-8",
"no"));
59 document.LinkEndChild(
new TiXmlElement(
"multimarker"));
60 TiXmlElement *xml_root = document.RootElement();
63 xml_root->SetAttribute(
"markers", n_markers);
66 TiXmlElement *xml_marker =
new TiXmlElement(
"marker");
67 xml_root->LinkEndChild(xml_marker);
69 xml_marker->SetAttribute(
"index", marker_indices[i]);
70 xml_marker->SetAttribute(
"status", marker_status[i]);
72 for(
int j = 0; j < 4; ++j) {
73 TiXmlElement *xml_corner =
new TiXmlElement(
"corner");
74 xml_marker->LinkEndChild(xml_corner);
75 CvPoint3D64f X = pointcloud[pointcloud_index(marker_indices[i], j)];
76 xml_corner->SetDoubleAttribute(
"x", X.x);
77 xml_corner->SetDoubleAttribute(
"y", X.y);
78 xml_corner->SetDoubleAttribute(
"z", X.z);
81 return document.SaveFile(fname);
84 bool MultiMarker::SaveText(
const char* fname) {
87 fstream file_op(fname, ios::out);
89 file_op<<n_markers<<endl;
94 file_op<<marker_indices[i]<<endl;
99 file_op<<marker_status[i]<<endl;
104 for(
size_t j = 0; j < 4; ++j)
106 CvPoint3D64f X = pointcloud[pointcloud_index(marker_indices[i], j)];
107 file_op<<X.x<<
" "<<X.y<<
" "<<X.z<<endl;
118 return SaveXML(fname);
121 return SaveText(fname);
127 bool MultiMarker::LoadXML(
const char* fname) {
128 TiXmlDocument document;
129 if (!document.LoadFile(fname))
return false;
130 TiXmlElement *xml_root = document.RootElement();
133 if (xml_root->QueryIntAttribute(
"markers", &n_markers) != TIXML_SUCCESS)
return false;
136 marker_indices.resize(n_markers);
137 marker_status.resize(n_markers);
139 TiXmlElement *xml_marker = xml_root->FirstChildElement(
"marker");
141 if (!xml_marker)
return false;
144 if (xml_marker->QueryIntAttribute(
"index", &index) != TIXML_SUCCESS)
return false;
145 if (xml_marker->QueryIntAttribute(
"status", &status) != TIXML_SUCCESS)
return false;
146 marker_indices[i] = index;
147 marker_status[i] = status;
150 TiXmlElement *xml_corner = xml_marker->FirstChildElement(
"corner");
151 for(
int j = 0; j < 4; ++j) {
152 if (!xml_corner)
return false;
155 if (xml_corner->QueryDoubleAttribute(
"x", &X.x) != TIXML_SUCCESS)
return false;
156 if (xml_corner->QueryDoubleAttribute(
"y", &X.y) != TIXML_SUCCESS)
return false;
157 if (xml_corner->QueryDoubleAttribute(
"z", &X.z) != TIXML_SUCCESS)
return false;
158 pointcloud[pointcloud_index(marker_indices[i], j)] = X;
160 xml_corner = (TiXmlElement*)xml_corner->NextSibling(
"corner");
163 xml_marker = (TiXmlElement*)xml_marker->NextSibling(
"marker");
168 bool MultiMarker::LoadText(
const char* fname) {
169 fstream file_op(fname, ios::in);
179 marker_indices.resize(n_markers);
180 marker_status.resize(n_markers);
183 file_op>>marker_indices[i];
187 file_op>>marker_status[i];
191 for(
size_t j = 0; j < 4; ++j)
197 pointcloud[pointcloud_index(marker_indices[i], j)] = X;
208 return LoadXML(fname);
211 return LoadText(fname);
217 MultiMarker::MultiMarker(vector<int>& indices)
219 marker_indices.resize(indices.size());
220 copy(indices.begin(), indices.end(), marker_indices.begin());
221 marker_status.resize(indices.size());
222 fill(marker_status.begin(), marker_status.end(), 0);
225 void MultiMarker::PointCloudReset() {
229 void MultiMarker::PointCloudCorners3d(
double edge_length,
Pose &pose, CvPoint3D64f corners[4]) {
231 CvMat *m3 = cvCreateMat(4,4,CV_64F); cvSetIdentity(m3);
234 for(
size_t j = 0; j < 4; ++j)
238 double X_data[4] = {0, 0, 0, 1};
244 X_data[0] = +0.5*edge_length;
245 X_data[1] = -0.5*edge_length;
247 X_data[0] = +0.5*edge_length;
248 X_data[1] = +0.5*edge_length;
250 X_data[0] = -0.5*edge_length;
251 X_data[1] = +0.5*edge_length;
254 CvMat X = cvMat(4, 1, CV_64F, X_data);
255 cvMatMul(m3, &X, &X);
257 corners[j].x = X_data[0] / X_data[3];
258 corners[j].y = X_data[1] / X_data[3];
259 corners[j].z = X_data[2] / X_data[3];
264 void MultiMarker::PointCloudAdd(
int marker_id,
double edge_length,
Pose &pose) {
265 CvPoint3D64f corners[4];
266 PointCloudCorners3d(edge_length, pose, corners);
267 for(
size_t j = 0; j < 4; ++j) {
268 pointcloud[pointcloud_index(marker_id, j,
true)] = corners[j];
269 marker_status[get_id_index(marker_id,
true)]=1;
282 void MultiMarker::PointCloudGet(
int marker_id,
int point,
283 double &x,
double &y,
double &z) {
284 CvPoint3D64f p3d = pointcloud[pointcloud_index(marker_id, point)];
290 bool MultiMarker::IsValidMarker(
int marker_id) {
291 int idx = get_id_index(marker_id);
292 return idx != -1 && marker_status[idx] != 0;
297 vector<CvPoint3D64f> world_points;
298 vector<PointDouble> image_points;
301 for (
size_t i=0; i<marker_status.size(); i++) {
302 if (marker_status[i] > 0) marker_status[i]=1;
308 const Marker* marker = *i;
309 int id = marker->
GetId();
310 int index = get_id_index(
id);
311 if (index < 0)
continue;
314 if (marker_status[index] > 0) {
317 CvPoint3D64f Xnew = pointcloud[pointcloud_index(
id, (
int)j)];
318 world_points.push_back(Xnew);
322 marker_status[index] = 2;
326 if (world_points.size() < 4)
return -1;
328 double rod[3], tra[3];
329 CvMat rot_mat = cvMat(3, 1,CV_64F, rod);
330 CvMat tra_mat = cvMat(3, 1,CV_64F, tra);
342 for(
size_t i = 0; i < marker_indices.size(); ++i) {
343 int id = marker_indices[i];
345 if (marker_status[i] == 1) {
346 vector<CvPoint3D64f> pw(4);
347 pw[0] = pointcloud[pointcloud_index(
id, 0)];
348 pw[1] = pointcloud[pointcloud_index(
id, 1)];
349 pw[2] = pointcloud[pointcloud_index(
id, 2)];
350 pw[3] = pointcloud[pointcloud_index(
id, 3)];
351 vector<CvPoint2D64f> pi(4);
363 cvLine(image, cvPoint(
int(p[0].
x),
int(p[0].
y)), cvPoint(
int(p[1].x),
int(p[1].y)), CV_RGB(255,0,0));
364 cvLine(image, cvPoint(
int(p[1].x),
int(p[1].y)), cvPoint(
int(p[2].x),
int(p[2].y)), CV_RGB(255,0,0));
365 cvLine(image, cvPoint(
int(p[2].x),
int(p[2].y)), cvPoint(
int(p[3].x),
int(p[3].y)), CV_RGB(255,0,0));
366 cvLine(image, cvPoint(
int(p[3].x),
int(p[3].y)), cvPoint(
int(p[0].x),
int(p[0].y)), CV_RGB(255,0,0));
Plain ASCII text file format.
std::vector< PointDouble > marker_corners_img
Marker corners in image coordinates.
virtual unsigned long GetId() const
Get id for this marker This is used e.g. in MarkerDetector to associate a marker id with an appropria...
std::vector< int > marker_status
Base class for using MultiMarker.
TFSIMD_FORCE_INLINE const tfScalar & y() const
Templateless version of MarkerDetector. Please use MarkerDetector instead.
std::map< int, CvPoint3D64f > pointcloud
std::vector< int > marker_indices
void TrackMarkersReset()
Clear the markers that are tracked.
Simple Camera class for calculating distortions, orientation or projections with pre-calibrated camer...
void ProjectPoints(std::vector< CvPoint3D64f > &pw, Pose *pose, std::vector< CvPoint2D64f > &pi) const
Project points.
Pose representation derived from the Rotation class
TFSIMD_FORCE_INLINE const tfScalar & x() const
Basic 2D Marker functionality.
void SetRodriques(const CvMat *mat)
Sets the rotation from given rotation vector.
MarkerDetector< MarkerData > marker_detector
Iterator type for traversing templated Marker vector without the template.
This file implements a multi-marker.
void GetMatrix(CvMat *mat) const
ALVAR_EXPORT Point< CvPoint2D64f > PointDouble
The default double point type.
void CalcExteriorOrientation(std::vector< CvPoint3D64f > &pw, std::vector< CvPoint2D64f > &pi, Pose *pose)
Calculate exterior orientation.
void TrackMarkerAdd(int id, PointDouble corners[4])
Add markers to be tracked Sometimes application or e.g. the MultiMarker implementation knows more abo...
void SetTranslation(const CvMat *tra)
virtual MarkerIterator & reset()=0
This file defines library export definitions, version numbers and build information.
std::vector< PointDouble > marker_corners
Marker corners in marker coordinates.