2012-01-18 4 views
2

BufferedImage를 IplImage로 효율적으로 변환하려고합니다 ... jni 부분에 대해 어떤 힌트를 주시겠습니까?BufferedImage를 IplImage로 효율적으로 변환하십시오.

나는 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

답변

1

:

IplImage.createFrom(aBufferedImage) 

편집 : 코드가 느린 이유는 몇 가지 이유가 있습니다. BufferedImage 클래스는 NIO 버퍼가 유행하기 전에 설계되었으므로 표준 Java 배열을 백업 버퍼로 사용합니다. Java 배열은 JNI에서 직접 (안전하게) 액세스 할 수 없으므로 기본적으로 GetIntArrayElements()를 호출하는 방식으로 메모리가 임시로 할당되고 배열 데이터가 새 할당 된 메모리로 복사되는 반면 ReleaseIntArrayElements()는 데이터를 다시 복사합니다 배열에 저장하고 임시 할당 메모리를 해제합니다. 또한 모든 호출에 새로운 IplImage를 할당하고 임시 버퍼에서 임시 IplImage로 모든 내용을 복사 할 때 다른 복사본을 만듭니다. 요컨대, 코드는 힙에 메모리를 두 번 할당하고 데이터를 세 번 복사합니다. 원하는 효과를 얻으려면 직접 NIO 버퍼를 사용하여 Java 내부에서 한 번만 데이터를 복사하는 것이 좋습니다.

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

이 특별한 경우를 많이로

이 가지 하지만, 기본적으로는 이상 루프 : 당신은 JavaCV의 소스 코드, 즉 IplImage.copyFrom (BufferedImage의)의 관련 부분에 어깨를 나란히하여이의 모습을 확인하실 수 있습니다 모든 픽셀이 사본을 생성합니다. 두 개의 스레드를 추가하여 여러 코어에서 병렬로 루프를 수행하면 성능을 더욱 향상시킬 수 있습니다. ...

Java에서 데이터를 복사 한 후 원하는 경우 원시 코드에서 직접 사용할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 그 이미지를 일치 목적으로 사용한다고 말하지 않았습니다. 즉, find_obj.cpp 데모와 서핑을 사용하여 두 이미지를 비교합니다. JavaCV를 보았지만 ObjectFinder가 find_obj.cpp와 같은 방식으로 두 이미지와 일치하는지 확신 할 수 없습니다. 당신이 저를 도울 수 있다면 기쁘 겠지만, 아마도 새로운 질문을 만들어야 할 것입니다 ... 고맙습니다. – user1148222

+0

좋아요, JavaCV가 어떻게 작동하는지 더 자세히 설명 할 편집을하겠습니다 ... –

+0

안녕하세요 사무엘, 자세한 답변을 주셔서 감사합니다 ... 제가 묻는 것을 설명합니다. – user1148222

관련 문제