Commit 6d1cdcf6 authored by gylns's avatar gylns Committed by Alexander Alekhin

Merge pull request #8910 from gylns:mser

fix the MSER history's size issue (#8910)

* simplify growHistory and merge

* add assertion for history's size

* MSER: fix merging components' history
parent dc59476c
...@@ -262,98 +262,95 @@ public: ...@@ -262,98 +262,95 @@ public:
} }
// add history chunk to a connected component // add history chunk to a connected component
void growHistory( CompHistory*& hptr, WParams& wp, int new_gray_level, bool final, bool force=false ) void growHistory(CompHistory*& hptr, WParams& wp, int new_gray_level, bool final)
{ {
bool update = final; if (new_gray_level < gray_level)
if( new_gray_level < 0 )
new_gray_level = gray_level; new_gray_level = gray_level;
if( !history || (history->size != size && size > 0 &&
(gray_level != history->val || force)))
{
CompHistory* h;
if (history && gray_level == history->val)
h = history;
else
{
h = hptr++;
h->parent_ = 0;
h->child_ = history;
h->next_ = 0;
if (history)
history->parent_ = h;
}
h->val = gray_level; CompHistory *h;
h->size = size; if (history && history->val == gray_level)
h->head = head; {
h = history;
}
else
{
h = hptr++;
h->parent_ = 0;
h->child_ = history;
h->next_ = 0;
history = h; if (history)
h->var = FLT_MAX;
h->checked = true;
if (h->size >= wp.p.minArea)
{ {
h->var = -1.f; history->parent_ = h;
h->checked = false;
update = true;
} }
} }
h->val = gray_level;
h->size = size;
h->head = head;
h->var = FLT_MAX;
h->checked = true;
if (h->size >= wp.p.minArea)
{
h->var = -1.f;
h->checked = false;
}
gray_level = new_gray_level; gray_level = new_gray_level;
if( update && history && gray_level != history->val ) history = h;
if (history && history->val != gray_level)
{
history->updateTree(wp, 0, 0, final); history->updateTree(wp, 0, 0, final);
}
} }
// merging two connected components // merging two connected components
void merge( ConnectedComp* comp1, ConnectedComp* comp2, void merge( ConnectedComp* comp1, ConnectedComp* comp2,
CompHistory*& hptr, WParams& wp ) CompHistory*& hptr, WParams& wp )
{ {
if( comp1->size < comp2->size ) if (comp1->gray_level < comp2->gray_level)
std::swap(comp1, comp2); std::swap(comp1, comp2);
if( comp2->size == 0 ) gray_level = comp1->gray_level;
comp1->growHistory(hptr, wp, gray_level, false);
comp2->growHistory(hptr, wp, gray_level, false);
if (comp1->size == 0)
{
head = comp2->head;
tail = comp2->tail;
}
else
{ {
// only grow comp1's history
comp1->growHistory(hptr, wp, -1, false);
gray_level = comp1->gray_level;
head = comp1->head; head = comp1->head;
tail = comp1->tail; wp.pix0[comp1->tail].setNext(comp2->head);
size = comp1->size; tail = comp2->tail;
history = comp1->history;
return;
} }
comp1->growHistory( hptr, wp, -1, false );
comp2->growHistory( hptr, wp, -1, false );
if (comp1->gray_level < comp2->gray_level)
std::swap(comp1, comp2);
gray_level = comp1->gray_level;
history = comp1->history;
wp.pix0[comp1->tail].setNext(comp2->head);
head = comp1->head;
tail = comp2->tail;
size = comp1->size + comp2->size; size = comp1->size + comp2->size;
// update the history size history = comp1->history;
history->size =size;
CompHistory *h1 = history->child_; CompHistory *h1 = history->child_;
CompHistory *h2 = comp2->history; CompHistory *h2 = comp2->history;
if (h2->size > wp.p.minArea) // the child_'s size should be the large one
if (h1 && h1->size > h2->size)
{ {
// the child_'s size should be the large one // add h2 as a child only if its size is large enough
if (h1 && h1->size > h2->size) if(h2->size >= wp.p.minArea)
{ {
h2->next_ = h1->next_; h2->next_ = h1->next_;
h1->next_ = h2; h1->next_ = h2;
h2->parent_ = history;
} }
else }
else
{
history->child_ = h2;
h2->parent_ = history;
// reserve h1 as a child only if its size is large enough
if (h1 && h1->size >= wp.p.minArea)
{ {
history->child_ = h2;
h2->next_ = h1; h2->next_ = h1;
} }
h2->parent_ = history;
} }
} }
...@@ -517,30 +514,26 @@ public: ...@@ -517,30 +514,26 @@ public:
ptr = *heap[curr_gray]; ptr = *heap[curr_gray];
heap[curr_gray]--; heap[curr_gray]--;
if( curr_gray < comptr[-1].gray_level ) if (curr_gray < comptr[-1].gray_level)
{
comptr->growHistory(histptr, wp, curr_gray, false); comptr->growHistory(histptr, wp, curr_gray, false);
CV_DbgAssert(comptr->size == comptr->history->size);
}
else else
{ {
// keep merging top two comp in stack until the gray level >= pixel_val // there must one pixel with the second component's gray level in the heap,
for(;;) // so curr_gray is not large than the second component's gray level
{ comptr--;
comptr--; CV_DbgAssert(curr_gray == comptr->gray_level);
comptr->merge(comptr, comptr+1, histptr, wp); comptr->merge(comptr, comptr + 1, histptr, wp);
if( curr_gray <= comptr[0].gray_level ) CV_DbgAssert(curr_gray == comptr->gray_level);
break;
if( curr_gray < comptr[-1].gray_level )
{
comptr->growHistory(histptr, wp, curr_gray, false);
break;
}
}
} }
} }
} }
for( ; comptr->gray_level != 256; comptr-- ) for( ; comptr->gray_level != 256; comptr-- )
{ {
comptr->growHistory(histptr, wp, 256, true, true); comptr->growHistory(histptr, wp, 256, true);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment