O algoritmo de preenchimento de área plana é um algoritmo muito importante no campo da computação gráfica. O preenchimento de área é para fornecer o limite de uma área (ou nenhum limite, basta fornecer a cor especificada), e todas as unidades de pixel dentro do limite são necessárias Modifique-o para a cor especificada (ou preenchimento de padrão). O preenchimento de área mais comumente usado é o preenchimento de polígono. Neste artigo, discutiremos vários algoritmos de preenchimento de área de polígono.
1. Algoritmo de enchimento de sementes (enchimento de sementes)
Se a área a ser preenchida é fornecida na forma de metadados de imagem, o algoritmo de enchimento de sementes (Seed Filling) geralmente é usado para o enchimento da área. O algoritmo de enchimento de sementes precisa fornecer a área dos dados da imagem e um ponto na área. Este algoritmo é mais adequado para operações de enchimento de imagens realizadas por interação homem-computador, e não é adequado para processamento automático de computador e julgamento de cores. De acordo com o método de definição do limite da área da imagem e o método de modificação da cor do ponto, o enchimento de sementes pode ser subdividido em várias categorias, como algoritmo de preenchimento (algoritmo de preenchimento), algoritmo de preenchimento de limite (algoritmo de preenchimento de limite) e para reduzir a recursão e empilhamento Algoritmo de enchimento de sementes de linha de varredura aprimorado e assim por diante.
O núcleo de todos os algoritmos de enchimento de sementes é na verdade um algoritmo recursivo, que começa a partir de um ponto de semente especificado, pesquisa em todas as direções e processa pixel por pixel até encontrar um limite. Vários algoritmos de enchimento de sementes estão apenas processando cores e limites. O acima é diferente. Antes de introduzir o algoritmo de enchimento de sementes, dois conceitos também são introduzidos, a saber, "Algoritmo 4-Unicom" e "Algoritmo 8-Unicom". Por ser uma pesquisa, envolve a direção da pesquisa. A partir de qualquer ponto da área, se você pesquisar apenas qualquer pixel na área através das quatro direções para cima, para baixo, para a esquerda e para a direita, a área preenchida com este método é chamada Para quatro domínios conectados, este método de preenchimento é chamado de "algoritmo 4-conectado". Se você começar de qualquer ponto na área e alcançar qualquer pixel na área através de todas as oito direções: cima, baixo, esquerda, direita, superior esquerdo, inferior esquerdo, superior direito e inferior direito, a área preenchida por este método é chamada de domínio oito conectado. Este método de preenchimento é denominado "Algoritmo 8-Unicom". Conforme mostrado na Figura 1 (a), suponha que o ponto azul no centro seja o ponto atualmente sendo processado. Se for o "algoritmo 4-Unicom", apenas os quatro pontos marcados em azul ao redor do processamento serão pesquisados e processados. Se for o "algoritmo 8-Unicom" "Além de processar os quatro pontos marcados em azul para cima, para baixo, esquerda e direita, ele também pesquisa e processa quatro pontos marcados em vermelho. Os efeitos de preenchimento dos dois algoritmos de pesquisa são mostrados na Figura 1 (b) e Figura 1 (c), respectivamente. Se o preenchimento começar a partir dos pontos amarelos, o "algoritmo 4-Unicom" pesquisa apenas como mostrado na Figura 1 (b) Preencha a área no canto esquerdo inferior, e o "algoritmo 8-Unicom" é mostrado na Figura 1 (c), preenchendo as áreas do canto esquerdo inferior e canto superior direito.
Figura (1) Efeito de preenchimento de "4-Unicom" e "8-Unicom"
Não é apenas por causa do efeito de preenchimento na Figura 1 que o "algoritmo 8-Unicom" deve ser melhor do que o "algoritmo 4-Unicom". O método de pesquisa Unicom deve ser selecionado de acordo com o ambiente do aplicativo e as necessidades reais. Em muitos casos, apenas "4-Unicom" Algoritmo "pode obter o resultado correto.
1.1 Algoritmo de Preenchimento (Flood Fill Algorithm)
O algoritmo de preenchimento por injeção não enfatiza particularmente o limite da área, ele apenas começa na posição especificada e substitui os pontos de uma determinada cor em todas as áreas conectadas por outra cor para obter o efeito de preenchimento. O algoritmo de enchimento de injeção pode realizar funções como substituição de cor, que tem sido amplamente utilizada em software de processamento de imagem. A implementação do algoritmo de enchimento por injeção é muito simples. O núcleo é a recursão e a pesquisa. O seguinte é uma implementação do algoritmo de enchimento por injeção:
164 vazio FloodSeedFill ( int x , int y , int old_color , int new_color ) 165 { 166 if ( GetPixelColor ( x , y ) == old_color ) 167 { 168 SetPixelColor ( x , y , nova_cor ); 169 para ( 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 } |
O loop for realiza a pesquisa recursiva nas 8 direções Unicom. O segredo está na definição de direction_8:
15 typedef struct tagDIRECTION 16 { 17 int x_offset ; 18 int y_offset ; 19 } DIREÇÃO ; |
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) 边界填充算法实现
<下一篇:扫描线种子填充算法>