平面領域塗りつぶしアルゴリズムは、コンピュータグラフィックスの分野で非常に重要なアルゴリズムです。領域塗りつぶしは、領域の境界を与える(または境界なし、指定された色を与える)ためのものであり、境界内のすべてのピクセル単位が必要です。指定した色(またはパターンの塗りつぶし)に変更します。最も一般的に使用される領域塗りつぶしは、ポリゴン塗りつぶしです。この記事では、いくつかの多角形領域塗りつぶしアルゴリズムについて説明します。
1.シードフィリングアルゴリズム(シードフィリング)
塗りつぶす領域が画像メタデータの形式で指定されている場合、通常、シード塗りつぶしアルゴリズム(シード塗りつぶし)が領域塗りつぶしに使用されます。シード塗りつぶしアルゴリズムは、画像データの領域と領域内の点を与える必要があります。このアルゴリズムは、人間とコンピューターの相互作用によって実行される画像塗りつぶし操作に適しています。コンピューターの自動処理や色の判断には適していません。画像領域の境界を定義する方法とポイントの色を変更する方法によれば、シード塗りつぶしは、塗りつぶしアルゴリズム(塗りつぶしアルゴリズム)、境界塗りつぶしアルゴリズム(境界塗りつぶしアルゴリズム)などのいくつかのカテゴリに細分でき、再帰とスタックを減らすことができます。スキャンラインシード塗りつぶしアルゴリズムなどの改善。
すべてのシードフィルアルゴリズムの中核は、実際には再帰的アルゴリズムであり、指定されたシードポイントから始まり、すべての方向に検索し、境界に到達するまでピクセルごとに処理します。さまざまなシードフィルアルゴリズムは、色と境界を処理するだけです。上記は異なります。シードフィリングアルゴリズムを紹介する前に、「4-Unicomアルゴリズム」と「8-Unicomアルゴリズム」という2つの概念も紹介します。これは検索なので、検索の方向が関係します。エリア内の任意のポイントから開始して、上下左右の4方向を介してエリア内のピクセルを検索するだけの場合、このメソッドで塗りつぶされたエリアが呼び出されます4つの接続されたドメインの場合、この充填方法は「4接続アルゴリズム」と呼ばれます。エリアの任意のポイントから開始し、8つの方向すべて(上、下、左、右、左上、左下、右上、右下)を介してエリアの任意のピクセルに到達する場合、このメソッドで塗りつぶされたエリアは、8つの接続されたドメインと呼ばれます。この充填方法は「8-Unicom Algorithm」と呼ばれます。図1(a)に示すように、中央の青い点が現在処理中の点であるとします。「4-Unicomアルゴリズム」の場合は、処理の周囲に青色でマークされた4つの点のみが検索されて処理されます。「8-Unicomアルゴリズム」の場合「青いマークされた4つのポイントを上下左右に処理するだけでなく、赤いマークされた4つのポイントも検索して処理します。2つの検索アルゴリズムの塗りつぶし効果をそれぞれ図1(b)と図1(c)に示します。塗りつぶしが黄色の点から始まる場合、「4-Unicom Algorithm」は図1(b)に示すようにのみ検索します左下隅の領域を塗りつぶし、図1(c)に「8-Unicomアルゴリズム」を示し、左下隅と右上隅の領域を塗りつぶします。
図(1)「4-Unicom」と「8-Unicom」の塗りつぶし効果
図1の塗りつぶし効果のためだけではなく、「8-Unicomアルゴリズム」は「4-Unicomアルゴリズム」より優れている必要があります。Unicom検索方法は、アプリケーション環境と実際のニーズに応じて選択する必要があります。多くの場合、「4-Unicom」のみです。アルゴリズム」は正しい結果を得ることができます。
1.1塗りつぶしアルゴリズム(塗りつぶしアルゴリズム)
注入塗りつぶしアルゴリズムは、領域の境界を特に強調せず、指定された位置から始まり、接続されているすべての領域の特定の指定された色の点を別の色に置き換えて、塗りつぶし効果を実現します。注入充填アルゴリズムは、画像処理ソフトウェアで広く使用されている色置換などの機能を実現できます。注入充填アルゴリズムの実装は非常に単純です。コアは再帰と検索です。以下は、注入充填アルゴリズムの実装です。
164 void FloodSeedFill (int x 、 int y 、 int old_color 、 int new_color ) 165 { 166 if ( GetPixelColor ( x 、 y ) == old_color ) 167 { 168 SetPixelColor ( x 、 y 、 new_color ); 169 for (int i = 0 ; i < COUNT_OF ( direction_8 ); i ++) 170 { 171 FloodSeedFill ( x + direction_8 [ i ]。x_offset 、 172 y + direction_8 [ i ]。y_offset 、 old_color 、 new_color ); 173 } 174 } 175 } |
forループは、8つのUnicom方向で再帰的な検索を実現します。秘密は、direction_8の定義にあります。
15 typedef struct tagDIRECTION 16 { 17 int x_offset ; 18 int y_offset ; 19 } DIRECTION 。 |
79 DIRECTION direction_8[] = { {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} }; |
这个是搜索类算法中常用的技巧,无需做太多说明,其实只要将其替换成如下direction_4的定义,就可以将算法改成4个联通方向填充算法:
80 DIRECTION direction_4[] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} }; |
图2就是应用本算法实现的“4-联通”和“8-联通”填充效果:
图(2) 注入填充算法实现
1.2 边界填充算法(Boundary Fill Algorithm)
边界填充算法与注入填充算法的本质其实是一样的,都是递归和搜索,区别只在于对边界的确认,也就是递归的结束条件不一样。注入填充算法没有边界的概念,只是对联通区域内指定的颜色进行替换,而边界填充算法恰恰强调边界的存在,只要是边界内的点无论是什么颜色,都替换成指定的颜色。边界填充算法在应用上也非常的广泛,画图软件中的“油漆桶”功能就是边界填充算法的例子。以下就是边界填充算法的一个实现:
177 void BoundarySeedFill(int x, int y, int new_color, int boundary_color) 178 { 179 int curColor = GetPixelColor(x, y); 180 if( (curColor != boundary_color) 181 && (curColor != new_color) ) 182 { 183 SetPixelColor(x, y, new_color); 184 for(int i = 0; i < COUNT_OF(direction_8); i++) 185 { 186 BoundarySeedFill(x + direction_8[i].x_offset, 187 y + direction_8[i].y_offset, new_color, boundary_color); 188 } 189 } 190 } |
关于direction_8的说明请参考上一节,图3就是应用本算法实现的“4-联通”和“8-联通”填充效果(其中颜色值是1的点就是指定的边界):
图(3) 边界填充算法实现
<下一篇:扫描线种子填充算法>