[英]Efficiently convert a BufferedImage to an IplImage
我正在嘗試高效地將BufferedImage轉換為IplImage ...您能給我有關jni部分的任何提示嗎?
現在,我執行以下步驟:
我從BufferedImage獲取rgb,然后將它們發送到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),以檢查其外觀:
它分為許多特殊情況,但基本上,它遍歷所有像素以產生副本。 添加多個線程以在多個內核上並行循環也可以進一步提高性能...
從Java復制數據后,如果需要,您可以直接在本機代碼中使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.