寒江雪 區域填充演算法 掃瞄線

2021-07-24 16:30:54 字數 2889 閱讀 5641

區域填充遞迴演算法已經領教過了。記憶體消耗大,時間效率低,經典的深搜思想。為了解決這個問題,於是有人提出了種子填充掃瞄線演算法。其實就是深搜不行,換寬搜(bfs)

該演算法假設已知其中乙個畫素點,然後從這個畫素點出發,去尋找周圍可以著色的點。

這個已知點,我們稱其為種子點。

每一輪著色之後,記錄下著色的區間大小,並對該區間上方和下方的掃瞄線進行掃瞄,觀察能否對其進行著色,如果能,則把種子點加入佇列中,待下次掃瞄使用。對於一條掃瞄線,可能有很多可著色區間,因此需要掃瞄更多的種子點,加入佇列中。

該演算法同樣分為兩種來討論

1.    以邊色為界限的著色

a)     先將種子點加入佇列中

b)     如果佇列不為空則繼續往下執行,否則演算法結束

c)     從佇列中取出種子點

d)     以種子點為起點,往右邊著色直到邊界,記錄區間右界xr

e)     以種子點為起點,往左邊著色直到邊界,記錄區間左界xl

f)      對區間[xl,xr]掃瞄上一條掃瞄線,遇到顏色不為邊界顏色的點,尋找其最右邊界,並標記為可以加入佇列。遇到邊界點則不再往下尋找

g)     如果可以加入佇列,則往佇列中加入新的種子點

h)     對下邊一條掃瞄線做同樣的操作。

**如下

struct seed;

void

cgraphicdlg::scanlineboundaryfill(int

x, int

y, colorref

edgecolor, colorref

newcolor) );

while (!que.empty())

xr = x - 1;

x = pt.x - 1;

while (getcoordinatepixel(x, y) != edgecolor)

xl = x + 1; //

處理上一條掃瞄線

x = xl;

y = pt.y+1;

while (x <= xr)

if (spanneedfill) );

spanneedfill = false; }

while (getcoordinatepixel(x, y) == edgecolor ) }

//處理下一條掃瞄線

x = xl;

y = pt.y - 1;

while (x <= xr)

if (spanneedfill) );

spanneedfill = false; }

while (getcoordinatepixel(x, y) == edgecolor) }

}return

void(); }

效果圖如下:

2.    以點色為界限的著色

a)     先將種子點加入佇列中

b)     如果佇列不為空,則演算法繼續執行,否則演算法結束

c)     從佇列中取出種子點

d)     以種子點為起點,往右填充,對於顏色與舊顏色一樣的畫素填充新顏色。如果顏色與舊顏色不一樣則不再往下填色。記錄區間右邊界xr

e)     以種子點為起點,往左填充,對於顏色與舊顏色一樣的畫素填充新顏色。如果顏色與舊顏色不一樣則不再往下填色。記錄區間左邊界xl

f)      對上一條掃瞄線區間[xl,xr]進行掃瞄,如果找到顏色與舊顏色一樣的畫素,則標記為該掃瞄線可填充,如果找到顏色與舊顏色不一樣的畫素則停止尋找。

g)     如果該掃瞄線有可填充的點,則把該點作為種子點加入佇列中。

h)     繼續尋找該掃瞄線其他掃瞄點,直到x達到xr

i)      對下一條掃瞄線做同樣的操作

**如下

void

cgraphicdlg::scandlinepointfill(int

x, int

y, colorref

oldcolor, colorref

newcolor) );

while (!que.empty())

xr = x - 1;

x = pt.x - 1;

while (getcoordinatepixel(x, y) == oldcolor)

xl = x + 1; //

處理上一條掃瞄線

x = xl;

y = pt.y + 1;

while (x

<= xr)

if (spanneedfill) ); }

while (getcoordinatepixel(x, y) != oldcolor&&x

<= xr)x++; }

//處理下一條掃瞄線

x = xl;

y = pt.y - 1;

while (x

<= xr)

if (spanneedfill) ); }

while (getcoordinatepixel(x, y) != oldcolor&&x

<= xr)x++;

} }

return

void(); }

效果圖如下(純色基礎)

效果圖如下(無純色基礎)

效果圖如下(座標軸點為起始種子點)

區域填充之掃瞄線演算法

區域的填充可以根據區域的填充,採用不同的填充演算法,而其中有掃瞄線類演算法和種子填充演算法。這裡,先介紹掃瞄線類演算法之有序邊表的掃瞄線演算法。其他什麼種子填充 邊界標誌演算法 4連通區域的遞迴演算法 8連通區域的遞迴演算法 掃瞄線種子填充演算法比較簡單。其實有序邊表其實領會了也好理解,關鍵是將思想...

多邊形區域填充演算法 掃瞄線種子填充演算法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!1.3掃瞄線種子填充演算法 1.1和1.2節介紹的兩種種子填充演算法的優點是非常簡單,缺點是使用了遞迴演算法,這不但需要大量棧空間來儲存相鄰的點,而且效率不高。為了減少演算法中的遞迴呼叫,節省棧空間的使用,人們提出了很多改進演算法,其中一種就是掃瞄...

二維區域掃瞄線填充演算法的實現

下面是乙個簡單的填充效果 include include define filling 1 define reset 2 typedef struct line,pline line lines 100 line line static int j 0 point draw refresh 1000...