cv :: imencode требуется для исходящего байта [] в Android OpenCV?

Я боролся с отправкой обратно CV: Mat в JNI как байт Java [], чтобы он мог быть успешно декодирован с помощью BitmapFactory.decode (). Когда я впервые привожу свой массив byte [] (созданный с использованием данных из растрового изображения Android) со стороны Java, я могу успешно использовать его в функциях C ++ OpenCV. Я делаю это, собирая Mat из байта [] и вызывая cv :: imdecode для Mat.

Проблема возникает, когда я возвращаюсь обратно в Android и пытаюсь использовать BitmapFactory для декодирования байтового массива в растровое изображение Android. Возвращает ноль, что указывает на проблему с декодированием. Я неправильно выполняю операции, прежде чем вернуться из JNI? Нужно ли использовать cv :: imencode, так как мне пришлось использовать cv :: imdecode для входного байта []?

Любая и вся помощь приветствуется! Пример кода ниже, где я конвертирую нужные мне данные из Mat в 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);

1

Решение

BitmapFactory ожидает, что предоставленные ему данные будут в известном формате файла, но вы передаете ему необработанные пиксели. Вы можете заставить его работать, вызывая cv :: imencode, но, возможно, более естественным решением для загрузки изображений из необработанных пиксельных данных будет создание исходного объекта Java Bitmap как изменяемого, а затем вызовы методов copyPixelsToBuffer и copyPixelsFromBuffer для получения и установки данные пикселей в этом объекте.

1

Другие решения

Решено! Это была комбинация моей исходной версии отправки в байтах с помощью 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);
0

По вопросам рекламы [email protected]