2010-05-30 9 views
8

Als Teil einer Anwendung, die ich für Android entwickle, möchte ich dem Benutzer eine Rand erkannt Version eines Bildes zeigen, die sie gemacht haben (etwas ähnliches wie im Beispiel unten).Sobel Edge Detection in Android

alt text

Um dies zu erreichen, ich habe an dem Sobel-Operator suche und wie es in Java zu implementieren. Viele der Beispiele, die ich gefunden habe, verwenden jedoch Objekte und Methoden in AWT (like this example), die nicht Teil von Android sind.

Meine Frage ist dann wirklich, bietet Android Alternativen zu den Funktionen von AWT, die im obigen Beispiel verwendet wurden? Wenn wir dieses Beispiel nur mit den in Android integrierten Bibliotheken umschreiben würden, wie würden wir dann vorgehen?

+0

Es gibt wirklich nichts AWT spezifisch über den Quellcode Sie im Zusammenhang mit: -/ – ivans

+0

Ist das nicht eine Klasse BufferedImage in AWT obwohl gefunden? – greenie

Antwort

3

da Sie BufferedImage in Android nicht, können Sie sich über alle grundlegenden Operationen ausführen:

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 
    } 

wie Sie sehen können, das man fast alles abdeckt müssen, dass AWT Beispiel für die Portierung. (Ändern Sie einfach den 'convolvePixel' -Funktion)

+0

Das ist großartig, aber Bitmap.getPixel() und Bitmap.setPixel() scheinen für mich sehr langsam zu sein, wenn ich es Pixel für Pixel mache. Ich dachte, es wäre besser, Bitmap.getPixels() am Anfang zu verwenden, um die Werte der Bitmap als Ganzzahlen in ein int [] zu kopieren. Wie würde ich Faltung an einem Array von RGB-int-Werten anstatt an der Bitmap durchführen? – greenie

+0

Sie sind richtig, das Holen des gesamten Arrays ist schneller. Um Faltungen am Array durchzuführen, iterieren Sie einfach mit derselben Art von for-Schleifen und erhalten Pixelwerte, indem Sie entweder separate R-, G- und B-Kanäle verwenden oder ein Pixel aus dem RGB-Array mit 'Color.rgb (r1, g1, b1) 'Funktion. – reflog

5

Die Frage und Antwort sind die 3 Jahre alt ... @ reflog Lösung arbeitet für eine einfache Aufgabe, wie Kantenerkennung, aber es ist langsam .

Ich verwende GPUImage auf iOS für Kantenerkennung Aufgabe. Es gibt eine entsprechende Bibliothek auf Android: https://github.com/CyberAgent/android-gpuimage/tree/master

Es ist hardwarebeschleunigt, so dass es sehr schnell sein soll. Hier ist die Sobel-Kantenerkennungsfilter: https://github.com/CyberAgent/android-gpuimage/blob/master/library/src/jp/co/cyberagent/android/gpuimage/GPUImageSobelEdgeDetection.java

die doc Laut, können Sie einfach tun:

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); 

Eine weitere Option render verwendet, die Sie jedes Pixel parallel zugreifen können und tun, was Sie wollen damit. Ich sehe damit noch keine Bildverarbeitungsbibliothek.

0

Eine weitere Option ist die Verwendung von OpenCV, die eine großartige Implementierung für Android hat.

Die Methode Imgproc.Sobel() nimmt ein Bild in Form eines "Mat" -Typs, der einfach aus einer Ressource oder Bitmap geladen werden kann. Die Eingabe Mat sollte ein Graustufenbild sein, das auch mit opencv erstellt werden kann. Mat src = Highgui.imread(getClass().getResource( "/SomeGrayScaleImage.jpg").getPath());

Dann führen Sie Sobel Kantendetektor auf, Speichern von Ergebnissen in einem neuen Mat. Wenn Sie die gleiche Bildtiefe beibehalten möchten, dann wird dies ... 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);

Ein Teil der Dokumentation Referenz hier: http://docs.opencv.org/java/org/opencv/imgproc/Imgproc.html#Sobel(org.opencv.core.Mat,%20org.opencv.core.Mat,%20int,%20int,%20int)

Für eine gradle Build in Android Studio können Sie in der opencv Bibliothek für Java aus verschiedenen Orten gebaut ziehen, aber ich auch Gastgeber eine aktuelle Build. In Ihrer build.gradle-Datei können Sie eine Abhängigkeit wie folgt hinzufügen ... Ansonsten ist es ein wenig schwierig. dependencies { compile 'com.iparse.android:opencv:2.4.8' } Wenn Sie Eclipse-verwenden, können Sie die OpenCV Website für Details überprüfen mit OpenCV auf Android: http://opencv.org/platforms/android.html