Android 中的 Sobel 边缘检测

发布于 2024-09-03 11:04:37 字数 483 浏览 18 评论 0原文

作为我为 Android 开发的应用程序的一部分,我想向用户展示他们拍摄的图像的边缘检测版本(类似于下面的示例)。

替代文本

为了实现这一目标,我一直在研究 Sobel 运算符以及如何在 Java 中实现它。但是,我发现的许多示例都使用 AWT 中的对象和方法 (就像这个例子),它不是Android的一部分。

我的问题是,Android 是否提供了上述示例中使用的 AWT 功能的替代方案?如果我们仅使用 Android 内置的库重写该示例,我们将如何进行?

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

alt text

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

二智少女猫性小仙女 2024-09-10 11:04:37

这个问题和答案已有 3 年历史了……@reflog 的解决方案适用于边缘检测等简单任务,但速度很慢。

我在 iOS 上使用 GPUImage 进行边缘检测任务。 Android 上有一个等效的库:
https://github.com/Cyber​​Agent/android-gpuimage/tree/master

它是硬件加速的,所以它应该非常快。这是索贝尔边缘检测滤波器:
https:/ /github.com/Cyber​​Agent/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,您可以并行访问每个像素并用它做任何您想做的事情。我还没有看到任何用它构建的图像处理库。

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.

卸妝后依然美 2024-09-10 11:04:37

由于 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”函数)

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)

活雷疯 2024-09-10 11:04:37

另一种选择是使用 OpenCV,它在 Android 上有很好的实现。

Imgproc.Sobel() 方法采用“Mat”类型形式的图像,可以轻松地从资源或位图中加载该图像。输入Mat应该是灰度图像,也可以使用opencv创建。
<代码>
Mat src = Highgui.imread(getClass().getResource(
"/SomeGrayScaleImage.jpg").getPath());

然后在其上运行 sobel 边缘检测器,将结果保存在新的 Mat 中。如果你想保持相同的图像深度,那么这就可以了......
<代码>
垫 dst;
int d深度 = -1; // 目标深度。 -1 保持距源的现有深度
int dx = 1;
整数dy=1;
Imgproc.Sobel(src, dst, d深度, dx, dy);
一些参考

文档在这里:
http://docs.opencv.org/java/org/opencv/imgproc/Imgproc.html#Sobel(org.opencv.core.Mat,%20org.opencv.core .Mat,%20int,%20int,%20int)

对于 Android Studio 中的 gradle 构建,您可以从不同的地方引入为 Java 构建的 opencv 库,但我还托管了一个最近的构建。在您的 build.gradle 文件中,您可以像这样添加依赖项...否则,这有点棘手。
<代码>
依赖项{
编译'com.iparse.android:opencv:2.4.8'
}

如果您使用的是 Eclipse,可以查看 Opencv 网站,了解有关在 Android 上使用 Opencv 的详细信息:http:// opencv.org/platforms/android.html

Another option is to use OpenCV, which has a great implementation for Android.

The Imgproc.Sobel() method takes an image in the form of a 'Mat' type, which is easily loaded from a resource or bitmap. The input Mat should be a grayscale image, which can also be created with opencv.

Mat src = Highgui.imread(getClass().getResource(
"/SomeGrayScaleImage.jpg").getPath());

Then run sobel edge detector on it, saving results in a new Mat. If you want to keep the same image depth, then this will do it...

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

Some reference documentation is here:
http://docs.opencv.org/java/org/opencv/imgproc/Imgproc.html#Sobel(org.opencv.core.Mat,%20org.opencv.core.Mat,%20int,%20int,%20int)

For a gradle build in Android Studio, you can pull in the opencv library built for Java from different places, but I also host a recent build. In your build.gradle file, you can add a dependency like so... Otherwise, it's a little tricky.

dependencies {
compile 'com.iparse.android:opencv:2.4.8'
}

If you're using Eclipse, you can check the Opencv website for details on using Opencv on Android: http://opencv.org/platforms/android.html

童话 2024-09-10 11:04:37

在此处检查 Java 实现:

http:// /code.google.com/p/kanzi/source/browse/java/src/kanzi/filter/SobelFilter.java

不依赖于 Swing/AWT 或任何其他库。它直接对图像像素进行操作并且速度很快。

结果可以在此处查看(向下滚动):

http://code.google.com/ p/kanzi/wiki/概述

Check a java implementation here:

http://code.google.com/p/kanzi/source/browse/java/src/kanzi/filter/SobelFilter.java

There is no dependency on Swing/AWT or any other library. It operates directly on the image pixels and it is fast.

The results can be seen here (scroll down):

http://code.google.com/p/kanzi/wiki/Overview

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文