2012-03-13 10 views
6

Soy un principiante en actionscript. Si entiendo correctamente, el DisplacementMapFilter mueve los píxeles de una 'imagen fuente' de acuerdo con el color de la posición de píxel correspondiente en una 'imagen MAP'.¿Cómo funciona el DisplacementMapFilter?

¡El problema es que mi imagen de destino contiene píxeles que NO están en la imagen de origen!

Por ejemplo, tomo una UNICOLOR 10 x 10 píxeles 'imagen de origen' con este bitmapData:

sourceBitmap = new BitmapData(BITMAP_WIDTH, BITMAP_HEIGHT, false, 0x000002); 

produce: 

    0 1 2 3 4 5 6 7 8 9 
[002,002,002,002,002,002,002,002,002,002] Row 0 
[002,002,002,002,002,002,002,002,002,002] Row 1 
[002,002,002,002,002,002,002,002,002,002] Row 2 
[002,002,002,002,002,002,002,002,002,002] Row 3 
[002,002,002,002,002,002,002,002,002,002] Row 4 
[002,002,002,002,002,002,002,002,002,002] Row 5 
[002,002,002,002,002,002,002,002,002,002] Row 6 
[002,002,002,002,002,002,002,002,002,002] Row 7 
[002,002,002,002,002,002,002,002,002,002] Row 8 
[002,002,002,002,002,002,002,002,002,002] Row 9 

Ahora, aprovecho mapa de desplazamiento NEGRO Y añado una pequeña plaza AZUL:

displacementBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0x000000); 
for(i=5;i<10;i++) 
    for(j=5;j<10;j++) 
     displacementBitmap.setPixel(i,j,255); 

produce: 

0 1 2 3 4 5 6 7 8 9 
[000,000,000,000,000,000,000,000,000,000] Row 0 
[000,000,000,000,000,000,000,000,000,000] Row 1 
[000,000,000,000,000,000,000,000,000,000] Row 2 
[000,000,000,000,000,000,000,000,000,000] Row 3 
[000,000,000,000,000,000,000,000,000,000] Row 4 
[000,000,000,000,000,255,255,255,255,255] Row 5 
[000,000,000,000,000,255,255,255,255,255] Row 6 
[000,000,000,000,000,255,255,255,255,255] Row 7 
[000,000,000,000,000,255,255,255,255,255] Row 8 
[000,000,000,000,000,255,255,255,255,255] Row 9 

El resultado:

displacementFilter = new DisplacementMapFilter(); 
displacementFilter.alpha=0; 
displacementFilter.color=0; 
displacementFilter.mapPoint=new Point(0,0); 
displacementFilter.scaleX=1; 
displacementFilter.scaleY=1; 
displacementFilter.componentX = flash.display.BitmapDataChannel.BLUE; 
displacementFilter.componentY = flash.display.BitmapDataChannel.BLUE; 
displacementFilter.mapBitmap = displacementBitmap; 

destinationBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0xFFFFFFFF); 
destinationBitmap.applyFilter(
    sourceBitmap.bitmapData, 
    new Rectangle(0,0,BITMAP_WIDTH,BITMAP_HEIGHT), 
    new Point(0,0), 
    displacementFilter 
); 

produce:   

    0 1 2 3 4 5 6 7 8 9 
[002,002,002,002,002,002,002,002,002,002] Row 0 
[002,002,002,002,002,002,002,002,002,002] Row 1 
[002,002,002,002,002,002,002,002,002,002] Row 2 
[002,002,002,002,002,002,002,002,002,002] Row 3 
[002,002,002,002,002,002,002,002,002,002] Row 4 
[002,002,002,002,002,001,001,001,001,001] Row 5 
[002,002,002,002,002,001,001,001,001,001] Row 6 
[002,002,002,002,002,001,001,001,001,001] Row 7 
[002,002,002,002,002,001,001,001,001,001] Row 8 
[002,002,002,002,002,001,001,001,001,001] Row 9 

así que no entiendo por qué tengo '' 001 píxeles cuáles no existe en la imagen de origen.

Muchas gracias.

+0

Y ahora, es hora de un enchufe desvergonzado para mi [pregunta] (http://stackoverflow.com/questions/9260717/displacement-map-filter-in-opencv). – karlphillip

Respuesta

3

El filtro de mapa de desplazamiento decide qué píxel para agarrar desde el mapa de bits fuente utilizando this formula:

dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX)/256, y + ((componentY(x, y) - 128) *scaleY)/256) 

dstPixel es el mapa de bits de destino, srcPixel es el mapa de bits fuente, y componentX/Y es desde el mapa de bits de desplazamiento. La asignación está determinada por cuán lejos está el canal componente de 128. Observe que 128 es el valor neutral donde no hay transformación, y se utiliza el mismo píxel fuente.

Por ejemplo, consideremos el píxel en (1, 1) en su caso. Su canal componente es azul, y el canal azul en (1, 1) en el mapa de desplazamiento tiene un valor de 0. Entonces lo desplazamos entre (0 - 128)/256, o -0.5. Entonces, el píxel final que tomamos del mapa de bits de origen está en (0.5, 0.5).

Pero, ¿qué significa usar la mitad de un píxel? Resulta que Flash usa bilinear filtering para suavizar los resultados. Usted termina con una mezcla de los colores en los cuatro píxeles entre (0,0) y (1,1).

Esta es la razón por la que está viendo píxeles impares que no están en la imagen de origen. Aunque todos los píxeles de la imagen de origen son del mismo color, parece haber algunas imprecisiones de punto flotante cuando Flash interpola entre los colores, por lo que a veces obtienes un valor de ligeramente desactivado. Tenga en cuenta que si utiliza un valor en su mapa de bits de desplazamiento que se divide "limpiamente" entre 128, como 0 o 64, obtendrá el resultado correcto. Pero si usas un valor como 255 o 19, obtienes algún error.

Desafortunadamente, no parece haber ninguna forma de desactivar el filtrado y utilizar un muestreo simple de vecino más cercano. Por lo tanto, si necesita garantizar que no se introducen nuevos colores, debe seleccionar cuidadosamente los valores en su mapa de desplazamiento.

Como alternativa, puede usar Pixel Bender para crear un kernel que hace lo que necesita. Pixel Bender le permite hacer un muestreo de vecino más cercano desde un mapa de bits de origen.

+0

Perfecto. Muchas gracias. –