ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Annotaion.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
12 #include <vtkActor.h>
13 #include <vtkBalloonRepresentation.h>
14 #include <vtkBalloonWidget.h>
15 #include <vtkCellData.h>
16 #include <vtkFloatArray.h>
17 #include <vtkLookupTable.h>
18 #include <vtkPolyData.h>
19 #include <vtkPolyDataMapper.h>
20 #include <vtkProperty.h>
21 #include <vtkTransform.h>
22 
23 // CV_CORE_LIB
24 #include <CVLog.h>
25 #include <CVTools.h>
26 
27 // CV_DB_LIB
28 #include <ecvColorTypes.h>
29 
30 #ifdef USE_TBB
31 #include <tbb/parallel_for.h>
32 #endif
33 
34 // SYSTEM
35 #include <QFile>
36 #include <map>
37 
38 using namespace std;
39 
40 // static variable
41 std::vector<std::string>* Annotation::types = nullptr;
42 
43 Annotation::Annotation(const std::vector<int>& slice, std::string type_) {
44  assert(!slice.empty());
45  this->type = type_;
46  this->m_slice.clear();
47  this->m_slice.assign(slice.begin(), slice.end());
48  this->actor = nullptr;
49  this->boxWidget = nullptr;
50 }
51 
52 Annotation::Annotation(const BoxLabel& label, bool visible_, bool lock_)
53  : visible(visible_), lock(lock_) {
54  // type
55  type = label.type;
56 
57  // init variable
58  initial();
59 
60  // apply transform
61  vtkSmartPointer<vtkTransform> cubeTransform =
63  cubeTransform->PostMultiply();
64  cubeTransform->Scale(label.detail.length, label.detail.width,
65  label.detail.height);
66  cubeTransform->RotateY(label.detail.yaw * 180 / vtkMath::Pi());
67  cubeTransform->Translate(label.detail.center_x, label.detail.center_y,
68  label.detail.center_z);
69 
70  applyTransform(cubeTransform);
71 }
72 
73 Annotation::Annotation(const PointCloudI::Ptr cloud,
74  vector<int>& slice,
75  std::string type_) {
76  double p1[3];
77  double p2[3];
78  ComputeOBB(cloud, slice, p1, p2);
79  BoxLabel label(p1, p2, type_);
80 
81  setAnchorPoint(cloud, slice);
82 
83  this->type = type_;
84 
85  this->m_slice.clear();
86  this->m_slice.assign(slice.begin(), slice.end());
87 
88  // init variable
89  initial();
90 
91  // apply transform
92  vtkSmartPointer<vtkTransform> cubeTransform =
94  cubeTransform->PostMultiply();
95  cubeTransform->Scale(label.detail.length, label.detail.width,
96  label.detail.height);
97  cubeTransform->RotateY(label.detail.yaw * 180 / vtkMath::Pi());
98  cubeTransform->Translate(label.detail.center_x, label.detail.center_y,
99  label.detail.center_z);
100 
101  applyTransform(cubeTransform);
102 }
103 
105  // release anchorPoints
106  for (auto p : anchorPoints) {
107  delete[] p;
108  }
109  anchorPoints.clear();
110 }
111 
113  // Cube
116  mapper->SetInputConnection(source->GetOutputPort());
118  actor->SetMapper(mapper);
120  colorAnnotation();
121 }
122 
124  if (!this->actor) return;
125 
128  lut->SetNumberOfTableValues(2);
129  lut->Build();
130  if (color_index < 0) {
132  lut->SetTableValue(0, c.r / 255.0, c.g / 255.0, c.b / 255.0, 0);
133  lut->SetTableValue(1, c.r / 255.0, c.g / 255.0, c.b / 255.0, 1);
134  } else {
135  // pcl::RGB c = pcl::GlasbeyLUT::at(color_index);
137  static_cast<std::size_t>(color_index));
138  lut->SetTableValue(0, c.r / 255.0, c.g / 255.0, c.b / 255.0, 0);
139  lut->SetTableValue(1, c.r / 255.0, c.g / 255.0, c.b / 255.0, 1);
140  }
141 
144 
145  // line color
146  for (int i = 0; i < 12; i++) {
147  cellData->InsertNextValue(1);
148  }
149 
150  // face color
151  for (int i = 0; i < 6; i++) {
152  cellData->InsertNextValue(0);
153  }
154 
155  // plusX face
156  cellData->InsertValue(12, 1);
157 
158  source->Update();
159  source->GetOutput()->GetCellData()->SetScalars(cellData);
160 
161  actor->GetProperty()->SetLineWidth(2);
162  actor->GetProperty()->SetLighting(false);
163 
164  mapper->SetLookupTable(lut);
165 }
166 
167 void Annotation::setAnchorPoint(const PointCloudI::Ptr cloud,
168  const std::vector<int>& slice) {
169  if (cloud->size() == 0 || slice.empty()) return;
170 
171  int num = static_cast<int>(slice.size());
172  anchorPoints.clear();
173  anchorPoints.resize(slice.size());
174 
175  if (num != 0) {
176 #ifdef USE_TBB
177  tbb::parallel_for(
178  0, num,
179  [&](int dataIndex)
180 #else
181 
182 #if defined(_OPENMP)
183 #pragma omp parallel for
184 #endif
185  for (int dataIndex = 0; dataIndex < num; ++dataIndex)
186 #endif
187  {
188  double* p = new double[3];
189  p[0] = static_cast<double>(
190  cloud
191  ->points[static_cast<std::size_t>(
192  slice[static_cast<std::size_t>(
193  dataIndex)])]
194  .x);
195  p[1] = static_cast<double>(
196  cloud
197  ->points[static_cast<std::size_t>(
198  slice[static_cast<std::size_t>(
199  dataIndex)])]
200  .y);
201  p[2] = static_cast<double>(
202  cloud
203  ->points[static_cast<std::size_t>(
204  slice[static_cast<std::size_t>(
205  dataIndex)])]
206  .z);
207  anchorPoints[static_cast<std::size_t>(dataIndex)] = p;
208  }
209 #ifdef USE_TBB
210  );
211 #endif
212  }
213 }
214 
216  BoxLabel label;
217  label.type = type;
218 
219  double p[3];
220  double s[3];
221  double o[3];
222  transform->GetPosition(p);
223  transform->GetScale(s);
224  transform->GetOrientation(o);
225  memcpy(label.data, p, 3 * sizeof(double));
226  memcpy(label.data + 3, s, 3 * sizeof(double));
227  label.detail.yaw = o[1] / 180 * vtkMath::Pi();
228  return label;
229 }
230 
232  if (this->actor) {
233  if (t == transform) return;
234 
235  transform = t;
236  actor->SetUserTransform(t);
237  }
238 }
239 
240 void Annotation::picked(vtkRenderWindowInteractor* interactor) {
241  // enable box widget
242  if (!this->actor) return;
243 
244  // enable box widget
245  if (!boxWidget) {
247  boxWidgetCallback0 = vtkSmartPointer<vtkBoxWidgetCallback0>::New();
248  boxWidgetCallback0->setAnno(this);
249  boxWidgetCallback1 = vtkSmartPointer<vtkBoxWidgetCallback1>::New();
250  boxWidgetCallback1->setAnno(this);
251 
252  boxWidget->SetInteractor(interactor);
253  // boxWidget->SetProp3D( cubeActor );
254  // boxWidget->SetPlaceFactor( 1.25 ); // Make the box 1.25x larger than
255  // the actor boxWidget->PlaceWidget();
256 
257  // default is [-0.5, 0.5], NOTE
258  // [-1,1] makes boxwidget fit to annotion,
259  // but [-0.5, 0.5] should be in the correct way, may be some bug
260  double bounds[6] = {-1, 1, -1, 1, -1, 1};
261  boxWidget->PlaceWidget(bounds);
262 
263  boxWidget->SetHandleSize(0.01);
264  boxWidget->GetOutlineProperty()->SetAmbientColor(1.0, 0.0, 0.0);
265  boxWidget->AddObserver(vtkCommand::InteractionEvent,
266  boxWidgetCallback0);
267  boxWidget->AddObserver(vtkCommand::EndInteractionEvent,
268  boxWidgetCallback1);
269  }
270 
272  t->DeepCopy(actor->GetUserTransform());
273  boxWidget->SetTransform(t);
274  boxWidget->On();
275 }
276 
278  if (this->boxWidget) {
279  boxWidget->Off();
280  }
281 }
282 
284  if (anchorPoints.size() == 0) return;
285 
286  transform->GetPosition(center);
287 
288  double r[3], x[3], z[3], y[3] = {0, 1, 0};
289  double s[3]; // scale
290 
291  transform->GetOrientation(r);
292  // direction
293  z[0] = std::sin(vtkMath::RadiansFromDegrees(r[1]));
294  z[1] = 0;
295  z[2] = std::cos(vtkMath::RadiansFromDegrees(r[1]));
296  vtkMath::Cross(y, z, x);
297 
298  double scs[2];
299  s[0] = computeScaleAndCenterShift(x, scs);
300  vtkMath::MultiplyScalar(x, scs[1]);
301  s[1] = computeScaleAndCenterShift(y, scs);
302  vtkMath::MultiplyScalar(y, scs[1]);
303  s[2] = computeScaleAndCenterShift(z, scs);
304  vtkMath::MultiplyScalar(z, scs[1]);
305 
306  // apply center shift
307  vtkMath::Add(center, x, center);
308  vtkMath::Add(center, y, center);
309  vtkMath::Add(center, z, center);
310 
312  t->Translate(center);
313  t->RotateY(r[1]);
314  t->Scale(s);
315 
316  boxWidget->SetTransform(t);
317  applyTransform(t);
318 }
319 
320 std::string Annotation::getType() const { return type; }
321 
322 const std::vector<int>& Annotation::getSlice() const { return m_slice; }
323 
324 void Annotation::setType(const std::string value) {
325  if (value != type) {
326  type = value;
327  if (this->actor) {
328  colorAnnotation();
329  }
330  }
331 }
332 
334 
335 double Annotation::computeScaleAndCenterShift(double o[], double scs[]) {
336  vtkMath::Normalize(o);
337 
338  double a, b;
339  a = -std::numeric_limits<double>::max();
340  b = std::numeric_limits<double>::max();
341 
342  double t[3];
343  for (auto x : anchorPoints) {
344  vtkMath::Subtract(x, this->center, t);
345  double s = vtkMath::Dot(t, o);
346  a = std::max(a, s);
347  b = std::min(b, s);
348  }
349  scs[0] = a - b;
350  scs[1] = (a + b) / 2;
351  return a - b;
352 }
353 
354 std::vector<std::string>* Annotation::GetTypes() {
355  if (!types) {
356  types = new vector<string>();
357  }
358 
359  return types;
360 }
361 
362 std::size_t Annotation::GetTypeIndex(std::string type_) {
363  assert(types);
364  for (std::size_t i = 0; i < types->size(); i++) {
365  if (types->at(i) == type_) return i;
366  }
367 
368  types->push_back(type_);
369  return types->size() - 1;
370 }
371 
372 std::string Annotation::GetTypeByIndex(size_t index) {
373  assert(types);
374  if (index > types->size() - 1) {
375  return "";
376  }
377 
378  return types->at(index);
379 }
380 
381 void Annotation::ComputeOBB(const PointCloudI::Ptr cloud,
382  std::vector<int>& slice,
383  double p1[3],
384  double p2[3]) {
385  p1[0] = std::numeric_limits<double>::max();
386  p1[1] = std::numeric_limits<double>::max();
387  p1[2] = std::numeric_limits<double>::max();
388 
389  // std::numeric_limits <double>::min (); is a number close enough to 0
390  p2[0] = -std::numeric_limits<double>::max();
391  p2[1] = -std::numeric_limits<double>::max();
392  p2[2] = -std::numeric_limits<double>::max();
393 
394  for (auto i : slice) {
395  std::size_t index = static_cast<std::size_t>(i);
396  p1[0] = std::min(p1[0], static_cast<double>(cloud->points[index].x));
397  p1[1] = std::min(p1[1], static_cast<double>(cloud->points[index].y));
398  p1[2] = std::min(p1[2], static_cast<double>(cloud->points[index].z));
399 
400  p2[0] = std::max(p2[0], static_cast<double>(cloud->points[index].x));
401  p2[1] = std::max(p2[1], static_cast<double>(cloud->points[index].y));
402  p2[2] = std::max(p2[2], static_cast<double>(cloud->points[index].z));
403  }
404 }
405 
406 Annotaions::Annotaions(vtkRenderWindowInteractor* interactor)
407  : m_interactor(interactor) {
408  if (interactor && !m_balloonWidget) {
411  balloonRep->SetBalloonLayoutToImageRight();
412 
414  m_balloonWidget->SetInteractor(interactor);
415  m_balloonWidget->SetRepresentation(balloonRep);
416  m_balloonWidget->On();
417  }
418 }
419 
420 void Annotaions::preserve(size_t num) {
421  if (num != 0) {
422  m_capacity = num;
423  m_labeledCloudIndex = new int[m_capacity];
424  }
425  memset(m_labeledCloudIndex, 0, m_capacity * sizeof(int));
426 }
427 
429  if (m_labeledCloudIndex) {
430  delete[] m_labeledCloudIndex;
431  m_labeledCloudIndex = nullptr;
432  }
433 
434  if (m_balloonWidget) {
435  m_balloonWidget->Off();
436  }
437  m_capacity = 0;
438 
439  if (Annotation::GetTypes()) {
440  delete Annotation::types;
441  Annotation::types = nullptr;
442  }
443 }
444 
446  // add balloon tip
447  if (m_balloonWidget) {
448  m_balloonWidget->AddBalloon(anno->getActor(), anno->getType().c_str(),
449  nullptr);
450  }
451 
452  // update internal labels
453  updateLabels(anno, false);
454  // add this anno to annotation manager
455  m_annotations.push_back(anno);
456 }
457 
459  if (m_balloonWidget) {
460  m_balloonWidget->RemoveBalloon(anno->getActor());
461  }
462  // reset internal labels
463  updateLabels(anno, true);
464  m_annotations.erase(
465  std::remove(m_annotations.begin(), m_annotations.end(), anno),
466  m_annotations.end());
467 }
468 
470  for (auto p : m_annotations) {
471  if (m_balloonWidget) {
472  m_balloonWidget->RemoveBalloon(p->getActor());
473  }
474  delete p;
475  }
476  m_annotations.clear();
477  preserve();
478 }
479 
480 std::size_t Annotaions::getSize() { return m_annotations.size(); }
481 
482 void Annotaions::updateLabels(Annotation* anno, bool resetFlag) {
483  if (!anno) return;
484 
485  int num = static_cast<int>(anno->getSlice().size());
486  int Annotype = static_cast<int>(Annotation::GetTypeIndex(anno->getType()));
487  if (m_labeledCloudIndex && num != 0) {
488 #ifdef USE_TBB
489  tbb::parallel_for(
490  0, num,
491  [&](int dataIndex)
492 #else
493 
494 #if defined(_OPENMP)
495 #pragma omp parallel for
496 #endif
497  for (int dataIndex = 0; dataIndex < num; ++dataIndex)
498 #endif
499  {
500  if (resetFlag) // reset labels which are related to this
501  // annotation
502  {
503  m_labeledCloudIndex[anno->getSlice()[static_cast<
504  std::size_t>(dataIndex)]] = 0;
505  } else {
506  m_labeledCloudIndex[anno->getSlice()[static_cast<
507  std::size_t>(dataIndex)]] = Annotype;
508  }
509  }
510 #ifdef USE_TBB
511  );
512 #endif
513  }
514 }
515 
516 typedef map<size_t, std::vector<int>> AnnotationMap;
517 
518 void Annotaions::loadAnnotations(string filename, int mode) {
519  m_annotations.clear();
520 
521  if (mode == 0) // semantic annotation
522  {
524  std::vector<size_t> indices;
525  if (!CVTools::QMappingReader(filename, indices)) {
526  return;
527  }
528 
529  AnnotationMap annotationsMap;
530  size_t i = 0;
531  for (i = 0; i < indices.size(); ++i) {
532  if (annotationsMap.find(indices[i]) == annotationsMap.end()) {
533  annotationsMap[indices[i]] = vector<int>();
534  }
535  annotationsMap[indices[i]].push_back(static_cast<int>(i));
536  }
537 
538  CVLog::Print(QString("loadAnnotations: finish cost %1 s")
539  .arg(CVTools::TimeOff()));
540  if (i != m_capacity) {
541  CVLog::Warning("label files are probably corrupted and drop it!");
542  return;
543  }
544 
545  if (!annotationsMap.empty()) {
546  for (AnnotationMap::iterator iter_int = annotationsMap.begin();
547  iter_int != annotationsMap.end(); iter_int++) {
548  size_t typeIndex = iter_int->first;
549  string type = Annotation::GetTypeByIndex(typeIndex);
550  if (type == "") continue;
551  vector<int> slice = iter_int->second;
552  add(new Annotation(slice, type));
553  }
554  }
555 
556  } else if (mode == 1) // bbox annotation
557  {
558  std::ifstream input(filename.c_str(), std::ios::in);
559  if (!input.good()) {
560  CVLog::Error(
561  QString("Cannot open file : %1").arg(filename.c_str()));
562  return;
563  }
564  std::string type;
565  while (input >> type) {
566  BoxLabel label;
567  label.type = type;
568  for (int j = 0; j < 7; j++) {
569  input >> label.data[j];
570  }
571  add(new Annotation(label));
572  }
573  input.close();
574  }
575 }
576 
577 void Annotaions::saveAnnotations(string filename, int mode) {
578  if (m_annotations.empty()) return;
579 
580  // #ifdef _WIN32
581  // CVTools::TimeStart();
582  // std::string ss;
583  // if (mode == 0) // semantic annotation
584  // {
585  // for (size_t i = 0; i < m_capacity; ++i)
586  // {
587  // ss += (std::to_string(m_labeledCloudIndex[i]) + "\n");
588  // }
589  // }
590  // else if (mode == 1) // bbox annotation
591  // {
592  // for (auto anno : m_annotations) {
593  // ss += (anno->getBoxLabel().toString() + "\n");
594  // }
595  // }
596  // else
597  // {
598  // CVLog::Warning(QString("unknown mode: %1, only semantic and box
599  // supported!").arg(mode)); return;
600  // }
601 
602  // if (!CVTools::FileMappingWriter(filename, (void*)ss.c_str(),
603  // strlen(ss.c_str())))
604  // {
605  // CVLog::Warning("save annotation file failed!");
606  // return;
607  // }
608  // CVLog::Print(QString("Save annotation file cost %1
609  // s").arg(CVTools::TimeOff()));
610 
611  // #else
612  // std::ofstream output(filename.c_str(), std::ios_base::out);
613  // if (mode == 0) // semantic annotation
614  // {
615  // for (size_t i = 0; i < m_capacity; ++i)
616  // {
617  // output << m_labeledCloudIndex[i] << std::endl;
618  // }
619  // }
620  // else if (mode == 1) // bbox annotation
621  // {
622  // for (auto anno : m_annotations) {
623  // output << anno->getBoxLabel().toString() << std::endl;
624  // }
625  // }
626 
627  // output.close();
628  // #endif
629 
631  std::string ss;
632  if (mode == 0) // semantic annotation
633  {
634  for (size_t i = 0; i < m_capacity; ++i) {
635  ss += (std::to_string(m_labeledCloudIndex[i]) + "\n");
636  }
637  } else if (mode == 1) // bbox annotation
638  {
639  for (auto anno : m_annotations) {
640  ss += (anno->getBoxLabel().toString() + "\n");
641  }
642  } else {
644  QString("unknown mode: %1, only semantic and box supported!")
645  .arg(mode));
646  return;
647  }
648 
649  if (!CVTools::QMappingWriter(filename, static_cast<const void*>(ss.c_str()),
650  strlen(ss.c_str()))) {
651  CVLog::Warning("save annotation file failed!");
652  return;
653  }
654  CVLog::Print(
655  QString("Save annotation file cost %1 s").arg(CVTools::TimeOff()));
656 }
657 
658 bool Annotaions::getAnnotations(std::vector<int>& annos) const {
659  if (!m_labeledCloudIndex || m_capacity == 0) return false;
660 
661  annos.resize(m_capacity);
662  memcpy(annos.data(), m_labeledCloudIndex, m_capacity * sizeof(int));
663 
664  return true;
665 }
666 
667 std::vector<Annotation*>& Annotaions::getAnnotations() { return m_annotations; }
668 
670  for (auto* anno : m_annotations) {
671  if (anno->getActor() == actor) {
672  return anno;
673  }
674  }
675  return nullptr;
676 }
677 
679  int index = -1;
680  if (!anno->getActor()) return index;
681 
682  for (auto anno2 : m_annotations) {
683  index++;
684  if (anno2->getActor() == anno->getActor()) {
685  return index;
686  }
687  }
688  return -1;
689 }
690 
692  if (index > getSize() - 1) return nullptr;
693  return m_annotations[static_cast<std::size_t>(index)];
694 }
695 
696 void Annotaions::getAnnotations(const std::string& type,
697  std::vector<Annotation*>& annotations) {
698  for (auto anno2 : m_annotations) {
699  if (anno2->getType() == type) {
700  annotations.push_back(anno2);
701  }
702  }
703 }
704 
705 void Annotaions::updateBalloonByIndex(std::size_t index) {
706  if (index > getSize() - 1) return;
707  if (!getAnnotation(index) || !getAnnotation(index)->getActor()) return;
708 
709  if (m_balloonWidget) {
710  m_balloonWidget->RemoveBalloon(getAnnotation(index)->getActor());
711  m_balloonWidget->AddBalloon(getAnnotation(index)->getActor(),
712  getAnnotation(index)->getType().c_str(),
713  nullptr);
714  }
715 }
716 
718  if (!m_balloonWidget || !anno->getActor()) return;
719  int annIndex = getAnnotationIndex(anno);
720  if (annIndex < 0) return;
721  updateBalloonByIndex(static_cast<std::size_t>(annIndex));
722 }
map< size_t, std::vector< int > > AnnotationMap
Definition: Annotaion.cpp:516
std::string filename
long color_index
char type
std::size_t getSize()
Definition: Annotaion.cpp:480
Annotaions(vtkRenderWindowInteractor *interactor=nullptr)
Definition: Annotaion.cpp:406
void loadAnnotations(std::string filename, int mode)
load annotations from file
Definition: Annotaion.cpp:518
void clear()
Definition: Annotaion.cpp:469
void add(Annotation *anno)
Definition: Annotaion.cpp:445
void release()
Definition: Annotaion.cpp:428
void updateBalloonByIndex(std::size_t index)
Definition: Annotaion.cpp:705
size_t m_capacity
Definition: Annotaion.h:287
std::vector< Annotation * > m_annotations
keep all annotation from current cloud
Definition: Annotaion.h:281
Annotation * getAnnotation(vtkActor *actor)
from annotatin box actor to find annotation itself
Definition: Annotaion.cpp:669
void saveAnnotations(std::string filename, int mode)
save annotations to file
Definition: Annotaion.cpp:577
vtkSmartPointer< vtkBalloonWidget > m_balloonWidget
Definition: Annotaion.h:284
void remove(Annotation *anno)
Definition: Annotaion.cpp:458
void preserve(size_t num=0)
Definition: Annotaion.cpp:420
void updateLabels(Annotation *anno, bool resetFlag=false)
Definition: Annotaion.cpp:482
void updateBalloonByAnno(Annotation *anno)
Definition: Annotaion.cpp:717
std::vector< Annotation * > & getAnnotations()
Definition: Annotaion.cpp:667
int * m_labeledCloudIndex
Definition: Annotaion.h:286
int getAnnotationIndex(Annotation *anno)
Definition: Annotaion.cpp:678
BoxLabel getBoxLabel()
getBoxLabel get boxLabel from annotaion tranformation
Definition: Annotaion.cpp:215
void applyTransform(vtkSmartPointer< vtkTransform > t)
apply transform to annotation
Definition: Annotaion.cpp:231
void picked(vtkRenderWindowInteractor *interactor)
enter picked state, show boxwidget which allow to adjust annotation
Definition: Annotaion.cpp:240
static std::size_t GetTypeIndex(std::string type_)
GetTypeIndex auto add to vector map if has not.
Definition: Annotaion.cpp:362
static std::vector< std::string > * GetTypes()
get types vector pointer
Definition: Annotaion.cpp:354
static std::vector< std::string > * types
types all annotation type here
Definition: Annotaion.h:224
Annotation(const std::vector< int > &slice, std::string type_)
Annotation construct from slice which load from label file.
Definition: Annotaion.cpp:43
void initial()
Definition: Annotaion.cpp:112
vtkSmartPointer< vtkActor > getActor() const
Definition: Annotaion.cpp:333
void colorAnnotation(int color_index=-1)
color the annotation with given color
Definition: Annotaion.cpp:123
void unpicked()
disable boxWidget
Definition: Annotaion.cpp:277
void setAnchorPoint(const PointCloudI::Ptr cloud, const std::vector< int > &slice)
copy selected points as anchor to current annotation
Definition: Annotaion.cpp:167
void adjustToAnchor()
keep current orientation, re-compute the center and scale to make annotation fit to selected point we...
Definition: Annotaion.cpp:283
std::string getType() const
Definition: Annotaion.cpp:320
double computeScaleAndCenterShift(double o[3], double scs[2])
computeScaleAndCenterShift
Definition: Annotaion.cpp:335
const std::vector< int > & getSlice() const
Definition: Annotaion.cpp:322
void setType(const std::string value)
change the type of annotation, and color too
Definition: Annotaion.cpp:324
static std::string GetTypeByIndex(size_t index)
GetTypeByIndex auto add to vector map if has not.
Definition: Annotaion.cpp:372
static void ComputeOBB(const PointCloudI::Ptr cloud, std::vector< int > &slice, double p1[3], double p2[3])
ComputeOBB compute max,min [x,y,z] aligned to xyz axis.
Definition: Annotaion.cpp:381
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
static bool Print(const char *format,...)
Prints out a formatted message in console.
Definition: CVLog.cpp:113
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
static QString TimeOff()
Definition: CVTools.cpp:39
static void TimeStart()
Definition: CVTools.cpp:37
static bool QMappingWriter(const std::string &filename, const void *data, std::size_t length)
Definition: CVTools.cpp:331
static bool QMappingReader(const std::string &filename, std::vector< size_t > &indices)
Definition: CVTools.cpp:280
RGB color structure.
Definition: ecvColorTypes.h:49
a[190]
normal_z y
normal_z x
normal_z z
CLOUDVIEWER_HOST_DEVICE float Cross(const Point &a, const Point &b)
Definition: IoUImpl.h:39
Rgb at(size_t color_id)
std::string to_string(const T &n)
Definition: Common.h:20
Definition: Eigen.h:85
struct BoxLabel::@53::@55 detail
double data[7]
Definition: Annotaion.h:37
std::string type
Definition: Annotaion.h:35
const float Pi
Definition: utils.cpp:15