40 iend = m_constructors.
end(); i != iend; ++i)
50 if (
c->RequiredSamples() > m_reqSamples)
52 m_reqSamples =
c->RequiredSamples();
56 size_t RansacShapeDetector::StatBucket(
float score)
const
58 return (
size_t)
std::max(0.f, std::floor((std::log(score) - std::log((
float)m_options.
m_minSupport)) / std::log(1.21f)) + 1);
65 void RansacShapeDetector::UpdateLevelWeights(
float factor,
70 sampleLevelProbability->
size());
71 double newSampleLevelProbabilitySum = 0;
72 for (
size_t i = 0; i < newSampleLevelProbability.size(); ++i)
74 if ((*sampleLevelProbability)[i] > 0)
76 newSampleLevelProbability[i] = (levelScores[i].first / (*sampleLevelProbability)[i]);
80 newSampleLevelProbability[i] = 0;
82 newSampleLevelProbabilitySum += newSampleLevelProbability[i];
85 for (
size_t i = 0; i < newSampleLevelProbability.size(); ++i)
87 newSampleLevelProbability[i] = .9f * newSampleLevelProbability[i] + .1f * newSampleLevelProbabilitySum / levelScores.size();
88 newSum += newSampleLevelProbability[i];
90 for (
size_t i = 0; i < sampleLevelProbability->
size(); ++i)
92 (*sampleLevelProbability)[i] = (1.f - factor) * (*sampleLevelProbability)[i] +
93 factor * (newSampleLevelProbability[i] / newSum);
97 template<
class ScoreVisitorT >
98 void RansacShapeDetector::GenerateCandidates(
102 size_t currentSize,
size_t numInvalid,
104 size_t* drawnCandidates,
106 float* bestExpectedValue,
107 CandidatesType* candidates)
const
113 ScoreVisitorT scoreVisitorCopy(scoreVisitor);
114 #pragma omp for schedule(dynamic, 10) reduction(+:genCands)
115 for (
int candIter = 0; candIter < 200; ++candIter)
118 double s = ((double)rand()) / (
double)RAND_MAX;
119 size_t sampleLevel = 0;
120 for (; sampleLevel < sampleLevelProbSum.
size() - 1; ++sampleLevel)
121 if (sampleLevelProbSum[sampleLevel] >=
s)
128 if (!DrawSamplesStratified(globalOctree, m_reqSamples, sampleLevel,
129 scoreVisitorCopy.GetShapeIndex(), &samples, &node))
135 size_t c = samples.
size();
137 for (
size_t i = 0; i < samples.
size(); ++i)
139 samplePoints[i] = globalOctree.at(samples[i]).pos;
140 samplePoints[i +
c] = globalOctree.at(samples[i]).normal;
145 iend = m_constructors.
end(); i != iend; ++i)
147 if ((*i)->RequiredSamples() > samples.
size()
148 || !(shape = (*i)->Construct(samplePoints)))
153 std::pair< float, float > dn;
154 bool verified =
true;
155 for (
size_t i = 0; i <
c; ++i)
158 if (!scoreVisitorCopy.PointCompFunc()(dn.first, dn.second))
171 cand.Indices()->Release();
173 cand.ImproveBounds(octrees,
pc, scoreVisitorCopy,
179 (*sampleLevelScores)[node->Level()].first += cand.ExpectedValue();
180 ++(*sampleLevelScores)[node->Level()].second;
187 (*sampleLevelScores)[node->Level()].first += cand.ExpectedValue();
188 ++(*sampleLevelScores)[node->Level()].second;
189 candidates->push_back(cand);
190 if (cand.ExpectedValue() > *bestExpectedValue)
192 *bestExpectedValue = cand.ExpectedValue();
198 *drawnCandidates += genCands;
209 template<
class ScoreVisitorT >
210 bool RansacShapeDetector::FindBestCandidate(CandidatesType& candidates,
212 ScoreVisitorT& scoreVisitor,
size_t currentSize,
213 size_t drawnCandidates,
size_t numInvalid,
size_t minSize,
float numLevels,
214 float* maxForgottenCandidate,
float* candidateFailProb)
const
216 if (!candidates.size())
220 size_t maxImproveSubsetDuringMaxSearch = octrees.
size();
222 std::sort(candidates.begin(), candidates.end());
224 if (candidates.size() && candidates.back().ExpectedValue() < *maxForgottenCandidate)
228 drawnCandidates =
std::max(candidates.size(), (
size_t)1);
229 *maxForgottenCandidate = 0;
233 for (
size_t i = candidates.size() - 1; i != -1; --i)
235 if (CandidateFailureProbability(
236 candidates[i].ExpectedValue(),
237 currentSize - numInvalid, drawnCandidates, numLevels) > m_options.
m_probability)
244 if (!candHeap.
size())
255 float bestCandidateFailureProbability;
256 while (candHeap.
size())
261 std::pop_heap(candHeap.
begin(), candHeap.
end(),
266 bool isEquivalent =
false;
267 for (
size_t j = 0; j < beatenCands.
size(); ++j)
269 if (beatenCands[j]->IsEquivalent(*candHeap.
front(),
pc,
278 std::pop_heap(candHeap.
begin(), candHeap.
end(),
283 bestCandidateFailureProbability = CandidateFailureProbability(
285 currentSize - numInvalid, drawnCandidates, numLevels);
286 while ((bestCandidateFailureProbability <= m_options.
m_probability)
287 && (*trial >= *candHeap.
front())
292 bestCandidateFailureProbability = CandidateFailureProbability(
294 currentSize - numInvalid, drawnCandidates, numLevels);
296 if (bestCandidateFailureProbability <= m_options.
m_probability
299 && *trial >= *candHeap.
front())
303 if (bestCandidateFailureProbability <= m_options.
m_probability
314 trial = candHeap.
front();
318 bestCandidateFailureProbability = CandidateFailureProbability(
320 currentSize - numInvalid, drawnCandidates, numLevels);
321 while (bestCandidateFailureProbability <= m_options.
m_probability
326 bestCandidateFailureProbability = CandidateFailureProbability(
328 currentSize - numInvalid, drawnCandidates, numLevels);
330 if ((bestCandidateFailureProbability > m_options.
m_probability
332 && (!m_autoAcceptSize || trial->
UpperBound() < m_autoAcceptSize))
336 std::sort(candidates.begin(), candidates.end());
338 size_t bestCandidate = candidates.size() - 1;
339 bestCandidateFailureProbability = CandidateFailureProbability(
340 candidates.back().ExpectedValue(),
341 currentSize - numInvalid, drawnCandidates, numLevels);
343 for (
size_t i = bestCandidate - 1; i != -1; --i)
345 float iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
346 currentSize - numInvalid, drawnCandidates, numLevels);
347 if (iFailProb > m_options.
m_probability || candidates[i].UpperBound() < minSize
348 || candidates[i].UpperBound() < candidates[bestCandidate].LowerBound())
353 if (candidates[bestCandidate].IsEquivalent(candidates[i],
pc,
358 bool isEquivalent =
false;
359 for (
size_t j = 0; j < beatenCands.
size(); ++j)
361 if (beatenCands[j]->IsEquivalent(candidates[i],
pc,
374 if (candidates[i].UpperBound() > candidates[bestCandidate].UpperBound()
375 && candidates[i].LowerBound() < candidates[bestCandidate].LowerBound())
377 bool dontBreak = candidates[i].ImproveBounds(octrees,
pc, scoreVisitor,
379 maxImproveSubsetDuringMaxSearch);
380 iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
381 currentSize - numInvalid, drawnCandidates, numLevels);
387 else if (candidates[bestCandidate].UpperBound() > candidates[i].UpperBound()
388 && candidates[bestCandidate].LowerBound() < candidates[i].LowerBound())
390 bool dontBreak = candidates[bestCandidate].ImproveBounds(octrees,
pc,
392 maxImproveSubsetDuringMaxSearch);
393 bestCandidateFailureProbability = CandidateFailureProbability(
394 candidates[bestCandidate].ExpectedValue(),
395 currentSize - numInvalid, drawnCandidates, numLevels);
403 bool dontBreak = candidates[bestCandidate].ImproveBounds(octrees,
pc,
405 maxImproveSubsetDuringMaxSearch);
406 dontBreak = candidates[i].ImproveBounds(octrees,
pc, scoreVisitor,
408 maxImproveSubsetDuringMaxSearch)
410 iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
411 currentSize - numInvalid, drawnCandidates, numLevels);
412 bestCandidateFailureProbability = CandidateFailureProbability(
413 candidates[bestCandidate].ExpectedValue(),
414 currentSize - numInvalid, drawnCandidates, numLevels);
421 while (bestCandidateFailureProbability <= m_options.
m_probability
423 && candidates[i].UpperBound() >= minSize
424 && candidates[bestCandidate].UpperBound() >= minSize
425 && candidates[i].UpperBound() > candidates[bestCandidate].LowerBound()
426 && candidates[i].LowerBound() < candidates[bestCandidate].UpperBound()
429 candidates[i] > candidates[bestCandidate]
431 || candidates[bestCandidate].UpperBound() < minSize)
432 && (iFailProb <= m_options.
m_probability && candidates[i].UpperBound() >= minSize))
434 while (iFailProb <= m_options.
m_probability && candidates[i].UpperBound() >= minSize
435 && candidates[i] > candidates[bestCandidate]
436 && candidates[i].ImproveBounds(octrees,
pc, scoreVisitor,
439 iFailProb = CandidateFailureProbability(candidates[i].ExpectedValue(),
440 currentSize - numInvalid, drawnCandidates, numLevels);
442 if (candidates[i] > candidates[bestCandidate])
444 beatenCands.
push_back(&candidates[bestCandidate]);
446 bestCandidateFailureProbability = iFailProb;
457 if (bestCandidateFailureProbability > m_options.
m_probability
458 || candidates[bestCandidate].UpperBound() < minSize)
464 while (candidates[bestCandidate].ImproveBounds(octrees,
pc, scoreVisitor,
467 bestCandidateFailureProbability = CandidateFailureProbability(
468 candidates[bestCandidate].ExpectedValue(),
469 currentSize - numInvalid, drawnCandidates, numLevels);
471 if ((bestCandidateFailureProbability <= m_options.
m_probability
472 && candidates[bestCandidate].UpperBound() >= minSize)
473 || (m_autoAcceptSize && candidates[bestCandidate].UpperBound() >= m_autoAcceptSize))
475 std::swap(candidates.back(), candidates[bestCandidate]);
476 *candidateFailProb = bestCandidateFailureProbability;
479 std::sort(candidates.begin(), candidates.end());
487 const auto endtime = std::chrono::steady_clock::now() + m_options.
m_maxruntime;
488 const auto timeout = [&]
491 && endtime <= std::chrono::steady_clock::now();
493 size_t pcSize = endIdx - beginIdx;
497 srand((
unsigned int)time(NULL));
510 size_t subsets =
std::max(
int(std::floor(std::log((
float)pcSize) / std::log(2.f))) - 9, 2);
512 bcube.
Bound(
pc.begin() + beginIdx,
pc.begin() + endIdx);
516 for (
size_t i = octrees.
size(); i;)
519 size_t subsetSize = pcSize;
522 subsetSize = subsetSize >> 1;
524 size_t bucketSize = pcSize / subsetSize;
525 for (
size_t j = 0; j < subsetSize; ++j)
528 index += j * bucketSize;
533 subsetIndices[j] =
index + beginIdx;
536 std::sort(subsetIndices.
begin(), subsetIndices.
end(),
537 std::greater< size_t >());
538 for (
size_t j = pcSize - 1, i = 0; i < subsetIndices.
size(); --j, ++i)
544 octrees[i]->ContainedData(&
pc);
545 octrees[i]->DataRange(pcSize - subsetSize + beginIdx,
547 octrees[i]->MaxBucketSize() = 20;
548 octrees[i]->MaxSubdivisionLevel() = 10;
549 octrees[i]->Build(bcube);
550 pcSize -= subsetSize;
553 pcSize = endIdx - beginIdx;
557 for (
size_t i = 0; i < pcSize; ++i)
559 globalOctreeIndices[i] = i + beginIdx;
562 globalOctree.MaxBucketSize() = 20;
563 globalOctree.MaxSubdivisionLevel() = 10;
564 globalOctree.IndexedData(globalOctreeIndices.
begin(),
565 globalOctreeIndices.
end(),
pc.begin());
566 globalOctree.
Build(bcube);
567 size_t globalOctTreeMaxNodeDepth = globalOctree.MaxDepth();
570 globalOctTreeMaxNodeDepth + 1);
571 for (
size_t i = 0; i < sampleLevelProbability.
size(); ++i)
573 sampleLevelProbability[i] = 1.0 / sampleLevelProbability.
size();
575 size_t drawnCandidates = 0;
577 float maxForgottenCandidate = 0;
580 size_t numShapes = 0;
582 size_t numInvalid = 0;
587 subsetScoreVisitor.SetShapeIndex(shapeIndex);
588 globalScoreVisitor.SetShapeIndex(shapeIndex);
589 size_t currentSize = pcSize;
593 sampleLevelProbability.
size());
594 for (
size_t i = 0; i < sampleLevelScores.
size(); ++i)
596 sampleLevelScores[i] = std::make_pair(0.f, 0u);
599 sampleLevelProbSum[0] = sampleLevelProbability[0];
600 for (
size_t i = 1; i < sampleLevelProbSum.
size() - 1; ++i)
601 sampleLevelProbSum[i] = sampleLevelProbability[i] +
602 sampleLevelProbSum[i - 1];
603 sampleLevelProbSum[sampleLevelProbSum.
size() - 1] = 1;
605 float bestExpectedValue = 0;
606 if (candidates.
size())
608 bestExpectedValue = candidates.
back().ExpectedValue();
610 bestExpectedValue =
std::min((
float)(currentSize - numInvalid), bestExpectedValue);
613 GenerateCandidates(globalOctree,
614 octrees,
pc, subsetScoreVisitor,
615 currentSize, numInvalid,
622 while (CandidateFailureProbability(bestExpectedValue,
623 currentSize - numInvalid, drawnCandidates,
626 currentSize - numInvalid, drawnCandidates,
630 float bestCandidateFailureProbability;
631 float failureProbability = std::numeric_limits< float >::infinity();
632 bool foundCandidate =
false;
633 size_t firstCandidateSize = 0;
634 while (FindBestCandidate(candidates, octrees,
pc, subsetScoreVisitor,
635 currentSize, drawnCandidates, numInvalid,
637 globalOctTreeMaxNodeDepth, &maxForgottenCandidate,
638 &bestCandidateFailureProbability))
643 firstCandidateSize = (size_t)candidates.
back().LowerBound();
645 for (
size_t i = 0; i < sampleLevelScores.
size(); ++i)
647 sampleLevelScores[i] = std::make_pair(0.f, 0u);
649 for (
size_t i = 0; i < candidates.
size(); ++i)
651 if (candidates[i].ExpectedValue() * 1.4f > candidates.
back().ExpectedValue())
653 size_t candLevel =
std::min(sampleLevelScores.
size() - 1,
654 candidates[i].Level());
655 ++sampleLevelScores[candLevel].first;
656 ++sampleLevelScores[candLevel].second;
659 UpdateLevelWeights(0.5f, sampleLevelScores, &sampleLevelProbability);
661 foundCandidate =
true;
662 if (bestCandidateFailureProbability < failureProbability)
664 failureProbability = bestCandidateFailureProbability;
666 std::string candidateDescription;
667 candidates.
back().Shape()->Description(&candidateDescription);
671 candidates.
back().GlobalScore(globalScoreVisitor, globalOctree);
674 candidates.
back().Clone(&clone);
675 float oldScore, newScore;
676 size_t oldSize, newSize;
682 bool allowDifferentShapes =
false;
683 size_t fittingIter = 0;
689 std::pair< size_t, float > score;
699 newSize = clone.
Size();
701 if (newScore > oldScore && newSize > m_options.
m_minSupport)
706 allowDifferentShapes =
false;
708 while (newScore > oldScore && fittingIter < 3);
712 candidates.
back().GlobalScore(globalScoreVisitor, globalOctree);
715 if (candidates.
back().Size() == 0)
717 std::cout <<
"ERROR: candidate size == 0 after fitting" << std::endl;
722 candidates.
back().Indices()->size()));
723 for (
size_t i = 0; i < candidates.
back().Indices()->size(); ++i)
725 shapeIndex[(*(candidates.
back().Indices()))[i]] = numShapes;
730 drawnCandidates = std::pow(1.f - (candidates.
back().Indices()->size() /
731 float(currentSize - numInvalid)), 3.f) * drawnCandidates;
732 numInvalid += candidates.
back().Indices()->size();
734 if (numInvalid > currentSize / 4)
740 size_t begin = beginIdx, end = beginIdx + currentSize;
744 int shapeIt =
shapes->size() - numShapes;
745 for (
size_t i = 0; i < numShapes; ++i, ++shapeIt)
747 shapeIterators[i] = end -= ((*shapes)[shapeIt]).second;
751 for (
size_t i = beginIdx, j = 0; i < beginIdx + currentSize; ++i)
752 if (shapeIndex[i] < 0)
754 if (i >= octrees[j]->end() -
pc.begin() + beginIdx
755 && j < octrees.
size() - 1)
759 shapeIndex[i] = begin++;
764 shapeIndex[i] = shapeIterators[shapeIndex[i]]++;
768 size_t mergedSubsets = 0;
769 if (subsetSizes[0] < 500 && subsetSizes.
size() > 1)
772 while (subsetSizes[0] < 500 && subsetSizes.
size() > 1)
774 subsetSizes[1] += subsetSizes[0];
783 size_t minInvalidIndex = currentSize - numInvalid + beginIdx;
784 #pragma parallel for schedule(static)
785 for (intptr_t i = 0, j = 0; i < globalOctreeIndices.
size(); ++i)
786 if (shapeIndex[globalOctreeIndices[i]] < minInvalidIndex)
788 globalOctreeIndices[j++] = shapeIndex[globalOctreeIndices[i]];
790 globalOctreeIndices.
resize(currentSize - numInvalid);
793 #pragma parallel for schedule(static)
794 for (intptr_t i = 0; i < candidates.
size(); ++i)
795 candidates[i].Reindex(shapeIndex, minInvalidIndex, mergedSubsets,
796 subsetSizes,
pc, currentSize - numInvalid, m_options.
m_epsilon,
800 for (
size_t i = beginIdx; i < beginIdx + currentSize; ++i)
801 while (i != shapeIndex[i])
803 pc.swapPoints(i, shapeIndex[i]);
804 std::swap(shapeIndex[i], shapeIndex[shapeIndex[i]]);
814 reindex(beginIdx + subsetSizes[0]);
815 for (
size_t i = 0; i < shuffleIndices.size(); ++i)
817 shuffleIndices[i] = i;
821 octrees[0]->ContainedData(&
pc);
822 octrees[0]->DataRange(beginIdx, beginIdx + subsetSizes[0]);
823 octrees[0]->MaxBucketSize() = 20;
824 octrees[0]->MaxSubdivisionLevel() = 10;
825 octrees[0]->ShuffleIndices(&shuffleIndices);
826 octrees[0]->Build(bcube);
827 octrees[0]->ShuffleIndices(NULL);
828 for (
size_t i = 0; i < shuffleIndices.size(); ++i)
830 reindex[shuffleIndices[i]] = i;
833 #pragma omp parallel for schedule(static)
834 for (intptr_t i = 0; i < globalOctreeIndices.
size(); ++i)
835 if (globalOctreeIndices[i] < reindex.
size())
837 globalOctreeIndices[i] = reindex[globalOctreeIndices[i]];
840 #pragma omp parallel for schedule(static, 100)
841 for (intptr_t i = 0; i < candidates.
size(); ++i)
843 candidates[i].Reindex(reindex);
845 for (
size_t i = 1, begin = subsetSizes[0] + beginIdx;
846 i < octrees.
size(); begin += subsetSizes[i], ++i)
848 octrees[i]->DataRange(begin, begin + subsetSizes[i]);
849 octrees[i]->Rebuild();
850 if (octrees[i]->Root()->Size() != subsetSizes[i])
852 std::cout <<
"ERROR IN REBUILD!!!!" << std::endl;
857 for (
size_t i = 0, begin = beginIdx; i < octrees.
size();
858 begin += subsetSizes[i], ++i)
860 octrees[i]->DataRange(begin, begin + subsetSizes[i]);
861 octrees[i]->Rebuild();
865 currentSize = globalOctreeIndices.
size();
867 globalOctree.IndexedRange(globalOctreeIndices.
begin(),
868 globalOctreeIndices.
end());
869 globalOctTreeMaxNodeDepth = globalOctree.Rebuild();
870 if (globalOctree.Root()->Size() != globalOctreeIndices.
size())
872 std::cout <<
"ERROR IN GLOBAL REBUILD!" << std::endl;
874 sampleLevelProbability.
resize(globalOctTreeMaxNodeDepth + 1);
877 std::fill(shapeIndex.
begin() + beginIdx,
878 shapeIndex.
begin() + beginIdx + currentSize, -1);
885 #pragma parallel for schedule(static, 100)
886 for (
size_t i = 0; i < candidates.
size(); ++i)
887 candidates[i].RecomputeBounds(octrees,
pc, subsetScoreVisitor,
888 currentSize - numInvalid, m_options.
m_epsilon,
892 std::sort(candidates.
begin(), candidates.
end(), std::greater< Candidate >());
893 size_t remainingCandidates = 0;
894 for (
size_t i = 0; i < candidates.
size(); ++i)
895 if (candidates[i].ExpectedValue() >= m_options.
m_minSupport
896 && candidates[i].Size() > 0)
898 candidates[remainingCandidates++] = candidates[i];
900 candidates.
resize(remainingCandidates);
904 std::sort(candidates.
begin(), candidates.
end(), std::greater< Candidate >());
905 size_t remainingCandidates = 0;
906 size_t nonConnectedCount = 0;
907 for (
size_t i = 0; i < candidates.
size(); ++i)
908 if (candidates[i].ExpectedValue() >= m_options.
m_minSupport &&
909 (candidates[i].ComputedSubsets() > octrees.
size() - 3 ||
910 nonConnectedCount++ < 500))
912 candidates[remainingCandidates++] = candidates[i];
914 else if (candidates[i].ExpectedValue() > maxForgottenCandidate)
916 maxForgottenCandidate = candidates[i].ExpectedValue();
918 candidates.
resize(remainingCandidates);
927 while (CandidateFailureProbability(m_options.
m_minSupport, currentSize - numInvalid,
928 drawnCandidates, globalOctTreeMaxNodeDepth) > m_options.
m_probability
938 size_t begin = beginIdx, end = beginIdx + currentSize;
941 int shapeIt =
shapes->size() - numShapes;
942 for (
size_t i = 0; i < numShapes; ++i, ++shapeIt)
944 shapeIterators[i] = end -= ((*shapes)[shapeIt]).second;
947 for (
size_t i = beginIdx; i < beginIdx + currentSize; ++i)
948 if (shapeIndex[i] < 0)
950 shapeIndex[i] = begin++;
954 shapeIndex[i] = shapeIterators[shapeIndex[i]]++;
958 for (
size_t i = beginIdx; i < beginIdx + currentSize; ++i)
959 while (i != shapeIndex[i])
961 pc.swapPoints(i, shapeIndex[i]);
962 std::swap(shapeIndex[i], shapeIndex[shapeIndex[i]]);
966 for (
size_t i = 0; i < octrees.
size(); ++i)
971 size_t eidx = endIdx;
972 for (
size_t i = 0; i <
shapes->size(); ++i)
974 size_t bidx = eidx - (*shapes)[i].second;
975 (*shapes)[i].first->OptimizeParametrization(
pc, bidx, eidx,
981 for (
size_t i =
shapes->size(); i != 0; --i)
983 if (
shapes->at(i - 1).second == 0)
988 return currentSize - numInvalid;
992 size_t numSamples,
size_t depth,
997 for (
size_t tries = 0; tries < m_maxCandTries; tries++)
1004 first = oct.Dereference(
rn_rand() % oct.size());
1006 while (shapeIndex[first] != -1);
1009 std::pair< size_t, size_t > nodeRange;
1013 if ((*node)->Size() < numSamples)
1018 while (samples->
size() < numSamples)
1023 i = oct.Dereference(
rn_rand() % (*node)->Size()
1026 while ((shapeIndex[i] != -1
1027 || std::find(samples->
begin(), samples->
end(), i) != samples->
end())
1036 if (samples->
size() == numSamples)
1044 PrimitiveShape* RansacShapeDetector::Fit(
bool allowDifferentShapes,
1048 std::pair< size_t, float >* score)
const
1050 if (!m_constructors.
size())