Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用一个像素的Sobel矩阵_Android_Image Processing - Fatal编程技术网

Android 如何使用一个像素的Sobel矩阵

Android 如何使用一个像素的Sobel矩阵,android,image-processing,Android,Image Processing,我想在我的android应用程序中使用Sobel操作符。但我不明白如何使用一个像素 int sobel_x[][] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; int sobel_y[][] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; Bitmap source = ImageHelper.GetBitmapGromUri(Path); int w =

我想在我的android应用程序中使用
Sobel
操作符。但我不明白如何使用一个像素

int sobel_x[][] = {{-1, 0, 1},
        {-2, 0, 2},
        {-1, 0, 1}};
int sobel_y[][] = {{-1, -2, -1},
        {0, 0, 0},
        {1, 2, 1}};
Bitmap source = ImageHelper.GetBitmapGromUri(Path);
    int w = source.getWidth();
    int h = source.getHeight();
    int[] pixels;
    pixels = new int[h * w];
    source.getPixels(pixels, 0, w, 1, 1, w - 1, h - 1);
    for(int i = 0;i < pixels.length;i++){
          ...
    }
intsobel_x[][]={{-1,0,1},
{-2, 0, 2},
{-1, 0, 1}};
int sobel_y[][]={{-1,-2,-1},
{0, 0, 0},
{1, 2, 1}};
位图源=ImageHelper.GetBitmapGromUri(路径);
int w=source.getWidth();
int h=source.getHeight();
int[]像素;
像素=新整数[h*w];
getPixels(像素,0,w,1,1,w-1,h-1);
对于(int i=0;i

我尝试使用
get/setPixel
。但是速度非常慢。

单个像素访问绝对不是正确的方式

我假设您已经将源转换为灰度,所以它本质上是一个字节数组。我建议您使用类似以下的方法来提取数据:

int w = source.getWidth();
int h = source.getHeight();
ByteBuffer buffer = ByteBuffer.allocate( w * h );
source.copyPixelsToBuffer( buffer );
final byte[] bitmapData = buffer.array()
这将为您提供源数据。现在,您可以对其应用Sobel过滤器。请注意,您希望将生成的输出字节写入一个新的
byte
数组,然后将其转换回图像

byte[] output = new byte[ w * h ];
for( int y=1; y<h-1; y++ ) {
    for( int x=1; x<w-1; x++ ) {
        int idx = y * w + x;

        // Apply Sobel filter
        byte sx = (byte) ((-1 * bitmapData[idx-w-1]) + ( 1 * bitmapData[idx-w+1] ) + (-2 * bitmapData[idx-1]) + ( 2 * bitmapData[idx+1] ) + (-1 * bitmapData[idx+w-1]) + ( 1 * bitmapData[idx+w+1] ) );

        output[idx] = sx;
    }
}
byte[]输出=新字节[w*h];

对于(inty=1;y好消息和坏消息。以下方法有效,但

由于某种特殊的原因,Android不允许您创建8位灰度图像。这意味着您必须创建ARGB_8888格式的灰度图像。这可能是您以前版本中出现的问题,我们将数据读取为字节,而不是字节

下面的代码可以正常工作,我只在模拟器上运行过你的图像,速度慢得离谱(11秒)。当然,你的图像很大,但我猜,这仍然是一种缓慢的方式

我强烈建议考虑使用OpenCV Java库,因为它们与Android位图类不同,既快速又节省内存

public class Sobel {
    private static Bitmap toGreyScale( Bitmap source ) {
        Bitmap greyScaleBitmap = Bitmap.createBitmap(
                source.getWidth(), source.getHeight(),
                Bitmap.Config.ARGB_8888);

        Canvas c = new Canvas(greyScaleBitmap);
        Paint p = new Paint();
        ColorMatrix cm = new ColorMatrix();

        cm.setSaturation(0);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm);
        p.setColorFilter(filter);
        c.drawBitmap(source, 0, 0, p);
        return greyScaleBitmap;
    }

    public static void doSobel( Bitmap source) {

        Bitmap grey = toGreyScale(source);

        int w = grey.getWidth();
        int h = grey.getHeight();
        // Allocate 4 times as much data as is necessary because Android.
        int sz = w * h;

        IntBuffer buffer = IntBuffer.allocate( sz );
        grey.copyPixelsToBuffer( buffer );
        final int[] bitmapData = buffer.array();

        int[] output = new int[ w * h ];
        for( int y=1; y<h-1; y++ ) {
            for( int x=1; x<w-1; x++ ) {
                int idx = (y * w + x );

                // Apply Sobel filter
                int tl = (bitmapData[idx - w - 1]) & 0xFF;
                int tr = (bitmapData[idx - w + 1]) & 0xFF;
                int l = (bitmapData[idx - 1]) & 0xFF;
                int r = (bitmapData[idx + 1]) & 0xFF;
                int bl = (bitmapData[idx + w - 1]) & 0xFF;
                int br = (bitmapData[idx + w + 1]) & 0xFF;

                int sx = (int) ( tr - tl + 2 * ( r - l ) + br - bl );
                sx = sx & 0xFF;

                // Put back into ARG and B bytes
                output[toIdx] = (sx << 24) | ( sx << 16) | (sx << 8) | sx;
            }
        }

        source.copyPixelsFromBuffer( IntBuffer.wrap(output));
    }
}
公共类Sobel{
专用静态位图toGreyScale(位图源){
位图灰度缩放位图=位图.createBitmap(
source.getWidth(),source.getHeight(),
位图.Config.ARGB_8888);
画布c=新画布(灰色缩放位图);
油漆p=新油漆();
ColorMatrix cm=新的ColorMatrix();
cm.设定饱和度(0);
ColorMatrixColorFilter过滤器=新的ColorMatrixColorFilter(厘米);
p、 设置彩色滤光片(滤光片);
c、 drawBitmap(源,0,0,p);
返回灰度刻度位图;
}
公共静态void doSobel(位图源){
位图灰色=toGreyScale(源);
int w=grey.getWidth();
inth=grey.getHeight();
//分配4倍于所需的数据,因为Android。
int sz=w*h;
IntBuffer=IntBuffer.allocate(sz);
灰色。copyPixelsToBuffer(缓冲区);
final int[]bitmapData=buffer.array();
int[]输出=新的int[w*h];

对于(int y=1;y
int[]输出=新字节[w*h];
-错误。如果使用int数组。如何设置为结果?
result.setPixels(输出,0,w,h);
??如果字节数组-
结果。copyPixelsFromBuffer(输出);
@NickDevil将输出设置为int[],并使用
Bitmap.createBitmap(int[]颜色、整数偏移量、整数步长、整数宽度、整数高度、位图.Config)或类似设置。或者将输出设为字节[],并使用
copyPixelsFromBuffer()
它工作正常,但结果不好,@NickDevil您需要确保位图类型与您使用的源数据相同。例如,为您使用的数据类型适当设置配置、跨距、偏移量等。位图res=Bitmap.createBitmap(输出,0,w,w,h,source.getConfig())我用这个。是的。它工作。在我的手机里-0秒。但是
toIdx
==
idx
?结果不好:(