BitmapToolkit Scol plugin
ArMarker.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25#include "sService.h"
26#include "ArMarker.h"
27#include "ArManager.h"
28
29ArMarker::ArMarker(unsigned int nid, float markerSize, MarkerType type) : aruco::Marker()
30{
31 id = nid;
32 m_type = type;
33 m_needUpdate = false;
34 m_visible = false;
35 m_size = markerSize;
36 m_lastReverse = false;
37 m_bUpdating = false;
38
39 for (unsigned int i = 0; i < 4; i++)
40 (*this).push_back(cv::Point2f(0.0f, 0.0f));
41}
42
46
48{
49 //TODO retrieve the featured picture
50 if (m_type != AR_ARUCO_MARKER)
51 return cv::Mat();
52
53 aruco::Dictionary dict = aruco::Dictionary::loadPredefined(aruco::Dictionary::ARUCO);
54 return dict.getMarkerImage_id(id, size / 4, true, false, false);
55}
56
58{
59 m_pos = pos;
60}
61
66
68{
69 m_orientation = orientation;
70}
71
73{
74 boost::mutex::scoped_lock l(markerMutex);
75 return m_pos;
76}
77
79{
80 boost::mutex::scoped_lock l(markerMutex);
81 return m_pixel_pos;
82}
83
85{
86 boost::mutex::scoped_lock l(markerMutex);
87 return m_orientation;
88}
89
90unsigned int ArMarker::GetID()
91{
92 return id;
93}
94
96{
97 return m_type;
98}
99
100void ArMarker::SetVisible(bool visible)
101{
102 //boost::mutex::scoped_lock l(markerMutex);
103 m_visible = visible;
104}
105
107{
108 boost::mutex::scoped_lock l(markerMutex);
109 boost::shared_lock< boost::shared_mutex > lockList(ArManager::GetInstance()->listMutex);
110 return m_visible;
111}
112
113void ArMarker::SetSize(float size)
114{
115 boost::mutex::scoped_lock l(markerMutex);
116 m_size = size;
117}
118
120{
121 boost::mutex::scoped_lock l(markerMutex);
122 return m_size;
123}
124
125void ArMarker::Draw(cv::Mat image)
126{
127 boost::mutex::scoped_lock l(markerMutex);
128 if ((*this).size()!=4)
129 return;
130
131 cv::Scalar color(255, 0, 0);
132 int lineWidth = 1;
133
134 cv::line(image, (*this)[0], (*this)[1], color, lineWidth, cv::LINE_AA);
135 cv::line(image, (*this)[1], (*this)[2], color, lineWidth, cv::LINE_AA);
136 cv::line(image, (*this)[2], (*this)[3], color, lineWidth, cv::LINE_AA);
137 cv::line(image, (*this)[3], (*this)[0], color, lineWidth, cv::LINE_AA);
138 cv::rectangle(image, (*this)[0]-cv::Point2f(2,2), (*this)[0]+cv::Point2f(2,2), cv::Scalar(0,0,255), lineWidth, cv::LINE_AA);
139 cv::rectangle(image, (*this)[1]-cv::Point2f(2,2), (*this)[1]+cv::Point2f(2,2), cv::Scalar(0,255,0), lineWidth, cv::LINE_AA);
140 cv::rectangle(image, (*this)[2]-cv::Point2f(2,2), (*this)[2]+cv::Point2f(2,2), cv::Scalar(255,0,0), lineWidth, cv::LINE_AA);
141
142 char cad[100];
143 sprintf(cad, "id=%d", id);
144
145 //determine the centroid
146 cv::Point cent(0,0);
147 for (int i = 0; i < 4; i++)
148 {
149 cent.x += static_cast<int>((*this)[i].x);
150 cent.y += static_cast<int>((*this)[i].y);
151 }
152 cent.x/= 4;
153 cent.y/= 4;
154
155 cv::putText(image, cad, cent, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255-color[0], 255-color[1], 255-color[2]), 2);
156}
157
158void ArMarker::SetCoords(std::vector<cv::Point2f> coords)
159{
160 if (coords.size() < 4)
161 return;
162
163 for (unsigned int i = 0; i < 4; i++)
164 (*this)[i] = coords[i];
165}
166
167void ArMarker::Update(ArCameraParam& camparam, aruco::Marker& marker, bool reverse)
168{
169 /* Get Matrix*/
170 double modelview_matrix[16];
171
172 try
173 {
174 //recalculate Rvec and Tvec with marker size
175 marker.calculateExtrinsics(m_size, camparam.camParam);
176 marker.glGetModelViewMatrix(modelview_matrix);
177 }
178 catch(std::exception&)
179 {
180 return;
181 }
182
183 if(marker.size() == 4)
184 SetCoords(marker);
185
186 //determine the centroid
187 Vector3 pixelPosition(0.0,0.0,0.0);
188 for (int j=0;j<4;j++)
189 {
190 pixelPosition.x += marker[j].x;
191 pixelPosition.y += marker[j].y;
192 }
193
194 pixelPosition.z = sqrt(pow((marker[1].x - marker[0].x),2) + pow((marker[1].y - marker[0].y),2));
195 pixelPosition.z += sqrt(pow((marker[2].x - marker[1].x),2) + pow((marker[2].y - marker[1].y),2));
196 pixelPosition.z += sqrt(pow((marker[3].x - marker[2].x),2) + pow((marker[3].y - marker[2].y),2));
197 pixelPosition.z += sqrt(pow((marker[0].x - marker[3].x),2) + pow((marker[0].y - marker[3].y),2));
198
199 pixelPosition.x/=4.0f;
200 pixelPosition.y/=4.0f;
201 pixelPosition.z/=4.0f;
202
203 //cv::circle(image, Point(pixelPosition.x, pixelPosition.y),pixelPosition.z/2,cv::Scalar(255,0,255));
204
205 SetPixelPosition(pixelPosition);
206 SetVisible(true);
207 Vector3 offset = camparam.GetCameraOffset();
208 SetPosition(Vector3(static_cast<float>(reverse ? -modelview_matrix[12] : modelview_matrix[12]) + offset.x, static_cast<float>(modelview_matrix[13]) + offset.y, static_cast<float>(modelview_matrix[14]) + offset.z));
209 SetOrientation(BtQuaternion::FromRotationMatrix(modelview_matrix, reverse));// *BtQuaternion(sqrt(0.5f), 0.0f, sqrt(0.5f), 0.0f));
210}
211
212/*
213void ArMarker::Update(cv::Mat frame, cv::Mat color, aruco::CameraParameters& camparam, bool reverse)
214{
215 if(!m_bUpdating)
216 {
217 m_lastCamParam = camparam;
218 frame.copyTo(m_lastFrame);
219 color.copyTo(m_lastColor);
220 m_lastReverse = reverse;
221 m_needUpdate = false;
222
223 // Run thread
224 try
225 {
226 m_thread_lock.lock();
227 SService* service = SService::GetInstance();
228 service->addWork(boost::bind(&ArMarker::DetectFeaturedThread, this));
229 }
230 catch(std::exception&)
231 {
232 m_thread_lock.unlock();
233 }
234 }
235}
236
237void ArMarker::DetectFeaturedThread()
238{
239 boost::mutex::scoped_lock l(killMutex);
240 if (m_fmarker)
241 {
242 m_bUpdating = true;
243 //bool found = (m_visible && m_fmarker->detectMotionFlow(m_lastFrame)) ? true : m_fmarker->detectFeatured(m_lastFrame);
244 bool found = m_fmarker->detectFeatured(m_lastFrame, m_lastColor, m_lastCamParam.CamSize);
245 if (found)
246 {
247 m_bUpdating = false;
248
249 //Get Matrix
250 double modelview_matrix[16];
251
252 try
253 {
254 //recalculate Rvec and Tvec with marker size
255 m_fmarker->calculateFeaturedExtrinsics(m_size, m_lastCamParam);
256 m_fmarker->glGetModelViewMatrix(modelview_matrix);
257 }
258 catch (std::exception&)
259 {
260 m_thread_lock.unlock();
261 return;
262 }
263
264 std::vector<cv::Point2f> coords;
265 if (m_fmarker->size() == 4)
266 {
267 for (int k = 0; k < 4; ++k)
268 coords.push_back(m_fmarker->at(k));
269 SetCoords(coords);
270 }
271
272 //determine the centroid
273 Vector3 pixelPosition(0.0,0.0,0.0);
274 for (int j=0;j<4;j++)
275 {
276 pixelPosition.x += m_fmarker->at(j).x;
277 pixelPosition.y += m_fmarker->at(j).y;
278 }
279
280 pixelPosition.z = sqrt(pow((m_fmarker->at(1).x - m_fmarker->at(0).x),2) + pow((m_fmarker->at(1).y - m_fmarker->at(0).y),2));
281 pixelPosition.z += sqrt(pow((m_fmarker->at(2).x - m_fmarker->at(1).x),2) + pow((m_fmarker->at(2).y - m_fmarker->at(1).y),2));
282 pixelPosition.z += sqrt(pow((m_fmarker->at(3).x - m_fmarker->at(2).x),2) + pow((m_fmarker->at(3).y - m_fmarker->at(2).y),2));
283 pixelPosition.z += sqrt(pow((m_fmarker->at(0).x - m_fmarker->at(3).x),2) + pow((m_fmarker->at(0).y - m_fmarker->at(3).y),2));
284
285 pixelPosition.x/=4.;
286 pixelPosition.y/=4.;
287 pixelPosition.z/=4.;
288
289 //cv::circle(image, Point(pixelPosition.x, pixelPosition.y),pixelPosition.z/2,cv::Scalar(255,0,255));
290
291 SetPixelPosition(pixelPosition);
292
293 SetPosition(Vector3(static_cast<float>(m_lastReverse ? -modelview_matrix[12] : modelview_matrix[12]), static_cast<float>(modelview_matrix[13]), static_cast<float>(modelview_matrix[14])));
294 SetOrientation(BtQuaternion::FromRotationMatrix(modelview_matrix, m_lastReverse));
295 SetVisible(true);
296 }
297 else
298 {
299 SetVisible(false);
300 }
301 }
302 m_needUpdate = true;
303 m_bUpdating = false;
304 m_thread_lock.unlock();
305}
306*/
307
308void ArMarker::rotateXAxis(cv::Mat& rotation)
309{
310 cv::Mat R(3, 3, CV_32F);
311 cv::Rodrigues(rotation, R);
312 // create a rotation matrix for x axis
313 cv::Mat RX = cv::Mat::eye(3, 3, CV_32F);
314 const float angleRad = 3.14159265359f / 2.f;
315 RX.at<float>(1, 1) = cos(angleRad);
316 RX.at<float>(1, 2) = -sin(angleRad);
317 RX.at<float>(2, 1) = sin(angleRad);
318 RX.at<float>(2, 2) = cos(angleRad);
319 // now multiply
320 R = R * RX;
321 // finally, the the rodrigues back
322 cv::Rodrigues(R, rotation);
323}
324
325std::vector<cv::Point2f> ArMarker::GetCorners()
326{
327 return *this;
328}
Vector3 GetCameraOffset()
aruco::CameraParameters camParam
static ArManager * GetInstance()
Definition ArManager.cpp:70
Vector3 GetPosition()
Definition ArMarker.cpp:72
boost::mutex markerMutex
Definition ArMarker.h:48
Vector3 GetPixelPosition()
Definition ArMarker.cpp:78
Vector3 m_pixel_pos
Definition ArMarker.h:52
bool IsVisible()
Definition ArMarker.cpp:106
unsigned int GetID()
Definition ArMarker.cpp:90
void rotateXAxis(cv::Mat &rotation)
Definition ArMarker.cpp:308
BtQuaternion m_orientation
Definition ArMarker.h:53
void SetPixelPosition(Vector3 pixelpos)
Definition ArMarker.cpp:62
void Update(ArCameraParam &camparam, aruco::Marker &marker, bool reverse)
Definition ArMarker.cpp:167
Vector3 m_pos
Definition ArMarker.h:51
@ AR_ARUCO_MARKER
Definition ArMarker.h:42
void Draw(cv::Mat image)
Definition ArMarker.cpp:125
void SetSize(float size)
Definition ArMarker.cpp:113
void SetPosition(Vector3 pos)
Definition ArMarker.cpp:57
void SetOrientation(BtQuaternion orientation)
Definition ArMarker.cpp:67
bool m_needUpdate
Definition ArMarker.h:55
float m_size
Definition ArMarker.h:56
float GetSize()
Definition ArMarker.cpp:119
void SetCoords(std::vector< cv::Point2f > coords)
Definition ArMarker.cpp:158
bool m_bUpdating
Definition ArMarker.h:57
cv::Mat GetMarkerBitmap(int size)
Definition ArMarker.cpp:47
virtual ~ArMarker()
Definition ArMarker.cpp:43
bool m_visible
Definition ArMarker.h:54
std::vector< cv::Point2f > GetCorners()
Definition ArMarker.cpp:325
BtQuaternion GetOrientation()
Definition ArMarker.cpp:84
void SetVisible(bool visible)
Definition ArMarker.cpp:100
ArMarker(unsigned int nid, float markerSize=-1, MarkerType type=AR_ARUCO_MARKER)
Definition ArMarker.cpp:29
MarkerType GetType()
Definition ArMarker.cpp:95
static BtQuaternion FromRotationMatrix(double rotMatrix[16], bool reverseX=false, bool reverseY=true)