• No results found

Flood-Fill. Flood-fill. Flood-Fill from Seed. Recursive Flood-Fill. 8-connected vs. 4-connected. Recursive Flood-Fill Algorithm

N/A
N/A
Protected

Academic year: 2022

Share "Flood-Fill. Flood-fill. Flood-Fill from Seed. Recursive Flood-Fill. 8-connected vs. 4-connected. Recursive Flood-Fill Algorithm"

Copied!
5
0
0

Loading.... (view fulltext now)

Full text

(1)

Flood-fill

Flood-Fill

• Used in interactive paint systems.

• The user specify a seed by pointing to the interior of the region to initiate a flood operation

Recursive Flood-Fill

• Fill a image-space region with some intensity (color) value

• How to define the region?

• Fill Until vs. Fill While

• 4-connectivity vs. 8-connectivity

Flood-Fill from Seed

• Start from the seed and floods the region until a boundary is met.

A simple recursive algorithm can be used:

void floodFill(int x, int y, int fill, int old) {

if ((x < 0) || (x >= width)) return;

if ((y < 0) || (y >= height)) return;

if (getPixel(x, y) == old) { setPixel(fill, x, y);

floodFill(x+1, y, fill, old);

floodFill(x, y+1, fill, old);

floodFill(x-1, y, fill, old);

floodFill(x, y-1, fill, old);

} }

8-connected vs. 4-connected

S

An 8-connected flood is able to flood through corners that a 4-connected flood cannot.

Recursive Flood-Fill Algorithm

The algorithm is very simple, however it is:

• highly recursive - requiring a huge number of procedural calls;

• can cause recursion stack to overflow

• no mechanism to determine whether the visited

pixels have been tested before

(2)

Fill Until vs. Fill While

seed

void floodUntil(int x, int y, int n_color, int B_color)

{

if ((x < 0) || (x >= width)) return;

if ((y < 0) || (y >= height)) return;

c = getPixel(x, y);

if (c != n_color && c != B_color) { setPixel(new_color, x, y);

floodFill(x+1, y, n_color B_color);

floodFill(x, y+1, n_color B_color);

floodFill(x-1, y, n_color B_color);

floodFill(x, y-1, n_color B_color);

} }

Flood Until

void floodWhile(int x, int y, int n_color, int old)

{

if ((x < 0) || (x >= width)) return;

if ((y < 0) || (y >= height)) return;

if (getPixel(x, y) == old) { setPixel(fill, x, y);

floodFill(x+1, y, n_color, old);

floodFill(x, y+1, n_color, old);

floodFill(x-1, y, n_color, old);

floodFill(x, y-1, n_color, old);

} }

Flood While

void floodWhile(int x, int y) {

if ((x < 0) || (x >= width)) return;

if ((y < 0) || (y >= height)) return;

if (getPixel(x, y) == old_color) { setPixel(n_color, x, y);

floodFill(x+1, y);

floodFill(x, y+1);

floodFill(x-1, y);

floodFill(x, y-1);

} }

With global variables

Use a stack

