Android — изображение обрабатывается, чтобы показать контур с помощью NDK

Я новичок в 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 algorithmLOGI("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, используемый для определения контура, но я не понимаю, насколько программно он обнаруживает края, пожалуйста, дайте мне знать, что не так в коде.

заранее спасибо

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_8888 к copy функция. Я подозреваю, что это приводит к сбою этих проверок, и поэтому функция возвращается до обработки изображения. Вы должны создавать свои растровые изображения, используя 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);

}

Держите меня в курсе о ваших успехах!

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector