簡體   English   中英

有效地將BufferedImage轉換為IplImage

[英]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),以檢查其外觀:

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

它分為許多特殊情況,但基本上,它遍歷所有像素以產生副本。 添加多個線程以在多個內核上並行循環也可以進一步提高性能...

從Java復制數據后,如果需要,您可以直接在本機代碼中使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM