26 m_maxCandTries(20), m_reqSamples(0), m_autoAcceptSize(0)
31 m_options(options), m_maxCandTries(20), m_reqSamples(0), m_autoAcceptSize(0)
49 m_constructors.push_back(
c);
50 if (
c->RequiredSamples() > m_reqSamples)
52 m_reqSamples =
c->RequiredSamples();
57RansacShapeDetector::StatBucket(
float score)
const
59 return (
size_t)std::max(
61 std::floor((std::log(score) - std::log((
float)m_options.
m_minSupport)) / std::log(1.21f)) +
70RansacShapeDetector::UpdateLevelWeights(
75 MiscLib::Vector<double> newSampleLevelProbability(sampleLevelProbability->
size());
76 double newSampleLevelProbabilitySum = 0;
77 for (
size_t i = 0; i < newSampleLevelProbability.size(); ++i)
79 if ((*sampleLevelProbability)[i] > 0)
81 newSampleLevelProbability[i] = (levelScores[i].first / (*sampleLevelProbability)[i]);
85 newSampleLevelProbability[i] = 0;
87 newSampleLevelProbabilitySum += newSampleLevelProbability[i];
90 for (
size_t i = 0; i < newSampleLevelProbability.size(); ++i)
92 newSampleLevelProbability[i] = .9f * newSampleLevelProbability[i] +
93 .1f * newSampleLevelProbabilitySum / levelScores.size();
94 newSum += newSampleLevelProbability[i];
96 for (
size_t i = 0; i < sampleLevelProbability->
size(); ++i)
98 (*sampleLevelProbability)[i] = (1.f - factor) * (*sampleLevelProbability)[i] +
99 factor * (newSampleLevelProbability[i] / newSum);
103template <
class ScoreVisitorT>
105RansacShapeDetector::GenerateCandidates(
109 ScoreVisitorT& scoreVisitor,
113 size_t* drawnCandidates,
115 float* bestExpectedValue,
116 CandidatesType* candidates)
const
122 ScoreVisitorT scoreVisitorCopy(scoreVisitor);
123#pragma omp for schedule(dynamic, 10) reduction(+ : genCands)
124 for (
int candIter = 0; candIter < 200; ++candIter)
127 double s = ((double)rand()) / (
double)RAND_MAX;
128 size_t sampleLevel = 0;
129 for (; sampleLevel < sampleLevelProbSum.
size() - 1; ++sampleLevel)
130 if (sampleLevelProbSum[sampleLevel] >= s)
135 MiscLib::Vector<size_t> samples;
137 if (!DrawSamplesStratified(globalOctree,
140 scoreVisitorCopy.GetShapeIndex(),
148 size_t c = samples.
size();
149 MiscLib::Vector<Vec3f> samplePoints(samples.
size() << 1);
150 for (
size_t i = 0; i < samples.
size(); ++i)
152 samplePoints[i] = globalOctree.at(samples[i]).pos;
153 samplePoints[i +
c] = globalOctree.at(samples[i]).normal;
156 PrimitiveShape* shape;
158 iend = m_constructors.end();
162 if ((*i)->RequiredSamples() > samples.
size() ||
163 !(shape = (*i)->Construct(samplePoints)))
168 std::pair<float, float> dn;
169 bool verified =
true;
170 for (
size_t i = 0; i <
c; ++i)
173 if (!scoreVisitorCopy.PointCompFunc()(dn.first, dn.second))
184 Candidate cand(shape, node->Level());
185 cand.Indices(
new MiscLib::RefCounted<MiscLib::Vector<size_t>>);
186 cand.Indices()->Release();
189 octrees, pc, scoreVisitorCopy, currentSize, m_options.m_bitmapEpsilon, 1);
190 if (cand.UpperBound() < m_options.m_minSupport)
194 (*sampleLevelScores)[node->Level()].first += cand.ExpectedValue();
195 ++(*sampleLevelScores)[node->Level()].second;
202 (*sampleLevelScores)[node->Level()].first += cand.ExpectedValue();
203 ++(*sampleLevelScores)[node->Level()].second;
204 candidates->push_back(cand);
205 if (cand.ExpectedValue() > *bestExpectedValue)
207 *bestExpectedValue = cand.ExpectedValue();
213 *drawnCandidates += genCands;
225template <
class ScoreVisitorT>
227RansacShapeDetector::FindBestCandidate(CandidatesType& candidates,
230 ScoreVisitorT& scoreVisitor,
232 size_t drawnCandidates,
236 float* maxForgottenCandidate,
237 float* candidateFailProb)
const
239 if (!candidates.size())
243 size_t maxImproveSubsetDuringMaxSearch = octrees.
size();
245 std::sort(candidates.begin(), candidates.end());
247 if (candidates.size() && candidates.back().ExpectedValue() < *maxForgottenCandidate)
251 drawnCandidates = std::max(candidates.size(), (
size_t)1);
252 *maxForgottenCandidate = 0;
255 MiscLib::Vector<Candidate*> candHeap;
256 for (
size_t i = candidates.size() - 1; i != -1; --i)
258 if (CandidateFailureProbability(candidates[i].ExpectedValue(),
259 currentSize - numInvalid,
261 numLevels) > m_options.m_probability)
268 if (!candHeap.
size())
273 std::make_heap(candHeap.
begin(), candHeap.
end(), CandidateHeapPred());
275 MiscLib::Vector<Candidate*> beatenCands;
276 Candidate* trial = candHeap.
front();
277 std::pop_heap(candHeap.
begin(), candHeap.
end(), CandidateHeapPred());
279 float bestCandidateFailureProbability;
280 while (candHeap.
size())
283 *candHeap.
front(), pc, m_options.m_epsilon, m_options.m_normalThresh))
285 std::pop_heap(candHeap.
begin(), candHeap.
end(), CandidateHeapPred());
289 bool isEquivalent =
false;
290 for (
size_t j = 0; j < beatenCands.
size(); ++j)
292 if (beatenCands[j]->IsEquivalent(
293 *candHeap.
front(), pc, m_options.m_epsilon, m_options.m_normalThresh))
301 std::pop_heap(candHeap.
begin(), candHeap.
end(), CandidateHeapPred());
305 bestCandidateFailureProbability = CandidateFailureProbability(
306 trial->
ExpectedValue(), currentSize - numInvalid, drawnCandidates, numLevels);
308 (bestCandidateFailureProbability <= m_options.m_probability) &&
311 octrees, pc, scoreVisitor, currentSize, m_options.m_bitmapEpsilon, octrees.
size()))
313 bestCandidateFailureProbability = CandidateFailureProbability(
314 trial->
ExpectedValue(), currentSize - numInvalid, drawnCandidates, numLevels);
316 if (bestCandidateFailureProbability <= m_options.m_probability &&
318 *trial >= *candHeap.
front())
322 if (bestCandidateFailureProbability <= m_options.m_probability &&
326 std::push_heap(candHeap.
begin(), candHeap.
end(), CandidateHeapPred());
332 trial = candHeap.
front();
333 std::pop_heap(candHeap.
begin(), candHeap.
end(), CandidateHeapPred());
336 bestCandidateFailureProbability = CandidateFailureProbability(
337 trial->
ExpectedValue(), currentSize - numInvalid, drawnCandidates, numLevels);
338 while (bestCandidateFailureProbability <= m_options.m_probability &&
341 octrees, pc, scoreVisitor, currentSize, m_options.m_bitmapEpsilon, octrees.
size()))
343 bestCandidateFailureProbability = CandidateFailureProbability(
344 trial->
ExpectedValue(), currentSize - numInvalid, drawnCandidates, numLevels);
346 if ((bestCandidateFailureProbability > m_options.m_probability ||
348 (!m_autoAcceptSize || trial->
UpperBound() < m_autoAcceptSize))
352 std::sort(candidates.begin(), candidates.end());
354 size_t bestCandidate = candidates.size() - 1;
355 bestCandidateFailureProbability = CandidateFailureProbability(
356 candidates.back().ExpectedValue(), currentSize - numInvalid, drawnCandidates, numLevels);
358 for (
size_t i = bestCandidate - 1; i != -1; --i)
360 float iFailProb = CandidateFailureProbability(
361 candidates[i].ExpectedValue(), currentSize - numInvalid, drawnCandidates, numLevels);
362 if (iFailProb > m_options.m_probability || candidates[i].UpperBound() < minSize ||
363 candidates[i].UpperBound() < candidates[bestCandidate].LowerBound())
368 if (candidates[bestCandidate].IsEquivalent(
369 candidates[i], pc, m_options.m_epsilon, m_options.m_normalThresh))
373 bool isEquivalent =
false;
374 for (
size_t j = 0; j < beatenCands.
size(); ++j)
376 if (beatenCands[j]->IsEquivalent(
377 candidates[i], pc, m_options.m_epsilon, m_options.m_normalThresh))
389 if (candidates[i].UpperBound() > candidates[bestCandidate].UpperBound() &&
390 candidates[i].LowerBound() < candidates[bestCandidate].LowerBound())
392 bool dontBreak = candidates[i].ImproveBounds(octrees,
396 m_options.m_bitmapEpsilon,
397 maxImproveSubsetDuringMaxSearch);
398 iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
399 currentSize - numInvalid,
407 else if (candidates[bestCandidate].UpperBound() > candidates[i].UpperBound() &&
408 candidates[bestCandidate].LowerBound() < candidates[i].LowerBound())
411 candidates[bestCandidate].ImproveBounds(octrees,
415 m_options.m_bitmapEpsilon,
416 maxImproveSubsetDuringMaxSearch);
417 bestCandidateFailureProbability =
418 CandidateFailureProbability(candidates[bestCandidate].ExpectedValue(),
419 currentSize - numInvalid,
430 candidates[bestCandidate].ImproveBounds(octrees,
434 m_options.m_bitmapEpsilon,
435 maxImproveSubsetDuringMaxSearch);
436 dontBreak = candidates[i].ImproveBounds(octrees,
440 m_options.m_bitmapEpsilon,
441 maxImproveSubsetDuringMaxSearch) ||
443 iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
444 currentSize - numInvalid,
447 bestCandidateFailureProbability =
448 CandidateFailureProbability(candidates[bestCandidate].ExpectedValue(),
449 currentSize - numInvalid,
457 }
while (bestCandidateFailureProbability <= m_options.m_probability &&
458 iFailProb <= m_options.m_probability && candidates[i].UpperBound() >= minSize &&
459 candidates[bestCandidate].UpperBound() >= minSize &&
460 candidates[i].UpperBound() > candidates[bestCandidate].LowerBound() &&
461 candidates[i].LowerBound() < candidates[bestCandidate].UpperBound());
462 if ((candidates[i] > candidates[bestCandidate] ||
463 bestCandidateFailureProbability > m_options.m_probability ||
464 candidates[bestCandidate].UpperBound() < minSize) &&
465 (iFailProb <= m_options.m_probability && candidates[i].UpperBound() >= minSize))
467 while (iFailProb <= m_options.m_probability && candidates[i].UpperBound() >= minSize &&
468 candidates[i] > candidates[bestCandidate] &&
469 candidates[i].ImproveBounds(octrees,
473 m_options.m_bitmapEpsilon,
476 iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
477 currentSize - numInvalid,
481 if (candidates[i] > candidates[bestCandidate])
483 beatenCands.
push_back(&candidates[bestCandidate]);
485 bestCandidateFailureProbability = iFailProb;
496 if (bestCandidateFailureProbability > m_options.m_probability ||
497 candidates[bestCandidate].UpperBound() < minSize)
503 while (candidates[bestCandidate].ImproveBounds(
504 octrees, pc, scoreVisitor, currentSize, m_options.m_bitmapEpsilon, octrees.
size()))
507 bestCandidateFailureProbability =
508 CandidateFailureProbability(candidates[bestCandidate].ExpectedValue(),
509 currentSize - numInvalid,
513 if ((bestCandidateFailureProbability <= m_options.m_probability &&
514 candidates[bestCandidate].UpperBound() >= minSize) ||
515 (m_autoAcceptSize && candidates[bestCandidate].UpperBound() >= m_autoAcceptSize))
517 std::swap(candidates.back(), candidates[bestCandidate]);
518 *candidateFailProb = bestCandidateFailureProbability;
521 std::sort(candidates.begin(), candidates.end() );
531 const auto endtime = std::chrono::steady_clock::now() + m_options.m_maxruntime;
532 const auto timeout = [&]
535 endtime <= std::chrono::steady_clock::now();
537 size_t pcSize = endIdx - beginIdx;
541 srand((
unsigned int)time(NULL));
544 CandidatesType candidates;
547 subsetScoreVisitor(m_options.m_epsilon, m_options.m_normalThresh);
549 globalScoreVisitor(3 * m_options.m_epsilon, m_options.m_normalThresh);
552 size_t subsets = std::max(
int(std::floor(std::log((
float)pcSize) / std::log(2.f))) - 9, 2);
558 for (
size_t i = octrees.
size(); i;)
561 size_t subsetSize = pcSize;
564 subsetSize = subsetSize >> 1;
566 size_t bucketSize = pcSize / subsetSize;
567 for (
size_t j = 0; j < subsetSize; ++j)
570 index += j * bucketSize;
575 subsetIndices[j] =
index + beginIdx;
578 std::sort(subsetIndices.
begin(), subsetIndices.
end(), std::greater<size_t>());
579 for (
size_t j = pcSize - 1, i = 0; i < subsetIndices.
size(); --j, ++i)
581 std::swap(pc[j + beginIdx], pc[subsetIndices[i]]);
585 octrees[i]->ContainedData(&pc);
586 octrees[i]->DataRange(pcSize - subsetSize + beginIdx, pcSize + beginIdx);
587 octrees[i]->MaxBucketSize() = 20;
588 octrees[i]->MaxSubdivisionLevel() = 10;
589 octrees[i]->Build(bcube);
590 pcSize -= subsetSize;
593 pcSize = endIdx - beginIdx;
597 for (
size_t i = 0; i < pcSize; ++i)
599 globalOctreeIndices[i] = i + beginIdx;
602 globalOctree.MaxBucketSize() = 20;
603 globalOctree.MaxSubdivisionLevel() = 10;
604 globalOctree.IndexedData(globalOctreeIndices.
begin(), globalOctreeIndices.
end(), pc.
begin());
605 globalOctree.
Build(bcube);
606 size_t globalOctTreeMaxNodeDepth = globalOctree.MaxDepth();
609 for (
size_t i = 0; i < sampleLevelProbability.
size(); ++i)
611 sampleLevelProbability[i] = 1.0 / sampleLevelProbability.
size();
613 size_t drawnCandidates = 0;
615 float maxForgottenCandidate = 0;
618 size_t numShapes = 0;
620 size_t numInvalid = 0;
627 size_t currentSize = pcSize;
631 for (
size_t i = 0; i < sampleLevelScores.
size(); ++i)
633 sampleLevelScores[i] = std::make_pair(0.f, 0u);
636 sampleLevelProbSum[0] = sampleLevelProbability[0];
637 for (
size_t i = 1; i < sampleLevelProbSum.
size() - 1; ++i)
638 sampleLevelProbSum[i] = sampleLevelProbability[i] + sampleLevelProbSum[i - 1];
639 sampleLevelProbSum[sampleLevelProbSum.
size() - 1] = 1;
641 float bestExpectedValue = 0;
642 if (candidates.
size())
646 bestExpectedValue = std::min((
float)(currentSize - numInvalid), bestExpectedValue);
649 GenerateCandidates(globalOctree,
660 }
while (CandidateFailureProbability(bestExpectedValue,
661 currentSize - numInvalid,
663 globalOctTreeMaxNodeDepth) > m_options.m_probability &&
664 CandidateFailureProbability(m_options.m_minSupport,
665 currentSize - numInvalid,
667 globalOctTreeMaxNodeDepth) > m_options.m_probability &&
670 float bestCandidateFailureProbability;
671 float failureProbability = std::numeric_limits<float>::infinity();
672 bool foundCandidate =
false;
673 size_t firstCandidateSize = 0;
674 while (FindBestCandidate(
682 std::max((
size_t)m_options.m_minSupport, (
size_t)(0.8f * firstCandidateSize)),
683 globalOctTreeMaxNodeDepth,
684 &maxForgottenCandidate,
685 &bestCandidateFailureProbability))
692 for (
size_t i = 0; i < sampleLevelScores.
size(); ++i)
694 sampleLevelScores[i] = std::make_pair(0.f, 0u);
696 for (
size_t i = 0; i < candidates.
size(); ++i)
701 std::min(sampleLevelScores.
size() - 1, candidates[i].Level());
702 ++sampleLevelScores[candLevel].first;
703 ++sampleLevelScores[candLevel].second;
706 UpdateLevelWeights(0.5f, sampleLevelScores, &sampleLevelProbability);
708 foundCandidate =
true;
709 if (bestCandidateFailureProbability < failureProbability)
711 failureProbability = bestCandidateFailureProbability;
713 std::string candidateDescription;
722 float oldScore, newScore;
723 size_t oldSize, newSize;
728 3 * m_options.m_epsilon,
729 m_options.m_normalThresh,
730 m_options.m_bitmapEpsilon);
731 newSize = std::max(clone.
Size(), candidates.
back().
Size());
732 bool allowDifferentShapes =
false;
733 size_t fittingIter = 0;
739 std::pair<size_t, float> score;
752 3 * m_options.m_epsilon,
753 m_options.m_normalThresh,
754 m_options.m_bitmapEpsilon);
755 newSize = clone.
Size();
757 if (newScore > oldScore && newSize > m_options.m_minSupport)
762 allowDifferentShapes =
false;
763 }
while (newScore > oldScore && fittingIter < 3);
772 std::cout <<
"ERROR: candidate size == 0 after fitting" << std::endl;
778 for (
size_t i = 0; i < candidates.
back().Indices()->size(); ++i)
780 shapeIndex[(*(candidates.
back().Indices()))[i]] = numShapes;
785 drawnCandidates = std::pow(1.f - (candidates.
back().
Indices()->
size() /
786 float(currentSize - numInvalid)),
791 if (numInvalid > currentSize / 4)
797 size_t begin = beginIdx, end = beginIdx + currentSize;
801 int shapeIt = shapes->size() - numShapes;
802 for (
size_t i = 0; i < numShapes; ++i, ++shapeIt)
804 shapeIterators[i] = end -= ((*shapes)[shapeIt]).second;
808 for (
size_t i = beginIdx, j = 0; i < beginIdx + currentSize; ++i)
809 if (shapeIndex[i] < 0)
811 if (i >= octrees[j]->end() - pc.
begin() + beginIdx &&
812 j < octrees.
size() - 1)
816 shapeIndex[i] = begin++;
821 shapeIndex[i] = shapeIterators[shapeIndex[i]]++;
825 size_t mergedSubsets = 0;
826 if (subsetSizes[0] < 500 && subsetSizes.
size() > 1)
829 while (subsetSizes[0] < 500 && subsetSizes.
size() > 1)
831 subsetSizes[1] += subsetSizes[0];
840 size_t minInvalidIndex = currentSize - numInvalid + beginIdx;
841#pragma parallel for schedule(static)
842 for (intptr_t i = 0, j = 0; i < globalOctreeIndices.
size(); ++i)
843 if (shapeIndex[globalOctreeIndices[i]] < minInvalidIndex)
845 globalOctreeIndices[j++] = shapeIndex[globalOctreeIndices[i]];
847 globalOctreeIndices.
resize(currentSize - numInvalid);
850#pragma parallel for schedule(static)
851 for (intptr_t i = 0; i < candidates.
size(); ++i)
852 candidates[i].Reindex(shapeIndex,
857 currentSize - numInvalid,
859 m_options.m_normalThresh,
860 m_options.m_bitmapEpsilon);
863 for (
size_t i = beginIdx; i < beginIdx + currentSize; ++i)
864 while (i != shapeIndex[i])
867 std::swap(shapeIndex[i], shapeIndex[shapeIndex[i]]);
877 reindex(beginIdx + subsetSizes[0]);
878 for (
size_t i = 0; i < shuffleIndices.size(); ++i)
880 shuffleIndices[i] = i;
884 octrees[0]->ContainedData(&pc);
885 octrees[0]->DataRange(beginIdx, beginIdx + subsetSizes[0]);
886 octrees[0]->MaxBucketSize() = 20;
887 octrees[0]->MaxSubdivisionLevel() = 10;
888 octrees[0]->ShuffleIndices(&shuffleIndices);
889 octrees[0]->Build(bcube);
890 octrees[0]->ShuffleIndices(NULL);
891 for (
size_t i = 0; i < shuffleIndices.size(); ++i)
893 reindex[shuffleIndices[i]] = i;
896#pragma omp parallel for schedule(static)
897 for (intptr_t i = 0; i < globalOctreeIndices.
size(); ++i)
898 if (globalOctreeIndices[i] < reindex.
size())
900 globalOctreeIndices[i] = reindex[globalOctreeIndices[i]];
903#pragma omp parallel for schedule(static, 100)
904 for (intptr_t i = 0; i < candidates.
size(); ++i)
906 candidates[i].Reindex(reindex);
908 for (
size_t i = 1, begin = subsetSizes[0] + beginIdx; i < octrees.
size();
909 begin += subsetSizes[i], ++i)
911 octrees[i]->DataRange(begin, begin + subsetSizes[i]);
912 octrees[i]->Rebuild();
913 if (octrees[i]->Root()->Size() != subsetSizes[i])
915 std::cout <<
"ERROR IN REBUILD!!!!" << std::endl;
920 for (
size_t i = 0, begin = beginIdx; i < octrees.
size();
921 begin += subsetSizes[i], ++i)
923 octrees[i]->DataRange(begin, begin + subsetSizes[i]);
924 octrees[i]->Rebuild();
928 currentSize = globalOctreeIndices.
size();
930 globalOctree.IndexedRange(globalOctreeIndices.
begin(), globalOctreeIndices.
end());
931 globalOctTreeMaxNodeDepth = globalOctree.Rebuild();
932 if (globalOctree.Root()->Size() != globalOctreeIndices.
size())
934 std::cout <<
"ERROR IN GLOBAL REBUILD!" << std::endl;
936 sampleLevelProbability.
resize(globalOctTreeMaxNodeDepth + 1);
940 shapeIndex.
begin() + beginIdx, shapeIndex.
begin() + beginIdx + currentSize, -1);
947#pragma parallel for schedule(static, 100)
948 for (
size_t i = 0; i < candidates.
size(); ++i)
949 candidates[i].RecomputeBounds(octrees,
952 currentSize - numInvalid,
954 m_options.m_normalThresh,
955 m_options.m_bitmapEpsilon);
958 std::sort(candidates.
begin(), candidates.
end(), std::greater<Candidate>());
959 size_t remainingCandidates = 0;
960 for (
size_t i = 0; i < candidates.
size(); ++i)
961 if (candidates[i].ExpectedValue() >= m_options.m_minSupport &&
962 candidates[i].Size() > 0)
964 candidates[remainingCandidates++] = candidates[i];
966 candidates.
resize(remainingCandidates);
970 std::sort(candidates.
begin(), candidates.
end(), std::greater<Candidate>());
971 size_t remainingCandidates = 0;
972 size_t nonConnectedCount = 0;
973 for (
size_t i = 0; i < candidates.
size(); ++i)
974 if (candidates[i].ExpectedValue() >= m_options.m_minSupport &&
975 (candidates[i].ComputedSubsets() > octrees.
size() - 3 ||
976 nonConnectedCount++ < 500))
978 candidates[remainingCandidates++] = candidates[i];
980 else if (candidates[i].ExpectedValue() > maxForgottenCandidate)
982 maxForgottenCandidate = candidates[i].ExpectedValue();
984 candidates.
resize(remainingCandidates);
992 }
while (CandidateFailureProbability(m_options.m_minSupport,
993 currentSize - numInvalid,
995 globalOctTreeMaxNodeDepth) > m_options.m_probability &&
996 (currentSize - numInvalid) >= m_options.m_minSupport && !timeout());
1004 size_t begin = beginIdx, end = beginIdx + currentSize;
1007 int shapeIt = shapes->size() - numShapes;
1008 for (
size_t i = 0; i < numShapes; ++i, ++shapeIt)
1010 shapeIterators[i] = end -= ((*shapes)[shapeIt]).second;
1013 for (
size_t i = beginIdx; i < beginIdx + currentSize; ++i)
1014 if (shapeIndex[i] < 0)
1016 shapeIndex[i] = begin++;
1020 shapeIndex[i] = shapeIterators[shapeIndex[i]]++;
1024 for (
size_t i = beginIdx; i < beginIdx + currentSize; ++i)
1025 while (i != shapeIndex[i])
1028 std::swap(shapeIndex[i], shapeIndex[shapeIndex[i]]);
1032 for (
size_t i = 0; i < octrees.
size(); ++i)
1037 size_t eidx = endIdx;
1038 for (
size_t i = 0; i < shapes->size(); ++i)
1040 size_t bidx = eidx - (*shapes)[i].second;
1041 (*shapes)[i].first->OptimizeParametrization(pc, bidx, eidx, m_options.m_bitmapEpsilon);
1046 for (
size_t i = shapes->size(); i != 0; --i)
1048 if (shapes->at(i - 1).second == 0)
1050 shapes->erase(shapes->begin() + i - 1);
1053 return currentSize - numInvalid;
1064 for (
size_t tries = 0; tries < m_maxCandTries; tries++)
1071 first = oct.Dereference(
rn_rand() % oct.size());
1072 }
while (shapeIndex[first] != -1);
1075 std::pair<size_t, size_t> nodeRange;
1078 if ((*node)->Size() < numSamples)
1083 while (samples->
size() < numSamples)
1088 i = oct.Dereference(
rn_rand() % (*node)->Size() + nodeRange.first);
1089 }
while ((shapeIndex[i] != -1 ||
1090 std::find(samples->
begin(), samples->
end(), i) != samples->
end()) &&
1099 if (samples->
size() == numSamples)
1108RansacShapeDetector::Fit(
bool allowDifferentShapes,
1113 std::pair<size_t, float>* score)
const
1115 if (!m_constructors.size())
1119 PrimitiveShape* bestShape = NULL;
1121 bestShape = initialShape.
LSFit(
1122 pc, m_options.m_epsilon, m_options.m_normalThresh, begin, end, score);
GfxTL::AACubeTree< 3, ScoreAACubeTreeStrategy< 3, RebuildAACubeTreeStrategy< GfxTL::BucketSizeMaxLevelSubdivisionTreeStrategy< GfxTL::CellLevelTreeStrategy< GfxTL::CellCenterAACubeTreeStrategy< 3, GfxTL::BaseAACubeTreeStrategy< GfxTL::CellRangeDataTreeStrategy< GfxTL::NullTreeStrategy, GfxTL::IteratedIndexedIteratorTreeDataKernel< MiscLib::Vector< size_t >::iterator, PointCloud::const_iterator > > > > > > > > > IndexedOctreeType
GfxTL::AACubeTree< 3, ScoreAACubeTreeStrategy< 3, RebuildAACubeTreeStrategy< GfxTL::BucketSizeMaxLevelSubdivisionTreeStrategy< GfxTL::CellLevelTreeStrategy< GfxTL::CellCenterAACubeTreeStrategy< 3, GfxTL::BaseAACubeTreeStrategy< GfxTL::CellRangeDataTreeStrategy< GfxTL::NullTreeStrategy, GfxTL::ShuffleIndicesTreeDataKernelStrategy< GfxTL::ImmediateRangeTreeDataKernel< PointCloud >, MiscLib::Vector< size_t > > > > > > > > > > ImmediateOctreeType
bool IsEquivalent(const Candidate &c, const PointCloud &pc, float epsilon, float normalThresh) const
void GlobalScore(ScoreVisitorT &scoreVisitor, const IndexedOctreeType &oct)
MiscLib::RefCounted< MiscLib::Vector< size_t > > * Indices()
void ConnectedComponent(const PointCloud &pc, float bitmapEpsilon, float *borderRatio=0)
float ExpectedValue() const
size_t ComputedSubsets() const
void Clone(Candidate *c) const
bool ImproveBounds(const MiscLib::Vector< ImmediateOctreeType * > &octrees, const PointCloud &pc, ScoreVisitorT &scoreVisitor, size_t currentSize, float bitmapEpsilon, size_t maxSubset, size_t minPoints=500)
float GlobalWeightedScore(ScoreVisitorT &scoreVisitor, const IndexedOctreeType &oct, const PointCloud &pc, float epsilon, float normalThresh, float bitmapEpsilon)
const CellType * NodeContainingPoint(const PointT &point, size_t maxLevel, size_t minSize, CellRange *range) const
AACubeTreeCell< DimT, typename ScoreAACubeTreeStrategy< 3, RebuildAACubeTreeStrategy< GfxTL::BucketSizeMaxLevelSubdivisionTreeStrategy< GfxTL::CellLevelTreeStrategy< GfxTL::CellCenterAACubeTreeStrategy< 3, GfxTL::BaseAACubeTreeStrategy< GfxTL::CellRangeDataTreeStrategy< GfxTL::NullTreeStrategy, GfxTL::IteratedIndexedIteratorTreeDataKernel< MiscLib::Vector< size_t >::iterator, PointCloud::const_iterator > > > > > > > >::CellData > CellType
void Bound(const Points &points, size_t size)
void resize(size_type s, const value_type &v)
unsigned int Release() const
void resize(size_type s, const value_type &v)
const PrimitiveShapeConstructor ** const_iterator
PrimitiveShapeConstructor ** iterator
void push_back(const T &v)
void swapPoints(unsigned int i, unsigned int j)
PrimtiveShape is a shape primitive in conjunction with a parametrization.
virtual PrimitiveShape * LSFit(const PointCloud &pc, float epsilon, float normalThresh, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end, std::pair< size_t, float > *score) const =0
virtual void Description(std::string *s) const =0
virtual void DistanceAndNormalDeviation(const Vec3f &p, const Vec3f &n, std::pair< float, float > *dn) const =0
virtual ~RansacShapeDetector()
size_t Detect(PointCloud &pc, size_t begin, size_t end, MiscLib::Vector< std::pair< MiscLib::RefCountPtr< PrimitiveShape >, size_t > > *shapes)
void Add(PrimitiveShapeConstructor *c)
void SetShapeIndex(const MiscLib::Vector< int > &shapeIndex)
double s(double t, double s0, double v0, double a0, double j)
bool operator()(const Candidate *a, const Candidate *b) const
unsigned int m_minSupport
static constexpr auto invalidRuntime