作为我正在为 Android 开发的应用程序的一部分,我想向用户展示他们拍摄的图像的边缘检测版本(类似于下面的示例)。
为了实现这一点,我一直在研究 Sobel 运算符以及如何在 Java 中实现它。但是,我发现的许多示例都使用了不属于 Android的 AWT 中的对象和方法(例如这个示例)。
那么我的问题是,Android 是否提供了上述示例中使用的 AWT 功能的替代方案?如果我们仅使用 Android 内置的库来重写该示例,我们将如何进行呢?
作为我正在为 Android 开发的应用程序的一部分,我想向用户展示他们拍摄的图像的边缘检测版本(类似于下面的示例)。
为了实现这一点,我一直在研究 Sobel 运算符以及如何在 Java 中实现它。但是,我发现的许多示例都使用了不属于 Android的 AWT 中的对象和方法(例如这个示例)。
那么我的问题是,Android 是否提供了上述示例中使用的 AWT 功能的替代方案?如果我们仅使用 Android 内置的库来重写该示例,我们将如何进行呢?
问题和答案已有 3 年历史了……@reflog 的解决方案适用于边缘检测等简单任务,但速度很慢。
我在 iOS 上使用 GPUImage 进行边缘检测任务。Android上有一个等效的库: https ://github.com/CyberAgent/android-gpuimage/tree/master
它是硬件加速的,所以它应该非常快。这是sobel边缘检测过滤器: https ://github.com/CyberAgent/android-gpuimage/blob/master/library/src/jp/co/cyberagent/android/gpuimage/GPUImageSobelEdgeDetection.java
根据文档,您可以简单地执行以下操作:
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);
另一种选择是使用 RenderScript,您可以并行访问每个像素并使用它做任何您想做的事情。我还没有看到任何用它构建的图像处理库。
由于你在Android中没有BufferedImage,你可以自己做所有的基本操作:
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
}
如您所见,这几乎涵盖了移植该 AWT 示例所需的所有内容。(只需更改“convolvePixel”功能)
另一种选择是使用 OpenCV,它对 Android 有很好的实现。
该Imgproc.Sobel()
方法以“Mat”类型的形式获取图像,该图像很容易从资源或位图中加载。输入的Mat应该是灰度图,也可以用opencv创建。
Mat src = Highgui.imread(getClass().getResource(
"/SomeGrayScaleImage.jpg").getPath());
然后在其上运行 sobel 边缘检测器,将结果保存在新的 Mat 中。如果你想保持相同的图像深度,那么这将做到......
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);
对于 Android Studio 中的 gradle 构建,您可以从不同的地方拉入为 Java 构建的 opencv 库,但我也托管了一个最近的构建。在您的 build.gradle 文件中,您可以像这样添加依赖项......否则,这有点棘手。
dependencies {
compile 'com.iparse.android:opencv:2.4.8'
}
如果您使用的是 Eclipse,您可以查看 Opencv 网站了解在 Android 上使用 Opencv 的详细信息:http: //opencv.org/platforms/android.html
在此处检查 java 实现:
http://code.google.com/p/kanzi/source/browse/java/src/kanzi/filter/SobelFilter.java
不依赖于 Swing/AWT 或任何其他库。它直接对图像像素进行操作,速度很快。
结果可以在这里看到(向下滚动):