2010-05-30 22 views
8

Como parte de una aplicación que estoy desarrollando para Android, me gustaría mostrarle al usuario una versión detectada en el borde de una imagen que han tomado (algo similar al ejemplo a continuación).Sobel Edge Detection en Android

alt text

Para lograr esto que he estado mirando el operador de Sobel y la forma de ponerla en práctica en Java. Sin embargo, muchos de los ejemplos que he encontrado hacen uso de objetos y métodos que se encuentran en AWT (like this example) que no es parte de Android.

Mi pregunta es, en realidad, ¿proporciona Android alguna alternativa a las características de AWT que se han utilizado en el ejemplo anterior? Si tuviéramos que reescribir ese ejemplo simplemente usando las bibliotecas integradas en Android, ¿cómo lo haríamos?

+0

Realmente no hay nada AWT específica sobre el código fuente se ha vinculado a: -/ – ivans

+0

¿No es una clase BufferedImage encontrado en AWT sin embargo? – greenie

Respuesta

3

ya que no tiene BufferedImage en Android, usted puede hacer todas las operaciones básicas a sí mismo:

Bitmap b = ... 
width = b.getWidth(); 
height = b.getHeight(); 
stride = b.getRowBytes(); 
for(int x=0;x<b.getWidth();x++) 
    for(int y=0;y<b.getHeight();y++) 
    { 
     int pixel = b.getPixel(x, y); 
     // you have the source pixel, now transform it and write to destination 
    } 

como se puede ver, esto cubre casi todo lo necesario para portar ese ejemplo AWT. (Acaba de cambiar la función 'convolvePixel')

+0

Esto es genial, pero Bitmap.getPixel() y Bitmap.setPixel() parecen ser muy lentos para mí cuando lo hago pixel por pixel. Pensé que sería mejor usar Bitmap.getPixels() al principio para copiar los valores del mapa de bits como enteros a un int []. ¿Cómo podría realizar la convolución en una matriz de valores RGB int en lugar de bitmap? – greenie

+0

Está en lo correcto, buscar toda la matriz es más rápido. Para realizar convoluciones en la matriz, simplemente itere usando el mismo tipo de bucles for y obtenga el valor de píxel utilizando canales separados R, G y B o componiendo un píxel desde una matriz RGB usando 'Color.rgb (r1, g1, b1) 'función. – reflog

5

La pregunta y la respuesta son 3 años de edad ... @ solución de reflog trabaja para una tarea simple, como la detección de bordes, pero es lenta .

Uso GPUImage en iOS para la tarea de detección de bordes. Hay una biblioteca equivalente en Android: https://github.com/CyberAgent/android-gpuimage/tree/master

Se acelera el hardware por lo que se supone que es muy rápido. Aquí está el filtro de detección de bordes Sobel: https://github.com/CyberAgent/android-gpuimage/blob/master/library/src/jp/co/cyberagent/android/gpuimage/GPUImageSobelEdgeDetection.java

Según el documento, puede simplemente hacer esto:

Uri imageUri = ...; 
mGPUImage = new GPUImage(this); 
mGPUImage.setGLSurfaceView((GLSurfaceView) findViewById(R.id.surfaceView)); 
mGPUImage.setImage(imageUri); // this loads image on the current thread, should be run in a thread 
mGPUImage.setFilter(new GPUImageSobelEdgeDetection()); 

// Later when image should be saved saved: 
mGPUImage.saveToPictures("GPUImage", "ImageWithFilter.jpg", null); 

Otra opción es usar RenderScript, la cual se puede acceder a cada píxel en paralelo y hacer lo que quiera con eso. Todavía no veo ninguna biblioteca de procesamiento de imágenes construida con eso.

0

Otra opción es usar OpenCV, que tiene una gran implementación para Android.

El método Imgproc.Sobel() toma una imagen en forma de tipo 'Mat', que se carga fácilmente desde un recurso o mapa de bits. La entrada Mat debe ser una imagen en escala de grises, que también se puede crear con opencv. Mat src = Highgui.imread(getClass().getResource( "/SomeGrayScaleImage.jpg").getPath());

A continuación, ejecute el detector de borde sobel en él, ahorrando resultados en un nuevo Mat. Si desea mantener la misma profundidad de imagen, entonces esto lo hará ... Mat dst; int ddepth = -1; // destination depth. -1 maintains existing depth from source int dx = 1; int dy = 1; Imgproc.Sobel(src, dst, ddepth, dx, dy);

Parte de la documentación de referencia es aquí: http://docs.opencv.org/java/org/opencv/imgproc/Imgproc.html#Sobel(org.opencv.core.Mat,%20org.opencv.core.Mat,%20int,%20int,%20int)

Para una acumulación Gradle en Android de estudio, se puede tirar en la biblioteca OpenCV integrado para Java desde diferentes lugares, pero también el anfitrión de una construcción reciente. En su archivo build.gradle, puede agregar una dependencia como tal ... De lo contrario, es un poco complicado. dependencies { compile 'com.iparse.android:opencv:2.4.8' } Si utilizas Eclipse, se puede comprobar el sitio web OPENCV para obtener más información sobre el uso de OPENCV en Android: http://opencv.org/platforms/android.html

Cuestiones relacionadas