2014-03-28 1 views
1

JNI의 CV : Mat를 Java 바이트 []로 보내므로 BitmapFactory.decode()로 성공적으로 디코딩 될 수 있습니다. 자바 측에서 처음으로 안드로이드 비트 맵의 ​​데이터를 사용하여 만든 byte [] 배열을 가져 오면 C++ OpenCV 함수에서 성공적으로 사용할 수 있습니다. 나는 byte []로부터 Mat를 빌드하고 매트에 cv :: imdecode를 호출하여이 작업을 수행합니다.Android OpenCV에서 보내는 바이트 []에 cv :: imencode가 필요합니까?

안드로이드로 돌아가 BitmapFactory를 사용하여 바이트 배열을 Android Bitmap으로 디코딩하려고하면 문제가 발생합니다. 해독에 문제가 있음을 나타내는 null을 반환합니다. JNI에서 돌아 오기 전에 작업을 잘못 수행하고 있습니까? 입력 바이트 []에 cv :: imdecode를 사용해야하므로 cv :: imencode를 사용해야합니까?

모든 도움을 주셨습니다. 코드 샘플은 JNI의 매트에서 필요한 데이터를 변환하는 위치입니다.

참고 저는 Apache Android_Bitmap 기능을 사용하고 있지만 바이트 배열을 사용하는 것은 현재 작업하고있는 요구 사항입니다.

//inData is a char* pointer that is set to a char* cast of the jbyte* pointer for the 
    // incoming Array. 

    cv::Mat inMat = cv::Mat(rows, columns, CV_8UC4, inData); 
    cv::Mat decodedMat = cv::imdecode(inMat, 1); 

    //convertImage is a function that changes the color space from BGR to Gray and then Gray to 
    //RGB. 

    convertImage(decodedMat, decodedMat); 

    cv::cvtColor(decodedMat, decodedMat, CV_RGB2RGBA); 
    jbyteArray jDataArray = env->NewByteArray(pixelDataLength); 
    env->SetByteArrayRegion(jDataArray,0,pixelDataLength,(jbyte*)decodedMat.data); 
    env->SetObjectField(in,dataArray,jDataArray); 
    env->ReleaseByteArrayElements(pixelData, bytePointerForIn, 0); 

답변

0

해결! Bitmap.compress()를 사용하여 바이트로 보내는 원래 버전의 조합이었고 copyPixelsFromBuffer를 사용하여 반환 된 픽셀에 대해 조합했습니다. 버디가 나를 올바른 방향으로 가리켜 주셔서 감사합니다.

Android: 

//input was the original bitmap that was used to construct the byte[] array. I then used input.compress() in JPEG format to a Byte. Very important for it to be compressed in a format that will be recognized in cv::imdecode. 

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
       input.compress(CompressFormat.JPEG, 100, bos); 
       data1.pixelData = bos.toByteArray(); 
... 

    //Reconstruction after JNI call 
    ByteBuffer buffer2 = ByteBuffer.wrap(data1.pixelData); 
    Bitmap returnFromConvert = Bitmap.createBitmap(input.getWidth(),  
    input.getHeight(),Bitmap.Config.ARGB_8888); 
    returnFromConvert.copyPixelsFromBuffer(buffer2); 
1

BitmapFactory는 제공되는 데이터가 알려진 파일 형식이어야하지만 원시 픽셀을 전달할 것으로 기대합니다. cv :: imencode를 호출하면 효과를 낼 수 있지만 원시 픽셀 데이터에서 이미지를로드하는 데 더 자연스러운 해결책은 원본 Java Bitmap 객체를 변경할 수있게 만든 다음 copyPixelsToBuffer 및 copyPixelsFromBuffer 메서드를 호출하여 그 오브젝트의 픽셀 데이터

+0

최대한 빨리 시도하고 다시 연락 드리겠습니다. 친구 버디에게 감사드립니다! 응답을 받으면 크레디트를 받게됩니다. – blkhatpersian

+0

좋은 소식과 나쁜 소식 친구. copyPixelstoBuffer 및 copyPixelsFromBuffer를 byte []로 전송하고 매트로 다시 구성한 다음 Android로 다시 보낼 수있는 곳에 성공적으로 구현할 수있었습니다. 문제는 cv :: imdecode를 사용하여 바이트 []에서 빌드 한 매트에서 색상 공간 조작을 실제로 수행해야 할 때입니다. 자세한 내용은 여기에 있습니다 : http://answers.opencv.org/question/31751/android-jni-bitmap-byte-returning-one-channel-mat/ – blkhatpersian

관련 문제