我正在Android中构建一个图像处理项目。我通过相机捕获位图图片,并通过JNI将其提供给opencv C ++函数。
首先,我使用保存的位图图片(PNG格式)测试我的opencv c ++函数,并且它成功了。
// in Android, save bitmap
Bitmap bmp = YUV_420_888_toRGB(img,img.getWidth(),img.getHeight());
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Log.e(TAG,"saved successfully.)");
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
// in opencv c++ function
Mat im = imread("/Users/Jun/Downloads/20170227/P9/1488167433596_frame.PNG");
// processing im
然后我将每个捕获的位图图片提供给相同的opencv c ++函数。但是,检测结果完全不同。我认为通过JNI将Java中的位图转换为C ++中的opencv mat时必定存在一些错误。请在下面找到转换代码:
//Java side:
public static int[] detector(Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int []pixels = new int[w*h];
bitmap.getPixels(pixels,0,w,0,0,w,h);
return detect(pixels,w,h);
}
private static native int[] detect(int pixels[],int w,int h);
// c++ side:
JNIEXPORT jintArray JNICALL Java_com_example_jun_helloworld_JNIUtils_detect(JNIEnv *env, jclass cls, jintArray buf, jint w, jint h) {
jint* cbuf = env->GetIntArrayElements(buf, false);
if (cbuf == NULL) {
return NULL;
}
Mat im(h, w, CV_8UC4, (unsigned char *) cbuf);
// processing im
两个" im" s应该是不同的。有人能告诉我转换中的错误吗?感谢。
答案 0 :(得分:1)
在代码中,将int指针转换为char指针。因此,您将更改代码处理数据的方式。
看看这里:
#include <stdio.h>
int main() {
// what you have in the code is array of ints
int iarray[5] = {1, 2, 3, 4, 5};
int *iarray_ptr = iarray;
// and you cast int pointer to char pointer
char *carray_ptr = (char *) iarray_ptr;
// so, you simply skip some values because of
// pointer aritmetics; your data are shifted
for(int i=0;i<5;i++) {
printf("int: %p, char %p\n", iarray_ptr + i, carray_ptr + i);
}
// you can always do something like this
char carray2[5];
for(int p=0;p<5;p++) {
// you can loose precision here!
carray2[p] = (char) iarray[p];
}
// and then, you can simply pass &carray2 to
// to your code
}
如果你运行代码,你可以清楚地看到指针算术的区别:
./pointer
int: 0x7fff51d859f0, char 0x7fff51d859f0
int: 0x7fff51d859f4, char 0x7fff51d859f1
int: 0x7fff51d859f8, char 0x7fff51d859f2
int: 0x7fff51d859fc, char 0x7fff51d859f3
int: 0x7fff51d85a00, char 0x7fff51d859f4
在转换为char *之后,您只需“分散”您的数据。