Painterly Rendering com
pinceladas curvas
Autores:
Fabiano Segadaes Romeiro
Leandro de Mattos Ferreira
Processamento de Imagens – IMPA 2001
Objetivos
• Criar um programa que , utilizando-se de
métodos da computação gráfica, permita a
reprodução de diversas técnicas de pintura
de forma prática , automatizada e
intuitiva.
• Permitir a criação de novos estilos por
meio da alteração de parâmetros
compreensíveis.
Método de pintura
• O processo físico de pintar utiliza-se de
•
pinceladas de diversos tamanhos e em várias
direções. Estas pinceladas sozinhas, não têm
muito significado, mas quando em conjunto
formam os efeitos desejados na pintura.
Este algoritmo começa a pintura com pincéis
grandes , e depois a refina com pinceladas cada
vez mais finas, assim como um artista
normalmente faz.
Método de Pintura
Imagem de Teste – O Lagarto
Método de Pintura
Pintura no estilo Expressionista – processo detalhado
1 – Após pinceladas com o
maior pincel (8 pixels)
2 – Após pinceladas com o
pincel médio (4 pixels)
3 – Após pinceladas com o
pincel médio (2 pixels)
4 – Após pinceladas com o
menor pincel (1 pixel)
Método de Pintura
Resultado Final – O Lagarto expressionista
O algoritmo
• Inicialmente, produz-se uma tela a partir da
imagem original. Cada pixel desta tela receberá
a cor mais distante, no espaço RGB, do pixel
correspondente na imagem original.
• Esta distância é calculada pela seguinte fórmula:
|(r1,g1,b1)-(r2,g2,b2)|=[(r1-r2)2 +(g1-g2)2 + (b1-b2)2]0,5
O algoritmo
• Sobre essa tela começamos a pintar as camadas
•
•
•
•
correspondentes a cada tamanho de pincel.
Calculamos inicialmente as summed area tables (sat)
correspondentes as componentes R, G e B da imagem
original.
Pintamos primeiramente a camada correspondente ao
pincel de maior tamanho sobre a tela, utilizando para
isso uma imagem de referência, gerada por um Blur da
imagem original.
Esse Blur é realizado através das sat, realizando para
cada pixel uma média entre os pixels que o cercam
(quanto maior o pincel, mais pixels são utilizados e mais
borrada a imagem fica)
Prosseguimos pintando as camadas para os outros
pincéis, em ordem decrescente de tamanho.
Algoritmo de pintura
•
•
•
•
•
•
•
•
•
•
•
•
•
Image *paint(Image *srcImage, pr_params pp )
{
fill_sat(srcImage, sat_r, sat_g, sat_b);
fill_canvas(canvas, srcImage);
for each brush radius R in pp
from largest to smallest do
{
satBlur(referenceImage, R, sat_r, sat_g, sat_b);
paintLayer(canvas, referenceImage, pp,R)
}
return canvas
}
O Algoritmo – Pintura das camadas
• Cria-se uma matriz que contem as
diferenças entre os pixels da imagem
original e da tela no seu estado atual.
• Varremos então a imagem de referência
(dividida em grids).
• Para cada grid traçamos a pincelada
correspondente.
• Utilização de z-buffer para as pinceladas.
O Algoritmo – Pintura das camadas
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
void paintLayer(canvas,referenceImage,pp, R)
{
Z_buff = matriz do z_buffer
D = difference(canvas,referenceImage)
grid = pp.f_grid*R
for (x=0;x< imageWidth;x+=grid)
for (y=0; y< imageHeight;y+=grid)
{
M= região (xgrid/2..x+grid/2, ygrid/2..y+grid/2)
areaError = (sum(Di,j) for i in M )/ grid*grid;
if (areaError > pp.Threshold)
{
(x1,y1) = ponto com Di,j máximo, com i pertencente a M
makeSplineStroke(R,x1 ,y1 ,referenceImage,canvas, pp,z_buff)
}
}
}
O Algoritmo - Pinceladas
• Para calcularmos a pincelada, partimos do
ponto de controle inicial, seguindo na
direção normal ao gradiente da luminância
da imagem original.
• Obtemos assim os demais pontos de
controle, sobre os quais traçamos a
pincelada como uma spline
O Algoritmo – Pinceladas
Void makeSplineStroke(R, x1, y1, referenceImage,canvas,pp,z_buff)
{
• strokeColor = referenceImage.color(x1 ,y1 )
• K = matriz que irá receber a pincelada
• adiciona (x1 ,y1 ) a K
• (x,y) = (x 1,y1 )
• (lastDx,lastDy) = (0,0)
• for (i=1;i<maxStrokeLength;i++)
• {
•
if (i > minStrokeLength and |refImage.color(x,y)canvas.color(x,y)|<|refImage.color(x,y)strokeColor|)
•
break;
•
if (refImage.gradient(x,y) ==(0, 0)) then
•
break;
•
(gx,gy) = refImage.gradientDirection(x,y)
•
(dx,dy) = (gy, gx)
• if (lastDx * dx + lastDy * dy < 0)
• (dx,dy) = (dx, dy)
• (dx,dy) =pp.f c *(dx,dy)+(1pp.f c )*(lastDx,lastDy)
• (dx,dy) = (dx,dy)/(dx 2 + dy 2 ) 1/2
• (x,y) = (x+R*dx, y+R*dy)
• (lastDx,lastDy) = (dx,dy)
• adiciona (x,y) to K
• }
• plotSplineStroke(canvas, strokeColor, K,z_buff);
}
Resultados e conclusões
• Ao longo do desenvolvimento, com a
interface gráfica o programa teve o seu
manuseio bastante facilitado, sobretudo
na geração de novos estilos de
renderização das pinturas.
• Tendo concluido o programa, testamos
diferentes parâmetros/estilos, que
geraram imagens bastante interessantes.
Estilos - Impressionista
Estilos – Colorist Wash
Estilos - Pontilhismo
Estilos – Psychodelic
Estilos – Ridist
Painterly Rendering
FIM
Download

Painterly Rendering