34 #ifndef AIMS_PRIMALSKETCH_PRIMALSKETCH_H
35 #define AIMS_PRIMALSKETCH_PRIMALSKETCH_H
123 const std::string & statFile=
"",
124 uint intersection_param=10 );
127 uint intersection_param );
141 template<
typename Geom,
typename Text>
142 ScaleSpaceBlob<typename SiteType<Geom>::type>
145 typename std::list<ScaleSpaceBlob<Site>*>
::iterator itBlobList = blobList.begin();
146 for (; itBlobList!=blobList.end(); ++itBlobList)
148 if ((*itBlobList).Label() == label)
149 return (*itBlobList);
155 template<
typename Geom,
typename Text>
158 typename std::list<ScaleSpaceBlob<Site>*>
::iterator itBlobList=blobList.begin();
160 std::list<GreyLevelBlob<Site>*> glBlobList;
161 typename std::list<GreyLevelBlob<Site>*>
::iterator
163 for (; itBlobList!=blobList.end(); ++itBlobList)
167 itGLBlobList=glBlobList.begin();
168 for (; itGLBlobList!=glBlobList.end(); ++itGLBlobList)
169 if ( ((*itGLBlobList)->Label()==glBlob->
Label()) && ((*itGLBlobList)->GetScale()==glBlob->
GetScale()) )
173 std::cout <<
"SS BLOB label=" << glBlob->
Label() <<
" and scale " << glBlob->
GetScale() <<
" cannot be found...." << std::endl;
179 template<
typename Geom,
typename Text>
181 float tmin,
float tmax,
const std::string & statFile,
182 uint intersection_param )
190 std::cout <<
"Computing primal sketch between tmin=" << tmin <<
" and tmax=" << tmax << std::endl;
194 float t_bif = tmax*2;
196 if ( _scaleSpace == NULL ) {
197 std::cerr <<
"Trying to compute a primal sketch without a scale-space" << std::endl;
198 std::cerr <<
"Subject : " << _subject;
202 std::set<float> scaleList=_scaleSpace->GetScaleList();
203 std::set<float>::reverse_iterator itScaleUp=scaleList.rbegin();
204 std::set<float>::reverse_iterator itScaleDown;
207 for ( ; (*itScaleUp) != tmax ; ++itScaleUp ) {
208 if ( itScaleUp == scaleList.rend() ) {
209 std::cerr <<
"Scale max " << tmax <<
" does not exist" << std::endl;
215 levelUp = _scaleSpace->
Scale(*itScaleUp);
217 levelDown=_scaleSpace->
Scale(tmin);
226 std::map<int, GreyLevelBlob<Site> *>
229 typename std::map<int, GreyLevelBlob<Site> *>
::iterator
230 itGL = listeGLB.begin();
232 for ( ; itGL != listeGLB.end() ; ++itGL ) {
233 glBlob=(*itGL).second;
242 AddBifurcation(bifurc);
248 for ( ; (*itScaleUp) > tmin ; ++itScaleUp ) {
249 itScaleDown=itScaleUp;
252 t_down = *itScaleDown;
253 MatchScaleLevels(t_up, t_down, intersection_param);
259 itGL = listeGLB.begin();
261 for ( ; itGL != listeGLB.end() ; ++itGL ) {
262 glBlob = (*itGL).second;
263 ssBlob = GetSSBlobFromGLBlob(glBlob);
264 if ( ssBlob != NULL) {
268 AddBifurcation(bifurc);
273 typename std::list<ScaleSpaceBlob<Site>*>
::iterator
274 itBlob = blobList.begin();
275 for ( ; itBlob != blobList.end() ; ++itBlob ) {
276 (*itBlob)->ComputeLifeTime();
277 (*itBlob)->ComputeScaleRep();
281 ComputeBlobMeasurements(statFile);
282 std::cout <<
"ssblobs avant : " << blobList.size() << std::endl;
285 typename std::list<Bifurcation<Site>*>
::iterator bifit = bifurcationList.begin();
287 uint merge_count = 0;
289 for ( bifit = bifurcationList.begin() ; bifit != bifurcationList.end() ; bifit++ )
290 if ((*bifit)->Type() ==
MERGE)
295 for ( bifit = bifurcationList.begin() ; bifit != bifurcationList.end() ; bifit++ ) {
296 if ( (*bifit)->Type() ==
APPEAR ) {
312 else if ( (*bifit)->Type() ==
DISAPPEAR ) {
326 else if ( (*bifit)->Type() ==
MERGE ) {
328 std::list<ScaleSpaceBlob<Site>*> blist = (*bifit)->BottomBlobs();
329 typename std::list<ScaleSpaceBlob<Site>*>
::iterator bottomit=blist.begin();
337 if ((*ssblob2).GlBlobRep()->GetListePoints().size() == 1) {
346 blist = (*bifit)->TopBlobs();
349 std::list<GreyLevelBlob<Site>*> glb = ssblob1->
glBlobs;
350 typename std::list<GreyLevelBlob<Site>*>
::iterator glbit = glb.begin();
351 for (; glbit != glb.end() ; glbit++)
357 int label1 = ssblob1->
Label();
358 for (itBlob=blobList.begin(); itBlob != blobList.end(); ++itBlob)
359 if ((*itBlob)->Label() == label1) {
360 blobList.erase(itBlob);
364 else if ( (*ssblob1).GlBlobRep()->GetListePoints().size() == 1 ) {
372 blist = (*bifit)->TopBlobs();
375 std::list<GreyLevelBlob<Site>*> glb = ssblob2->
glBlobs;
376 typename std::list<GreyLevelBlob<Site>*>
::iterator glbit = glb.begin();
377 for (; glbit != glb.end() ; glbit++)
383 int label2 = ssblob2->
Label();
384 for (itBlob=blobList.begin(); itBlob != blobList.end(); ++itBlob)
385 if ((*itBlob)->Label() == label2) {
386 blobList.erase(itBlob);
392 else if ((*bifit)->Type() ==
SPLIT) {
395 std::list<ScaleSpaceBlob<Site>*> blist = (*bifit)->TopBlobs();
396 typename std::list<ScaleSpaceBlob<Site>*>
::iterator topit=blist.begin();
404 if ((*ssblob1).GlBlobRep()->GetListePoints().size() == 1) {
412 blist = (*bifit)->BottomBlobs();
415 std::list<GreyLevelBlob<Site>*> glb = ssblob1->
glBlobs;
416 typename std::list<GreyLevelBlob<Site>*>
::iterator glbit = glb.begin();
417 for (; glbit != glb.end() ; glbit++)
423 int label1 = ssblob1->
Label();
424 for (itBlob=blobList.begin(); itBlob != blobList.end(); ++itBlob)
425 if ((*itBlob)->Label() == label1) {
426 blobList.erase(itBlob);
430 else if ((*ssblob1).GlBlobRep()->GetListePoints().size() == 1){
438 blist = (*bifit)->BottomBlobs();
441 std::list<GreyLevelBlob<Site>*> glb = ssblob2->
glBlobs;
442 typename std::list<GreyLevelBlob<Site>*>
::iterator glbit = glb.begin();
443 for ( ; glbit != glb.end() ; glbit++ )
449 int label2 = ssblob2->
Label();
450 for ( itBlob = blobList.begin() ; itBlob != blobList.end() ; ++itBlob )
451 if ( (*itBlob)->Label() == label2 ) {
452 blobList.erase ( itBlob );
459 bifit = bifurcationList.begin();
460 for (bifit = bifurcationList.begin() ; bifit != bifurcationList.end() ; bifit++)
461 if ((*bifit)->Type() ==
MERGE)
466 std::cout <<
"ssblobs après : " << blobList.size() << std::endl;
468 for (itBlob=blobList.begin(); itBlob != blobList.end(); ++itBlob) {
469 (*itBlob)->ComputeLifeTime();
470 (*itBlob)->ComputeScaleRep();
473 ComputeBlobMeasurements(statFile);
478 template<
typename Geom,
typename Text>
482 int stat1=0, stat2=0, stat3=0;
484 std::cout <<
"Matching " << t_up <<
" <-> " << t_down << std::endl;
491 std::cout <<
"Blob detection at scale " << t_up << std::endl;
493 std::cout <<
"Blob detection at scale " << t_down << std::endl;
496 std::cout <<
"\tt=" << t_up <<
" : " << levelUp->
nbBlobs() <<
" blobs" << std::endl;
497 std::cout <<
"\tt=" << t_down <<
" : " << levelDown->
nbBlobs() <<
" blobs" << std::endl;
499 std::map<int, GreyLevelBlob<Site> *> listeGLB_up=levelUp->
BlobList();
500 std::map<int, GreyLevelBlob<Site> *> listeGLB_down=levelDown->
BlobList();
504 std::cout <<
"\tComputing potential links" << std::endl;
506 std::map<int, std::set<int> > matchUp;
507 std::map<int, std::set<int> > matchDown;
508 typename std::map<int, GreyLevelBlob<Site> *>
::iterator
510 typename std::map<int, GreyLevelBlob<Site> *>
::iterator
513 int labelUp, labelDown;
515 iteratorUp=listeGLB_up.begin();
516 for (; iteratorUp!=listeGLB_up.end(); ++iteratorUp)
518 blobUp=(*iteratorUp).second; labelUp=(*iteratorUp).first;
519 matchUp[labelUp]=std::set<int>();
520 std::set<Site,ltstr_p3d<Site> > pointsUp=blobUp->
GetListePoints();
521 iteratorDown=listeGLB_down.begin();
522 for (; iteratorDown!=listeGLB_down.end(); ++iteratorDown)
524 blobDown=(*iteratorDown).second; labelDown=(*iteratorDown).first;
525 if (matchDown.find(labelDown) == matchDown.end())
526 matchDown[labelDown]=std::set<int>();
528 std::set<Site,ltstr_p3d<Site> > pointsInter;
529 std::set<Site,ltstr_p3d<Site> > pointsDown=blobDown->
GetListePoints();
530 std::set_intersection(pointsDown.begin(), pointsDown.end(),
531 pointsUp.begin(), pointsUp.end(),
532 std::inserter(pointsInter, pointsInter.begin()),
535 if (pointsInter.size()>intersection_param)
537 matchUp[labelUp].insert(labelDown);
538 matchDown[labelDown].insert(labelUp);
544 std::cout <<
"\tChecking potential refinements" << std::endl;
545 std::map<int, std::set<int> >
::iterator itMatchUp=matchUp.begin();
546 std::map<int, std::set<int> >
::iterator itMatchDown=matchDown.begin();
548 for (; itMatchUp!=matchUp.end(); ++itMatchUp)
550 int nUp=(*itMatchUp).second.size();
557 std::set<int> setUp=(*itMatchUp).second;
558 std::set<int>::iterator itUp=setUp.begin();
559 for (; itUp!=setUp.end(); ++itUp)
560 if (matchDown[*itUp].size()>1)
563 if (refinement>0)
break;
567 for (; itMatchDown!=matchDown.end(); ++itMatchDown)
569 if ((*itMatchDown).second.size() > 2)
571 if (refinement>0)
break;
574 t=exp((log(t_up) + log(t_down))/2.0); t_new=0;
576 while ((i*0.1) <= t) i++;
578 if ((refinement>0) && ((t_up-t_new)>min_delta_t) && ((t_new-t_down)>min_delta_t))
580 std::cout <<
"\tRefinement needed (type " ;
584 std::cout <<
" 2 <-> 2)" << std::endl;
588 std::cout <<
"split 1->3)" << std::endl;
592 std::cout <<
"merge 3->1)" << std::endl;
596 std::cout <<
"unknown)" << std::endl;
599 std::cout <<
"\tNew scale : " << t_new << std::endl;
600 MatchScaleLevels(t_up, t_new, intersection_param);
601 MatchScaleLevels(t_new, t_down, intersection_param);
602 std::cout <<
"\trefinement successful" << std::endl;
606 if (refinement >0) std::cout <<
"\tAccepting matching but refinement needed (type " << refinement <<
")" << std::endl;
607 else std::cout <<
"\tMatching OK" << std::endl;
608 itMatchUp=matchUp.begin();
609 itMatchDown=matchDown.begin();
613 std::cout <<
"\tResolving matching - version 2" << std::endl;
614 std::vector<std::pair<std::set<int>, std::set<int> > > bifurcTable;
615 std::set<int> set1, set2;
616 for (; itMatchUp!=matchUp.end(); ++itMatchUp)
618 labelUp=(*itMatchUp).first;
619 std::set<int> setUp=(*itMatchUp).second;
623 set1=std::set<int>();set1.insert(labelUp);
625 bifurcTable.push_back(std::pair<std::set<int>, std::set<int> >(set1, set2));
630 std::set<int>::iterator itSetUp;
631 for (itSetUp=setUp.begin(); (itSetUp!=setUp.end()&&(checkRepeat==0)); ++itSetUp)
633 int blobLab=(*itSetUp);
634 if (matchDown[blobLab].size() > 1)
640 set1=std::set<int>();set1.insert(labelUp);
642 bifurcTable.push_back(std::pair<std::set<int>, std::set<int> >(set1, set2));
648 std::vector<std::pair<std::set<int>, std::set<int> > >
::iterator
649 itBifurc=bifurcTable.begin();
651 for (; (itBifurc!=bifurcTable.end())&&(flagMerge==0); ++itBifurc)
653 std::set<int> setTmp=(*itBifurc).second;
654 std::set<int> setInter;
655 std::set_intersection(setUp.begin(), setUp.end(),
656 setTmp.begin(), setTmp.end(),
657 std::inserter(setInter, setInter.begin()));
658 if (setInter.size()>0)
661 (*itBifurc).first.insert(labelUp);
662 itSetUp=setUp.begin();
663 for (; itSetUp!=setUp.end(); ++itSetUp)
664 (*itBifurc).second.insert(*itSetUp);
671 set1=std::set<int>();set1.insert(labelUp);
673 bifurcTable.push_back(std::pair<std::set<int>, std::set<int> >(set1, set2));
678 for (; itMatchDown!=matchDown.end(); ++itMatchDown)
681 labelDown=(*itMatchDown).first;
682 std::set<int> setDown=(*itMatchDown).second;
683 if (setDown.size()==0)
685 set2=std::set<int>();set2.insert(labelDown);
687 bifurcTable.push_back(std::pair<std::set<int>, std::set<int> >(set1, set2));
691 std::vector< std::pair<std::set<int>, std::set<int> > >
::iterator itTable=bifurcTable.begin();
692 std::pair<std::set<int>, std::set<int> > pairSet;
696 std::cout <<
"\t Table -> Blobs and bifurcations" << std::endl;
699 for (; itTable!=bifurcTable.end(); ++itTable) {
706 labelUp = *(set1.begin());
707 blobUp = levelUp->
Blob(labelUp);
708 ssBlobUp = GetSSBlobFromGLBlob(blobUp);
709 if ( ssBlobUp != NULL) {
715 AddBifurcation(bifurc);
721 else if (set1.size()==0)
724 labelDown=*(set2.begin());
725 blobDown=levelDown->
Blob(labelDown);
734 AddBifurcation(bifurc);
742 if ((set1.size()==1) && (set2.size()==1))
744 labelUp = *(set1.begin());
745 labelDown = *(set2.begin());
746 blobUp = levelUp->
Blob ( labelUp );
747 ssBlobUp = GetSSBlobFromGLBlob ( blobUp );
748 if ( ssBlobUp != NULL) {
749 blobDown = levelDown->
Blob ( labelDown );
753 else if ((set1.size()==1) && (set2.size()==2))
757 labelUp = *(set1.begin());
758 blobUp = levelUp->
Blob(labelUp);
759 ssBlobUp = GetSSBlobFromGLBlob(blobUp);
760 if ( ssBlobUp != NULL) {
764 std::set<int>::iterator itSet2=set2.begin();
765 for (; itSet2!=set2.end(); ++itSet2)
768 blobDown=levelDown->
Blob(labelDown);
779 AddBifurcation(bifurc);
785 else if ( (set1.size()==2) && (set2.size()==1) )
789 labelDown = *(set2.begin());
790 blobDown = levelDown->
Blob(labelDown);
799 std::set<int>::iterator itSet1=set1.begin();
800 for (; itSet1!=set1.end(); ++itSet1)
803 blobUp = levelUp->
Blob(labelUp);
804 ssBlobUp = GetSSBlobFromGLBlob(blobUp);
805 if ( ssBlobUp != NULL) {
811 AddBifurcation(bifurc);
820 std::set<int>::iterator itSet2=set2.begin();
821 for (; itSet2!=set2.end(); ++itSet2)
824 blobDown = levelDown->
Blob(labelDown);
834 std::set<int>::iterator itSet1=set1.begin();
835 for (; itSet1!=set1.end(); ++itSet1)
838 blobUp = levelUp->
Blob(labelUp);
839 ssBlobUp = GetSSBlobFromGLBlob(blobUp);
840 if ( ssBlobUp != NULL) {
846 AddBifurcation(bifurc);
850 std::cout <<
"\t OK" << std::endl;
858 template<
typename Geom,
typename Text>
860 const std::string & statName )
863 std::map<float, BlobMeasurements > statsM, statsSD;
866 float max_int, mean_int, max_cont, mean_cont, area, areamoy, areavar, tvalue;
875 std::cout <<
"Computing multiscale measurements for SSBlobs"
878 if (statName.length()>0)
880 if ((fileStats=fopen(statName.c_str(),
"r"))==NULL)
882 std::cerr <<
"Problem : cannot open stat file " << statName
886 std::cout <<
"Found stat file, reading it" << std::endl;
887 while (!feof(fileStats))
889 res = fscanf(fileStats,
"%f\n", &t);
892 std::cerr <<
"file corrupted" << std::endl;
894 res = fscanf(fileStats,
"%f %f %f %f %f", &max_int, &mean_int, &max_cont, &mean_cont, &area);
897 std::cerr <<
"file corrupted" << std::endl;
899 measurements=
new BlobMeasurements(max_int, mean_int, max_cont, mean_cont, area);
900 statsM.insert(std::pair<float, BlobMeasurements>(t, *measurements));
901 res = fscanf(fileStats,
"%f %f %f %f %f", &max_int, &mean_int, &max_cont, &mean_cont, &area);
904 std::cerr <<
"file corrupted" << std::endl;
906 measurements=
new BlobMeasurements(max_int, mean_int, max_cont, mean_cont, area);
907 statsSD.insert(std::pair<float, BlobMeasurements>(t, *measurements));
910 typename std::list<ScaleSpaceBlob<Site>*>
::iterator itSSBlobs=blobList.begin();
911 std::cout <<
"processing GLblobs for normalisation" << std::endl;
912 for (; itSSBlobs!=blobList.end(); ++itSSBlobs)
915 typename std::list<GreyLevelBlob<Site>*>
::iterator itglb;
917 for (itglb=ssBlob->
glBlobs.begin();itglb!=ssBlob->
glBlobs.end();++itglb)
921 if (statsM.find(t)!=statsM.end())
951 std::cerr <<
"Problem during measurements normalisation !" << std::endl;
952 std::cerr <<
"Stat file " << statName <<
" incomplete, can't find scale " << t << std::endl;
958 typename std::list< ScaleSpaceBlob<Site>* >
::iterator itSSBlobs=blobList.begin();
959 std::cout <<
"Computing multi-scale measurements" << std::endl;
961 for (; itSSBlobs!=blobList.end(); ++itSSBlobs)
964 typename std::list<GreyLevelBlob<Site>*>
::iterator itGLBlobs=ssBlob->
glBlobs.begin();
967 max_int=0; mean_int=0; max_cont=0; mean_cont=0; area=0; areamoy=0; areavar=0; tvalue=0;
973 std::cout <<
"PROBLEME DE DT<0" << std::endl;
984 for (; itGLBlobs!=ssBlob->
glBlobs.end(); ++itGLBlobs)
1004 std::cout <<
"PROBLEME DE DT<0" << std::endl;
1019 std::set<Site,ltstr_p3d<Site> > pixels;
1023 typename std::set<Site, ltstr_p3d<Site> >
::iterator itPix;
1025 for (itPix=pixels.begin();itPix!=pixels.end();itPix++){
1026 if (ima.intensity(*itPix) > tvmax )
1027 tvmax = ima.intensity(*itPix);
1031 measure=
BlobMeasurements(max_int, mean_int, max_cont,mean_cont, area, tvalue, tvmax);
1034 areavar +=area*area;
void AddTopBlob(ScaleSpaceBlob< T > *blob)
std::list< ScaleSpaceBlob< T > * > TopBlobs()
void AddBottomBlob(ScaleSpaceBlob< T > *blob)
std::list< ScaleSpaceBlob< T > * > BottomBlobs()
std::set< T, ltstr_p3d< T > > & GetListePoints()
BlobMeasurements measurements
ScaleSpaceBlob< Site > * GetSSBlobFromGLBlob(GreyLevelBlob< Site > *glBlob)
TexturedData< Geom, Text > * _mask
void AddBlob(ScaleSpaceBlob< Site > *blob)
std::list< ScaleSpaceBlob< Site > * > BlobSet()
void MatchScaleLevels(float t_up, float t_down, uint intersection_param)
ScaleSpaceBlob< Site > * Blob(int label)
std::list< ScaleSpaceBlob< Site > * > blobList
std::list< Bifurcation< Site > * > BifurcationList()
void SetScaleSpace(ScaleSpace< Geom, Text > *scaleSpace)
ScaleSpace< Geom, Text > * _scaleSpace
void ComputePrimalSketch(float tmin, float tMax, const std::string &statFile="", uint intersection_param=10)
std::list< Bifurcation< Site > * > bifurcationList
void ComputeBlobMeasurements(const std::string &statName="")
SiteType< Geom >::type Site
void AddBifurcation(Bifurcation< Site > *bifurcation)
PrimalSketch(const std::string &subject, ScaleSpace< Geom, Text > *scaleSpace, int type)
PrimalSketch(const std::string &subject, int type)
PrimalSketch(const std::string &subject, ScaleSpace< Geom, Text > *scaleSpace, TexturedData< Geom, Text > *mask, int type)
TexType< Text >::type Val
ScaleSpace< Geom, Text > * scaleSpace()
void DetectBlobs(TexturedData< Geom, Text > *mask, char *stats=0)
std::map< int, GreyLevelBlob< Site > * > BlobList()
GreyLevelBlob< Site > * Blob(int label)
void AddGreyLevelBlob(GreyLevelBlob< T > *blob)
Bifurcation< T > * TopBifurcation()
void SetScaleMin(float t)
void SetBottomBifurcation(Bifurcation< T > *bif)
GreyLevelBlob< T > * GlBlobRep()
Bifurcation< T > * BottomBifurcation()
void SetMeasurements(BlobMeasurements meas)
std::list< GreyLevelBlob< T > * > glBlobs
void SetTopBifurcation(Bifurcation< T > *bif)
void SetScaleMax(float t)
BucketMap< Void > * mask(const BucketMap< Void > &src, const BucketMap< Void > &m, bool intersect=true)