1

私は android ndk を初めて使用します。ruckus と IBM ブログによる画像処理の例を通して学習を始めました。画像のアウトラインを表示しようとしています。これが私が使用しているコードです

package com.example;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class OutlineClass extends Activity{
    private ImageView imageView;
      private Bitmap bitmap;
      private Button button;
      private Bitmap original;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.outline);

          original  = BitmapFactory.decodeResource(getResources(), R.drawable.wallace);
          bitmap    = BitmapFactory.decodeResource(getResources(), R.drawable.wallace);
          button    = (Button) findViewById(R.id.obutton);
          imageView = (ImageView) findViewById(R.id.oimageView2);
          button.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                  ShowOutline();

            }


        });

        }

        private void ShowOutline() {
            Bitmap oBitmap = original.copy(Bitmap.Config.ARGB_8888, true);
            Bitmap gBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

            showOutlineWithNative(oBitmap,gBitmap );
            imageView.setImageBitmap(gBitmap);

        }

        public native void showOutlineWithNative(Bitmap bmp1, Bitmap bmp2);
    }

そして、これは私が画像のアウトラインを表示するために使用しているCコードです

/*
To show outline
Pixel operation
*/
JNIEXPORT void JNICALL Java_com_example_OutlineClass_showOutlineWithNative(JNIEnv
* env, jobject  obj, jobject bitmapedges,jobject bitmapgray)
{
    AndroidBitmapInfo  infogray;
        void*              pixelsgray;
        AndroidBitmapInfo  infoedges;
        void*              pixelsedge;
        int                ret;
        int             y;
        int             x;
        int             sumX,sumY,sum;
        int             i,j;
        int                Gx[3][3];
        int                Gy[3][3];
        uint8_t            *graydata;
        uint8_t            *edgedata;


        LOGI("findEdges running");

        Gx[0][0] = -1;Gx[0][1] = 0;Gx[0][2] = 1;
        Gx[1][0] = -2;Gx[1][1] = 0;Gx[1][2] = 2;
        Gx[2][0] = -1;Gx[2][1] = 0;Gx[2][2] = 1;



        Gy[0][0] = 1;Gy[0][1] = 2;Gy[0][2] = 1;
        Gy[1][0] = 0;Gy[1][1] = 0;Gy[1][2] = 0;
        Gy[2][0] = -1;Gy[2][1] = -2;Gy[2][2] = -1;


        if ((ret = AndroidBitmap_getInfo(env, bitmapedges, &infogray)) < 0) {
            LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
            return;
        }


        if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infoedges)) < 0) {
            LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
            return;
        }




        if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
            LOGE("Bitmap format is not A_8 !");
            return;
        }


        if (infoedges.format != ANDROID_BITMAP_FORMAT_A_8) {
            LOGE("Bitmap format is not A_8 !");
            return;
        }



        if ((ret = AndroidBitmap_lockPixels(env, bitmapedges, &pixelsgray)) < 0) {
            LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        }

        if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsedge)) < 0) {
            LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        }


        // modify pixels with image processing algorithm


        LOGI("time to modify pixels....");

        graydata = (uint8_t *) pixelsgray;
        edgedata = (uint8_t *) pixelsedge;

        for (y=0;y<=infogray.height - 1;y++) {
            for (x=0;x<infogray.width -1;x++) {
                sumX = 0;
                sumY = 0;
                // check boundaries
                if (y==0 || y == infogray.height-1) {
                    sum = 0;
                } else if (x == 0 || x == infogray.width -1) {
                    sum = 0;
                } else {
                    // calc X gradient
                    for (i=-1;i<=1;i++) {
                        for (j=-1;j<=1;j++) {
                            sumX += (int) ( (*(graydata + x + i + (y + j)
    * infogray.stride)) * Gx[i+1][j+1]);
                        }
                    }

                    // calc Y gradient
                    for (i=-1;i<=1;i++) {
                        for (j=-1;j<=1;j++) {
                            sumY += (int) ( (*(graydata + x + i + (y + j)
    * infogray.stride)) * Gy[i+1][j+1]);
                        }
                    }

                    sum = abs(sumX) + abs(sumY);

                }

                if (sum>255) sum = 255;
                if (sum<0) sum = 0;

                *(edgedata + x + y*infogray.width) = 255 - (uint8_t) sum;



            }
        }

        AndroidBitmap_unlockPixels(env, bitmapgray);
        AndroidBitmap_unlockPixels(env, bitmapedges);

}

私が得ている結果は、変更のない同じ画像です...輪郭を検出するために使用されるsebelアルゴリズムは知っていますが、プログラムでエッジを検出する方法がわからないので、コードの何が問題なのか教えてください。

前もって感謝します

4

1 に答える 1

1

ここにはいくつかの問題があると思います。

まず、NDK コードで、入力ビットマップが Alpha_8 画像 (つまり、グレースケール画像) としてエンコードされていることを確認します。

if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
        LOGE("Bitmap format is not A_8 !");
        return;
}


if (infoedges.format != ANDROID_BITMAP_FORMAT_A_8) {
        LOGE("Bitmap format is not A_8 !");
        return;
}

ビットマップを作成するときは、Bitmap.Config.ARGB_8888copy関数に渡します。これにより、これらのチェックが失敗し、関数が画像を処理する前に返されると思われます。を使用してビットマップを作成する必要がありますcopy(Bitmap.Config.ALPHA_8, true)

また、プロセスの最後に間違ったビットマップを表示しようとしているようにも思えます。ビットマップをshowOutlineWithNative間違った順序で渡しています。表示するビットマップbitmapedgesはネイティブ関数の引数であり、ここでは入力のグレースケール イメージを表示しようとしています。

要約すると、正しいコードは次のShowOutlineようになります。

private void ShowOutline() {
        // grayscale version of the original bitmap:
        Bitmap gray = original.copy(Bitmap.Config.ALPHA_8, true);
        // receiver bitmap for the Sobel detector:
        Bitmap output = bitmap.copy(Bitmap.Config.ALPHA_8, true);

        showOutlineWithNative(output, gray);
        imageView.setImageBitmap(output);

}

進捗状況をお知らせください。

于 2012-10-29T14:13:16.780 に答える