PageRenderTime 337ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/MT/MT_Tracking/base/MT_TrackerBase.cpp

http://github.com/leonard-lab/MADTraC
C++ | 568 lines | 439 code | 115 blank | 14 comment | 64 complexity | a83f7ea276b044e85cbb9c453e08d0ff MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * MT_TrackerBase.cpp
  3. *
  4. * Created by Daniel Swain on 10/18/09.
  5. *
  6. */
  7. #include "MT_TrackerBase.h"
  8. #include "MT/MT_Core/support/mathsupport.h" /* for MT_getTimeSec() */
  9. /* MT_TrackedObjectsBase safe access convenience macros */
  10. #define SAFE_TO_RETURN(index, method, fail_value) \
  11. if(index < 0 || index >= m_iNumObjects) \
  12. { \
  13. return fail_value; \
  14. } \
  15. else \
  16. { \
  17. return m_TrackedObjects[index].method; \
  18. } /* end of SAFE_TO_RETURN macro */
  19. #define SAFE_TO_METHOD(index, method) \
  20. if(index < 0 || index >= m_iNumObjects) \
  21. { \
  22. return; \
  23. } \
  24. else \
  25. { \
  26. m_TrackedObjects[index].method; \
  27. } /* end of SAFE_TO_METHOD macro */
  28. MT_TrackerFrameGroup::MT_TrackerFrameGroup()
  29. {
  30. StandardFrameGroupInit(0);
  31. }
  32. void MT_TrackerFrameGroup::StandardFrameGroupInit(unsigned int n_frames)
  33. {
  34. m_iNFrames = n_frames;
  35. m_vFrames.resize(n_frames, 0);
  36. m_vFrameNames.resize(n_frames, string("Unset name"));
  37. }
  38. std::vector<string> MT_TrackerFrameGroup::getFrameNames() const
  39. {
  40. return m_vFrameNames;
  41. }
  42. IplImage* MT_TrackerFrameGroup::getFrame(unsigned int frame_index) const
  43. {
  44. if(frame_index < 0 || frame_index >= m_iNFrames)
  45. {
  46. return *m_vFrames[0];
  47. }
  48. else
  49. {
  50. return *m_vFrames[frame_index];
  51. }
  52. }
  53. MT_TrackedObjectsBase::MT_TrackedObjectsBase(unsigned int nobj,
  54. unsigned int state_size,
  55. unsigned int measurement_size)
  56. {
  57. m_TrackedObjects.resize(nobj,
  58. MT_TrackedObjectBase(state_size, measurement_size));
  59. m_iNumObjects = nobj;
  60. }
  61. unsigned int MT_TrackedObjectsBase::getNumConsecutiveFrames(unsigned int i) const
  62. {
  63. SAFE_TO_RETURN(i, m_iNumConsecutiveFrames, 0);
  64. }
  65. int MT_TrackedObjectsBase::getRobotIndex(unsigned int i) const
  66. {
  67. SAFE_TO_RETURN(i, m_iRobotIndex, MT_NO_ROBOT);
  68. }
  69. bool MT_TrackedObjectsBase::getIsMoving(unsigned int i) const
  70. {
  71. SAFE_TO_RETURN(i, getIsMoving(), false);
  72. }
  73. void MT_TrackedObjectsBase::setRobotIndex(unsigned int i, int new_index)
  74. {
  75. SAFE_TO_METHOD(i, m_iRobotIndex = new_index);
  76. }
  77. void MT_TrackedObjectsBase::setXY(unsigned int i, double x, double y)
  78. {
  79. SAFE_TO_METHOD(i, setXY(x,y));
  80. }
  81. void MT_TrackedObjectsBase::setOrientation(unsigned int i, double orientation)
  82. {
  83. SAFE_TO_METHOD(i, setOrientation(orientation));
  84. }
  85. double MT_TrackedObjectsBase::getX(unsigned int i) const
  86. {
  87. SAFE_TO_RETURN(i, getX(), 0);
  88. }
  89. double MT_TrackedObjectsBase::getY(unsigned int i) const
  90. {
  91. SAFE_TO_RETURN(i, getY(), 0);
  92. }
  93. double MT_TrackedObjectsBase::getOrientation(unsigned int i) const
  94. {
  95. SAFE_TO_RETURN(i, getOrientation(), 0);
  96. }
  97. CvKalman* MT_TrackedObjectsBase::initKalmanFilter(unsigned int i,
  98. unsigned int num_control_inputs)
  99. {
  100. SAFE_TO_RETURN(i, initKalmanFilter(num_control_inputs), NULL);
  101. }
  102. void MT_TrackedObjectsBase::setState(unsigned int i, double* state)
  103. {
  104. SAFE_TO_METHOD(i, setState(state));
  105. }
  106. double* MT_TrackedObjectsBase::getState(unsigned int i) const
  107. {
  108. SAFE_TO_RETURN(i, getState(), NULL);
  109. }
  110. void MT_TrackedObjectsBase::setMeasurement(unsigned int i, double* measurement)
  111. {
  112. SAFE_TO_METHOD(i, setMeasurement(measurement));
  113. }
  114. double* MT_TrackedObjectsBase::getMeasurement(unsigned int i) const
  115. {
  116. SAFE_TO_RETURN(i, getMeasurement(), NULL);
  117. }
  118. unsigned int MT_TrackedObjectsBase::getStateSize(unsigned int i) const
  119. {
  120. SAFE_TO_RETURN(i, getStateSize(), 0);
  121. }
  122. unsigned int MT_TrackedObjectsBase::getMeasurementSize(unsigned int i) const
  123. {
  124. SAFE_TO_RETURN(i, getMeasurementSize(), 0);
  125. }
  126. CvKalman* MT_TrackedObjectsBase::getKalmanFilterStruct(unsigned int i)
  127. {
  128. SAFE_TO_RETURN(i, getKalmanFilterStruct(), NULL);
  129. }
  130. MT_TrackedObjectBase::MT_TrackedObjectBase(unsigned int state_size,
  131. unsigned int measurement_size)
  132. :m_pKalmanFilter(NULL)
  133. {
  134. m_iNumConsecutiveFrames = 0;
  135. m_iRobotIndex = MT_NO_ROBOT;
  136. m_iStateSize = state_size;
  137. m_iMeasurementSize = measurement_size;
  138. m_pdState = (double *)calloc(state_size, sizeof(double));
  139. m_pdMeasurement = (double *)calloc(measurement_size, sizeof(double));
  140. }
  141. MT_TrackedObjectBase::MT_TrackedObjectBase(const MT_TrackedObjectBase& TO)
  142. : m_iNumConsecutiveFrames(0),
  143. m_iRobotIndex(MT_NO_ROBOT),
  144. m_iStateSize(TO.m_iStateSize),
  145. m_iMeasurementSize(TO.m_iMeasurementSize),
  146. m_pKalmanFilter(NULL)
  147. {
  148. m_pdState = (double *)calloc(m_iStateSize, sizeof(double));
  149. m_pdMeasurement = (double *)calloc(m_iMeasurementSize, sizeof(double));
  150. }
  151. MT_TrackedObjectBase::~MT_TrackedObjectBase()
  152. {
  153. if(m_iStateSize)
  154. {
  155. free(m_pdState);
  156. }
  157. if(m_iMeasurementSize)
  158. {
  159. free(m_pdMeasurement);
  160. }
  161. if(m_pKalmanFilter)
  162. {
  163. cvReleaseKalman(&m_pKalmanFilter);
  164. }
  165. }
  166. CvKalman* MT_TrackedObjectBase::initKalmanFilter(unsigned int num_control_inputs)
  167. {
  168. if(m_pKalmanFilter)
  169. {
  170. cvReleaseKalman(&m_pKalmanFilter);
  171. }
  172. m_pKalmanFilter = cvCreateKalman(m_iStateSize, m_iMeasurementSize, num_control_inputs);
  173. return m_pKalmanFilter;
  174. }
  175. MT_TrackerBase::MT_TrackerBase(IplImage* ProtoFrame)
  176. : m_pTrackedObjects(NULL)
  177. {
  178. doInit(ProtoFrame);
  179. }
  180. MT_TrackerBase::MT_TrackerBase()
  181. {
  182. doInit(NULL);
  183. }
  184. MT_TrackerBase::~MT_TrackerBase()
  185. {
  186. for(unsigned int i = 0; i < m_vDataGroups.size(); i++)
  187. {
  188. delete m_vDataGroups[i];
  189. m_vDataGroups[i] = NULL;
  190. }
  191. for(unsigned int i = 0; i < m_vDataReports.size(); i++)
  192. {
  193. delete m_vDataReports[i];
  194. m_vDataReports[i] = NULL;
  195. }
  196. if(m_pTrackerFrameGroup)
  197. {
  198. delete m_pTrackerFrameGroup;
  199. }
  200. if(m_pTrackedObjects)
  201. {
  202. delete m_pTrackedObjects;
  203. }
  204. releaseFrames();
  205. }
  206. void MT_TrackerBase::doInit(IplImage* ProtoFrame)
  207. {
  208. m_SourceName = "Unknown";
  209. m_Note = "None";
  210. NFound = 0;
  211. m_vDataGroups.resize(0);
  212. m_pTrackerFrameGroup = NULL;
  213. BG_frame = NULL;
  214. ROI_frame = NULL;
  215. if(ProtoFrame)
  216. {
  217. doTrain(ProtoFrame);
  218. }
  219. else
  220. {
  221. FrameWidth = 0;
  222. FrameHeight = 0;
  223. }
  224. }
  225. void MT_TrackerBase::initDataFile()
  226. {
  227. char datestring[10];
  228. char timestring[10];
  229. sprintf(datestring, "%02d/%02d/%02d", MT_getMonthMM(), MT_getDay(), MT_getYearYY());
  230. sprintf(timestring, "%02d:%02d:%02d", MT_getHour24(), MT_getMinute(), MT_getSecond());
  231. m_XDF.writeParameterToXML(MT_XDF_XML_VIDEOSOURCE_KEY, m_SourceName);
  232. m_XDF.writeParameterToXML(MT_XDF_XML_USERNOTE_KEY, m_Note.c_str());
  233. m_XDF.writeParameterToXML("Date", datestring);
  234. m_XDF.writeParameterToXML("Time", timestring);
  235. for(unsigned int i = 0; i < m_vDataGroups.size(); i++)
  236. {
  237. m_XDF.writeDataGroupToXML(m_vDataGroups[i]);
  238. }
  239. }
  240. void MT_TrackerBase::releaseFrames()
  241. {
  242. if(BG_frame)
  243. {
  244. cvReleaseImage(&BG_frame);
  245. }
  246. if(ROI_frame)
  247. {
  248. cvReleaseImage(&ROI_frame);
  249. }
  250. }
  251. void MT_TrackerBase::doTrain(IplImage* frame)
  252. {
  253. // TODO Should really check this against the ROI frame if it exists
  254. CvSize framesize = cvSize(frame->width,frame->height);
  255. FrameWidth = frame->width;
  256. FrameHeight = frame->height;
  257. createFrames();
  258. if(frame->nChannels == 3)
  259. {
  260. cvCvtColor(frame, BG_frame, CV_BGR2GRAY);
  261. } else {
  262. cvCopy(frame, BG_frame);
  263. }
  264. }
  265. void MT_TrackerBase::createFrames()
  266. {
  267. // TODO Should really check this against the ROI frame if it exists
  268. CvSize framesize = cvSize(FrameWidth, FrameHeight);
  269. if(BG_frame)
  270. {
  271. cvReleaseImage(&BG_frame);
  272. }
  273. BG_frame = cvCreateImage(framesize, IPL_DEPTH_8U, 1);
  274. }
  275. bool MT_TrackerBase::setROIImage(const char* ROIFilename,
  276. std::string* p_error_message)
  277. {
  278. char message[512];
  279. ROI_frame = cvLoadImage(ROIFilename,CV_LOAD_IMAGE_GRAYSCALE);
  280. if(ROI_frame == 0)
  281. {
  282. sprintf(message,"Could not load ROI frame %s.",ROIFilename);
  283. } else {
  284. // need to make sure it's the right size
  285. if( (ROI_frame->width != FrameWidth) || (ROI_frame->height != FrameHeight) )
  286. {
  287. sprintf(message, "ROI Frame %s does not have the correct size.\n",ROIFilename);
  288. ROI_frame = 0;
  289. }
  290. }
  291. if(ROI_frame == 0)
  292. {
  293. if(p_error_message)
  294. {
  295. *p_error_message = message;
  296. }
  297. else
  298. {
  299. fprintf(stderr, "%s\n", message);
  300. }
  301. return false;
  302. }
  303. return true;
  304. }
  305. bool MT_TrackerBase::setBackgroundImage(const char* BackgroundFilename,
  306. std::string* p_error_message)
  307. {
  308. char message[512];
  309. IplImage* tBG_frame = cvLoadImage(BackgroundFilename,CV_LOAD_IMAGE_GRAYSCALE);
  310. if(tBG_frame == 0)
  311. {
  312. sprintf(message, "Could not load background frame %s\n", BackgroundFilename);
  313. } else {
  314. // need to make sure it's the right size
  315. if( (tBG_frame->width != FrameWidth) || (tBG_frame->height != FrameHeight) )
  316. {
  317. sprintf(message, "ROI Frame %s does not have the correct size.\n", BackgroundFilename);
  318. }
  319. }
  320. if(tBG_frame == 0)
  321. {
  322. if(p_error_message)
  323. {
  324. *p_error_message = message;
  325. }
  326. else
  327. {
  328. fprintf(stderr, "%s\n", message);
  329. }
  330. return false;
  331. }
  332. // frame is ok, so re-train the tracker with this background
  333. // note we don't need to actually assign the frame, this gets taken care of
  334. // in the Train() function
  335. doTrain(tBG_frame);
  336. return true;
  337. }
  338. bool MT_TrackerBase::setDataFile(const char* DataFilename,
  339. std::string* p_error_message)
  340. {
  341. char message[512];
  342. if(m_XDF.initAsNew(DataFilename, MT_XDF_OVERWRITE) == MT_XDF_ERROR)
  343. {
  344. sprintf(message, "Could not initialize data file %s.", DataFilename);
  345. if(p_error_message)
  346. {
  347. *p_error_message = message;
  348. }
  349. else
  350. {
  351. fprintf(stderr, "%s\n", message);
  352. }
  353. return false;
  354. }
  355. initDataFile();
  356. return true;
  357. }
  358. IplImage* MT_TrackerBase::getProcessedFrame(unsigned int frame_index) const
  359. {
  360. if(!m_pTrackerFrameGroup || frame_index < 0 || frame_index >= m_pTrackerFrameGroup->getNumFrames())
  361. {
  362. return NULL;
  363. }
  364. else
  365. {
  366. return m_pTrackerFrameGroup->getFrame(frame_index);
  367. }
  368. }
  369. unsigned int MT_TrackerBase::getNumProcessedFrames() const
  370. {
  371. if(!m_pTrackerFrameGroup)
  372. {
  373. return 0;
  374. }
  375. else
  376. {
  377. return m_pTrackerFrameGroup->getNumFrames();
  378. }
  379. }
  380. unsigned int MT_TrackerBase::getNumDataGroups() const
  381. {
  382. return m_vDataGroups.size();
  383. }
  384. MT_DataGroup* MT_TrackerBase::getDataGroup(unsigned int i) const
  385. {
  386. if(i < 0 || i >= getNumDataGroups())
  387. {
  388. return NULL;
  389. }
  390. else
  391. {
  392. return m_vDataGroups[i];
  393. }
  394. }
  395. unsigned int MT_TrackerBase::getNumDataReports() const
  396. {
  397. return m_vDataReports.size();
  398. }
  399. MT_DataReport* MT_TrackerBase::getDataReport(unsigned int i) const
  400. {
  401. if(i < 0 || i >= getNumDataReports())
  402. {
  403. return NULL;
  404. }
  405. else
  406. {
  407. return m_vDataReports[i];
  408. }
  409. }
  410. double MT_TrackerBase::getFrameRate(bool updaterate)
  411. {
  412. static double t_previous = MT_getTimeSec();
  413. static double t_now = MT_getTimeSec();
  414. static double dt;
  415. if(updaterate)
  416. {
  417. t_now = MT_getTimeSec();
  418. dt = t_now - t_previous;
  419. t_previous = t_now;
  420. }
  421. if(dt == 0)
  422. {
  423. return 0;
  424. }
  425. else
  426. {
  427. return 1.0/dt;
  428. }
  429. }
  430. MT_BoundingBox MT_TrackerBase::getObjectBoundingBox() const
  431. {
  432. return MT_BoundingBox(0,0,0,0);
  433. }
  434. void MT_TrackerBase::setNote(const char* note)
  435. {
  436. m_Note = std::string(note);
  437. if(m_XDF.getStatus() == MT_XDF_OK)
  438. {
  439. m_XDF.writeParameterToXML(MT_XDF_XML_USERNOTE_KEY, m_Note.c_str());
  440. }
  441. }
  442. void MT_TrackerBase::getNote(std::string* note)
  443. {
  444. std::string exist_note;
  445. if(m_XDF.getStatus() == MT_XDF_OK)
  446. {
  447. if(m_XDF.getParameterString(MT_XDF_XML_USERNOTE_KEY, &exist_note) == MT_XDF_OK)
  448. {
  449. m_Note = exist_note;
  450. }
  451. }
  452. *note = m_Note;
  453. }