首页 文章

Android中的Sobel边缘检测

提问于
浏览
8

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

alt text

为了达到这个目的,我发现使用了不属于Android的AWT(like this example)中的对象和方法 .

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

4 回答

  • 0

    由于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'功能)

  • 3

    问题和答案是3年...... @ reflog的解决方案适用于像边缘检测这样的简单任务,但速度很慢 .

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

    它's hardware accelerated so it'应该非常快 . 这是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,您可以并行访问每个像素并随意执行任何操作 . 我没有看到任何使用它构建的图像处理库 .

  • 0

    在这里检查java实现:

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

    不依赖于Swing / AWT或任何其他库 . 它直接在图像像素上运行,速度很快 .

    结果可以在这里看到(向下滚动):

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

  • 6

    另一种选择是使用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);

    一些参考文档在这里: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文件中,你可以像这样添加一个依赖...否则,它有点棘手 . dependencies { compile 'com.iparse.android:opencv:2.4.8' } 如果你正在使用Eclipse,你可以查看Opencv网站,了解在Android上使用Opencv的详细信息:http://opencv.org/platforms/android.html

相关问题