gpt4 book ai didi

java - 高效地将 BufferedImage 转换为 IplImage

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:33:32 27 4
gpt4 key购买 nike

我正在尝试有效地将 BufferedImage 转换为 IplImage...您能给我一些关于 jni 部分的提示吗?

现在我执行以下步骤:

我从 BufferedImage 获取 rgbs 并将它们发送到我执行以下操作的 jni 代码:

IplImage* getIplImageFromIntArray(JNIEnv* env, jintArray array_data,
jint width, jint height) {
int *pixels = env->GetIntArrayElements(array_data, 0);
if (pixels == 0) {
return 0;
}
IplImage *image = loadPixels(pixels, width, height);
env->ReleaseIntArrayElements(array_data, pixels, 0);
if (image == 0) {
return 0;
}
return image;}};

IplImage* loadPixels(int* pixels, int width, int height) {
int x, y;
IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
unsigned char* base = (unsigned char*) (img->imageData);
unsigned char* ptr;
for (y = 0; y < height; y++) {
ptr = base + y * img->widthStep;
for (x = 0; x < width; x++) {
// blue
ptr[3 * x] = pixels[x + y * width] & 0xFF;
// green
ptr[3 * x + 1] = pixels[x + y * width] >> 8 & 0xFF;
// blue
ptr[3 * x + 2] = pixels[x + y * width] >> 16 & 0xFF;
}
}
return img;}

但这真的很慢......谢谢你的帮助!

最佳答案

JavaCV :

IplImage.createFrom(aBufferedImage)

编辑:您的代码运行缓慢有几个原因。 BufferedImage 类是在 NIO 缓冲区流行之前设计的,因此它使用标准 Java 数组作为后备缓冲区。不能(安全地)直接从 JNI 访问 Java 数组,因此默认情况下,通过调用 GetIntArrayElements() 的方式,临时分配内存并将数组数据复制到新分配的内存中,而 ReleaseIntArrayElements() 也会复制回数据进入数组,并释放临时分配的内存。并且您还在每次调用时分配一个新的 IplImage,并在将所有内容从该临时缓冲区复制到临时 IplImage 时制作另一个拷贝。简而言之,您的代码在堆上分配了两次内存并复制了三次数据。实现预期效果的推荐方法是使用直接 NIO 缓冲区从 Java 内部仅复制一次数据。您可以通过查看 JavaCV 源代码的相关部分(即 IplImage.copyFrom(BufferedImage))来检查它的外观:

http://code.google.com/p/javacv/source/browse/trunk/javacv/src/com/googlecode/javacv/cpp/opencv_core.java#881

它分支成许多特殊情况,但基本上它遍历所有像素以生成拷贝。添加几个线程以在多个内核上并行循环也可以进一步提高性能...

从 Java 复制数据后,如果需要,您可以直接从 native 代码使用它。

关于java - 高效地将 BufferedImage 转换为 IplImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8904285/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com