Queue q = Ø Add the seed to q While(!q.empty()) {

P = q.pop();

For (x = P’s neighboring pixels) { If (getPixel(x) == old) {

setPixel(x, new_color);

q.push(x);

p r o c e d u r e F l o o d W h i l e ( x , y : i n t e g e r ; o l d V a l , n a w V a l : c o l o r ) ;

b e g i n

i f R e a d P i x e l ( x , y ) = o l d V a l t h e n b e g i n

W r i t e P i x e l ( x , y , n e w V a l ) ; F l o o d W h i l e ( x , y - 1 , o l d V a l , n e w V a l ) ; F l o o d W h i l e ( x , y + 1 , o l d V a l , n e w V a l ) ; F l o o d W h i l e ( x - 1 , y , o l d V a l , n e w V a l ) ; F l o o d W h i l e ( x + 1 , y , o l d V a l , n e w V a l ) ; e n d

e n d ;

p r o c e d u r e F l o o d U n t i l ( x , y : i n t e g e r ; b o u n d a r y V a l , n a w V a l : c o l o r ) ;

v a r c : c o l o r b e g i n

c : = r e a d P i x e l ( x , y ) ;

i f ( c < > b o u n d a r y V a l ) a n d ( c < > n e w V a l ) t h e n b e g i n

W r i t e P i x e l ( x , y , n e w V a l ) ;

F l o o d U n t i l ( x , y - 1 , b o u n d a r y V a l , n e w V a l ) ; F l o o d U n t i l ( x , y + 1 , b o u n d a r y V a l , n e w V a l ) ; F l o o d U n t i l ( x - 1 , y , b o u n d a r y V a l , n e w V a l ) ; F l o o d U n t i l ( x + 1 , y , b o u n d a r y V a l , n e w V a l ) ; e n d

:KLOHYV8QWLO

(3)

Serial Recursion is Depth-First

So the fill algorithm will continue in one direction until a boundary is reached.

It will then change directions momentarily and attempt to continue back in the original direction.

Potential problem of stack overflow. How to avoid it?

Breath-first Traversal

Queue q = Ø Add the seed to q While(!q.empty()) {

P = q.removefirst();

For (x = P’s neighboring pixels) { If (getPixel(x) == old) {

setPixel(x, fill);

q.insert(x);

} } }

Recursive Flood-Fill Algorithm

• Can also have an “until” version, defining region by boundary

• Recursive flood-fill is somewhat blind and many pixels may be retested several times

• Tag a pixel with a direction and avoid redundant calls…

• Row coherence can improve performance dramatically

Row Coherence

Push address of seed pixel onto stack while(stack is not empty)

{

Pop the stack to provide next seed Fill in the run defined by the seed In the adjacent rows (above and below)

find the reachable interior runs, and push the address of their rightmost pixels }

Floodfill in runs

S

Floodfill in runs

C B A Stack C

B A

(4)

Floodfill in runs

B A Stack

B A

Floodfill in runs

D A Stack D

A

Floodfill in runs

A Stack A

Floodfill in runs

Stack

Row Coherence

S

Row Coherence

a

b

(5)

Row Coherence

c a

b d e

Row Coherence

c a

d f g

The Stack then

contains:

a,c,d,f,g

F l o o d F i l l A l g o r i t h m

p r o c e d u r e F i l l ( x , y : i n t e g e r ; o l d V a l , n e w V a l : c o l o r ) ; b e g i n

p u s h ( x , y ) ; w h i l e s t a c k i s n o t e m p t y b e g i n

p o p ( x , y ) ; o p e n _ u p = F A L S E ; o p e n _ d o w n = F A L S E ; w h i l e c o l o r [ x - - , y ] = = o l d V a l ;

/ * m o v e t o m o s t l e f t p i x e l * / w h i l e c o l o r [ x + + , y ] = = o l d V a l

b e g i n

c o l o r [ x , y ] = n e w V a l ; i f o p e n _ u p = = F A L S E b e g i n

i f c o l o r [ x , y + 1 ] = = o l d V a l b e g i n

p u s h ( x , y + 1 ) ; o p e n _ u p = T R U E ; e n d ;

e n d

e l s e i f c o l o r [ x , y + 1 ] < > o l d V a l o p e n _ u p = F A L S E ; i f o p e n _ d o w n = = F A L S E b e g i n

i f c o l o r [ x , y - 1 ] = = o l d V a l b e g i n

p u s h ( x , y - 1 ) ; o p e n _ d o w n = T R U E ; e n d ;

e n d

e l s e i f c o l o r [ x , y - 1 ] < > o l d V a l o p e n _ d o u n = F A L S E ; e n d ;

e n d ; e n d ; e n d ;

References

Related documents

This contract will also provide CAA training for selected USAF pilots involved in the F-5 Security Assistance Training Program. Detailed results of the evaluation are in

The second alternative basis assessment proposed by the Revenue is for a current year basis, a deeming procedure which taxes income accruing in a particular accounting period as if

Until a regulatory floodway is designated, no new construction, substantial improvements, or other development (including fill) shall be permitted within the areas of special

response is unimpaired in thoracic aorta. ACh response is expressed as % relaxation of a PE induced contraction. A) Proximal ring relaxation response. B) Middle ring

The estimated value is £12 based on the catalogue price adjusted to take condition into account.. How much do

Abrasion, corrosion, and thermal alteration are the main taphonomic processes related to the loss of original shell color, and can significantly affect the surface coloration

A cross-sectional cohort study of mothers and their infants between birth and six months attending BFHI and non BFHI accredited health facilities in Blantyre district of Malawi

The first one emphasizes integration, considering meaning as a sense of coherence, order and connection that allows to perceive events, phenomena, individuals, living beings