android image-processing android-canvas motion-blur

¿Cómo desenfocar una parte de la imagen en Android?



image-processing android-canvas (1)

Estoy trabajando en un proyecto donde tengo que mostrar una parte de la imagen clara y hacer que el resto de la imagen sea borrosa. El desenfoque debe ser gestionado por el control deslizante. Significa que puede aumentar o disminuir. La imagen del resultado final debería parecerse a continuación.

Durante mi investigación para esto, encontré los siguientes enlaces útiles

  1. http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/

  2. https://github.com/kikoso/android-stackblur

  3. http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/

Pero el problema en los enlaces anteriores es que todos hacen que la imagen se vea borrosa. No es una parte de la imagen.

Amablemente sugiera alguna solución para lograr esto. Gracias por adelantado.


hacer un desenfoque enmascarado varias veces ...

  1. crear máscara

    0 significa desenfoque (negro) y >=1 significa no desenfoque (blanco). Inicie esta parte con un valor lo suficientemente grande, por ejemplo w=100 píxeles

  2. crear función de desenfoque enmascarado

    solo una convolución común con alguna matriz como

    0.0 0.1 0.0 0.1 0.6 0.1 0.0 0.1 0.0

    pero hágalo solo para los píxeles de destino donde la máscara es ==0 después de que la imagen se vea borrosa, desenfoque también la máscara. Esto debería agrandar un poco el área blanca (por píxel por iteración pero perdiendo magnitud en los bordes, por eso w>1 ).

  3. bala de bucle # 2 N veces

    N determina la profundidad del gradiente de desenfoque / no desenfoque, la w es solo para asegurar que la máscara con burros crecerá ... Cada vez que la máscara de desenfoque aumente su parte blanca

Eso debería ser el truco. También puedes usar la dilatación de la máscara en lugar de difuminarla.

[edit1] implementación

Hoy he jugado un poco con esto y descubrí que la máscara no está creciendo lo suficiente con suavidad, así que cambio un poco el algoritmo (aquí el código C ++):

picture pic0,pic1,pic2; // pic0 - source // pic1 - output // pic2 - mask int x0=400,y0=330,r0=100,dr=200; // x0,y0,r0 - masked area // dr - blur gradient size int i,r; // init output as sourceimage pic1=pic0; // init mask (size of source image) with gradient circles pic2.resize(pic0.xs,pic0.ys); pic2.clear(0); for (i=1;i<=255;i++) { r=r0+dr-((dr*i)>>8); pic2.bmp->Canvas->Brush->Color=TColor(i<<16); // shifted because GDI has inverse channel layout then direct pixel access pic2.bmp->Canvas->Pen ->Color=TColor(i<<16); pic2.bmp->Canvas->Ellipse(x0-r,y0-r,x0+r,y0+r); } for (i=1;i<255;i+=10) pic1.rgb_smooth_masked(pic2,i);

Aquí la función suave:

//--------------------------------------------------------------------------- void picture::rgb_smooth_masked(const picture &mask,DWORD treshold) { int i,x,y; color *q0,*q1,*m0,c0,c1,c2; if ((xs<2)||(ys<2)) return; for (y=0;y<ys-1;y++) { q0=p[y ]; m0=mask.p[y]; q1=p[y+1]; for (x=0;x<xs-1;x++) if (m0[x].dd<treshold) { c0=q0[x]; c1=q0[x+1]; c2=q1[x]; for (i=0;i<4;i++) q0[x].db[i]=DWORD((DWORD(c0.db[i])+DWORD(c0.db[i])+DWORD(c1.db[i])+DWORD(c2.db[i]))>>2); } } } //---------------------------------------------------------------------------

  1. crea una máscara de degradado con círculos que aumentan de color de 1 a 255

    el resto es negro, el ancho del gradiente es dr y determina la nitidez de suavizado.

  2. crear suave enmascarado con máscara y umbral

    suaviza todos los píxeles donde el píxel de máscara es <umbral. Vea la función rgb_smooth_masked . Utiliza matriz de convolución 2x2

    0.50,0.25 0.25,0.00

  3. umbral de bucle de 1 a 255 por algún paso

    El paso determina la intensidad de desenfoque de la imagen.

Y finalmente, aquí algunos resultados visuales, esta es la imagen fuente que tomé con mi cámara:

Y aquí la salida a la izquierda y la máscara a la derecha:

el color azul significa values < 256 (B es el más bajo de 8 bits de color)

Utilizo mi propia clase de imagen para imágenes, por lo que algunos miembros son:

  • xs,ys tamaño de la imagen en píxeles
  • p[y][x].dd es un píxel en la posición (x,y) como tipo entero de 32 bits
  • clear(color) : borra toda la imagen
  • resize(xs,ys) : redimensiona la imagen a una nueva resolución