Skip to content

Commit 6d1cdcf

Browse files
gylnsalalek
authored andcommitted
Merge pull request opencv#8910 from gylns:mser
fix the MSER history's size issue (opencv#8910) * simplify growHistory and merge * add assertion for history's size * MSER: fix merging components' history
1 parent dc59476 commit 6d1cdcf

File tree

1 file changed

+67
-74
lines changed

1 file changed

+67
-74
lines changed

modules/features2d/src/mser.cpp

Lines changed: 67 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -262,98 +262,95 @@ class MSER_Impl : public MSER
262262
}
263263

264264
// add history chunk to a connected component
265-
void growHistory( CompHistory*& hptr, WParams& wp, int new_gray_level, bool final, bool force=false )
265+
void growHistory(CompHistory*& hptr, WParams& wp, int new_gray_level, bool final)
266266
{
267-
bool update = final;
268-
if( new_gray_level < 0 )
267+
if (new_gray_level < gray_level)
269268
new_gray_level = gray_level;
270-
if( !history || (history->size != size && size > 0 &&
271-
(gray_level != history->val || force)))
272-
{
273-
CompHistory* h;
274-
275-
if (history && gray_level == history->val)
276-
h = history;
277-
else
278-
{
279-
h = hptr++;
280-
h->parent_ = 0;
281-
h->child_ = history;
282-
h->next_ = 0;
283-
if (history)
284-
history->parent_ = h;
285-
}
286269

287-
h->val = gray_level;
288-
h->size = size;
289-
h->head = head;
270+
CompHistory *h;
271+
if (history && history->val == gray_level)
272+
{
273+
h = history;
274+
}
275+
else
276+
{
277+
h = hptr++;
278+
h->parent_ = 0;
279+
h->child_ = history;
280+
h->next_ = 0;
290281

291-
history = h;
292-
h->var = FLT_MAX;
293-
h->checked = true;
294-
if (h->size >= wp.p.minArea)
282+
if (history)
295283
{
296-
h->var = -1.f;
297-
h->checked = false;
298-
update = true;
284+
history->parent_ = h;
299285
}
300286
}
287+
h->val = gray_level;
288+
h->size = size;
289+
h->head = head;
290+
h->var = FLT_MAX;
291+
h->checked = true;
292+
if (h->size >= wp.p.minArea)
293+
{
294+
h->var = -1.f;
295+
h->checked = false;
296+
}
297+
301298
gray_level = new_gray_level;
302-
if( update && history && gray_level != history->val )
299+
history = h;
300+
if (history && history->val != gray_level)
301+
{
303302
history->updateTree(wp, 0, 0, final);
303+
}
304304
}
305305

306306
// merging two connected components
307307
void merge( ConnectedComp* comp1, ConnectedComp* comp2,
308308
CompHistory*& hptr, WParams& wp )
309309
{
310-
if( comp1->size < comp2->size )
310+
if (comp1->gray_level < comp2->gray_level)
311311
std::swap(comp1, comp2);
312312

313-
if( comp2->size == 0 )
313+
gray_level = comp1->gray_level;
314+
comp1->growHistory(hptr, wp, gray_level, false);
315+
comp2->growHistory(hptr, wp, gray_level, false);
316+
317+
if (comp1->size == 0)
318+
{
319+
head = comp2->head;
320+
tail = comp2->tail;
321+
}
322+
else
314323
{
315-
// only grow comp1's history
316-
comp1->growHistory(hptr, wp, -1, false);
317-
gray_level = comp1->gray_level;
318324
head = comp1->head;
319-
tail = comp1->tail;
320-
size = comp1->size;
321-
history = comp1->history;
322-
return;
325+
wp.pix0[comp1->tail].setNext(comp2->head);
326+
tail = comp2->tail;
323327
}
324328

325-
comp1->growHistory( hptr, wp, -1, false );
326-
comp2->growHistory( hptr, wp, -1, false );
327-
328-
if (comp1->gray_level < comp2->gray_level)
329-
std::swap(comp1, comp2);
330-
331-
gray_level = comp1->gray_level;
332-
history = comp1->history;
333-
wp.pix0[comp1->tail].setNext(comp2->head);
334-
335-
head = comp1->head;
336-
tail = comp2->tail;
337329
size = comp1->size + comp2->size;
338-
// update the history size
339-
history->size =size;
330+
history = comp1->history;
340331

341332
CompHistory *h1 = history->child_;
342333
CompHistory *h2 = comp2->history;
343-
if (h2->size > wp.p.minArea)
334+
// the child_'s size should be the large one
335+
if (h1 && h1->size > h2->size)
344336
{
345-
// the child_'s size should be the large one
346-
if (h1 && h1->size > h2->size)
337+
// add h2 as a child only if its size is large enough
338+
if(h2->size >= wp.p.minArea)
347339
{
348340
h2->next_ = h1->next_;
349341
h1->next_ = h2;
342+
h2->parent_ = history;
350343
}
351-
else
344+
}
345+
else
346+
{
347+
history->child_ = h2;
348+
h2->parent_ = history;
349+
// reserve h1 as a child only if its size is large enough
350+
if (h1 && h1->size >= wp.p.minArea)
352351
{
353-
history->child_ = h2;
354352
h2->next_ = h1;
355353
}
356-
h2->parent_ = history;
357354
}
358355
}
359356

@@ -517,30 +514,26 @@ class MSER_Impl : public MSER
517514
ptr = *heap[curr_gray];
518515
heap[curr_gray]--;
519516

520-
if( curr_gray < comptr[-1].gray_level )
517+
if (curr_gray < comptr[-1].gray_level)
518+
{
521519
comptr->growHistory(histptr, wp, curr_gray, false);
520+
CV_DbgAssert(comptr->size == comptr->history->size);
521+
}
522522
else
523523
{
524-
// keep merging top two comp in stack until the gray level >= pixel_val
525-
for(;;)
526-
{
527-
comptr--;
528-
comptr->merge(comptr, comptr+1, histptr, wp);
529-
if( curr_gray <= comptr[0].gray_level )
530-
break;
531-
if( curr_gray < comptr[-1].gray_level )
532-
{
533-
comptr->growHistory(histptr, wp, curr_gray, false);
534-
break;
535-
}
536-
}
524+
// there must one pixel with the second component's gray level in the heap,
525+
// so curr_gray is not large than the second component's gray level
526+
comptr--;
527+
CV_DbgAssert(curr_gray == comptr->gray_level);
528+
comptr->merge(comptr, comptr + 1, histptr, wp);
529+
CV_DbgAssert(curr_gray == comptr->gray_level);
537530
}
538531
}
539532
}
540533

541534
for( ; comptr->gray_level != 256; comptr-- )
542535
{
543-
comptr->growHistory(histptr, wp, 256, true, true);
536+
comptr->growHistory(histptr, wp, 256, true);
544537
}
545538
}
546539

0 commit comments

Comments
 (0)