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