As part of an application that I'm developing for Android I'd like to show the user an edge-detected version of an image they have taken (something similar to the example below).
To achieve this I've been looking at the Sobel operator and how to implement it in Java. However, many of the examples that I've found make use of objects and methods found in AWT (like this example) that isn't part of Android.
My question is then really, does Android provide any alternatives to the features of AWT that have been used in the above example? If we were to rewrite that example just using the libraries built into Android, how would we go about it?
The Sobel filter is used for edge detection. It works by calculating the gradient of image intensity at each pixel within the image. It finds the direction of the largest increase from light to dark and the rate of change in that direction.
Sobel edge detection method cannot produce smooth and thin edge compared to canny method. But same like other method, Sobel and Canny methods also very sensitive to the noise pixels. Sometime all the noisy image can not be filtered perfectly. Unremoved noisy pixels will effect the result of edge detection.
The main advantages of the Sobel operator are that it is simple and more time-efficient. However, the edges are rough. On the other hand, the Canny technique produces smoother edges due to the implementation of Non-maxima suppression and thresholding.
Also if you compare the result of sobel operator with Prewitt operator, you will find that sobel operator finds more edges or make edges more visible as compared to Prewitt Operator. This is because in sobel operator we have allotted more weight to the pixel intensities around the edges.
The question and answer are 3 years old... @reflog's solution works for a simple task like edge detection, but it's slow.
I use GPUImage on iOS for edge detection task. There is a equivalent library on Android: https://github.com/CyberAgent/android-gpuimage/tree/master
It's hardware accelerated so it's supposed to be very fast. Here is the sobel edge detection filter: https://github.com/CyberAgent/android-gpuimage/blob/master/library/src/jp/co/cyberagent/android/gpuimage/GPUImageSobelEdgeDetection.java
According the doc, you can simply do this:
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);
Another option is using RenderScript, which you can access each pixel in parallel and do whatever you want with it. I don't see any image processing library built with that yet.
since you don't have BufferedImage in Android, you can do all the basic operations yourself:
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
}
as you can see, this covers almost everything you need for porting that AWT example. (just change the 'convolvePixel' function)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With