2017-02-13 15 views
0

Я использую camera2 api для своего приложения, которое основано на Camera2Raw.Как получить исходные данные изображения датчика камеры Android с помощью JNI + OpenCV + NDK?

mRawImageReader = ImageReader.newInstance(largestRaw.getWidth(), 
     largestRaw.getHeight(),ImageFormat.RAW_SENSOR, /*maxImages*/ 

У меня есть image от ImageReader.OnImageAvailableListener, вместо сохранения файла DNG, я передаю его байтовый массив в моей родной функции OpenCV к процессу:

int w = image.getWidth(); 
int h = image.getHeight(); 
ByteBuffer buffer = planes[0].getBuffer(); 
byte[] data = new byte[buffer.remaining()]; 
buffer.get(data); 
addShot(w, h, data); 
image.close(); 

и функции C++:

JNIEXPORT jboolean JNICALL addShot(JNIEnv* env, jobject obj, jint width, jint height, jbyteArray p_data) 
    { 
     jbyte* _p_data= env->GetByteArrayElements(p_data, 0); 
     Mat srcBGR(height, width, CV_8UC3); 
     Mat mdata(height, width, CV_8UC3, (unsigned char *)_p_data); 
//  Mat tmp_mat= imdecode(mdata,1); 
     cvtColor(mdata, srcBGR, CV_RGB2BGR); 
     env->ReleaseByteArrayElements(p_data, _p_data, 0); 
    } 

Первый. для обеспечения уверенности, я пытаюсь сохранить как JPEG на стороне C++. Но результат имеет много зеленых цветов.

Я думаю, что в моем коде на C++ отсутствует часть.

Может ли кто-нибудь помочь в этом?

+0

[Docs] (https://developer.android.com/reference/android/graphics/ImageFormat.html#RAW_SENSOR): «Общий формат изображения датчика сырой камеры, обычно представляющий одноканальное изображение Байер-мозаики. образец пикселя цвета хранится с 16 бит точности ». - Разве это не так в вашем случае? Потому что вы, кажется, относитесь к нему как к 3-канальному RGB-изображению с 8-битной точностью. Это кажется довольно странным. –

+0

Да, правильно. Я думаю, что мой код на C++ может быть для другого случая, такого как формат YUV. Код, который я отправил, был моим испытанием, обработка изображений - это не моя область :(Поэтому я прошу помощи. Я был бы очень признателен, если бы кто-нибудь меня увел – imudin07

+0

android-24 добавил NdkCamera, вы могли бы получить изображение с камеры прямо оттуда Файлы заголовков находятся под платформами NDK include/camera, include/media (для AImagerReader). – Gerry

ответ

1

Обработка данных Bayer RAW не является тривиальным - это необработанное считывание значений пикселей с датчика, и вам нужно много дополнительных метаданных и обработки, чтобы преобразовать их в видимое изображение. Если вы не знаете, как это сделать, я не рекомендую попробовать - вы можете просто подключить библиотеку, например Adobe's DNG SDK, или libraw.

Вы уверены, что не хотите, чтобы данные YUV_420_888 обрабатывались, но несжаты?

+0

Благодарим за ответ. Библиотеки, которые вы отправили, предназначены для ПК? Я пытаюсь обрабатывать только в мобильном приложении. 'YUV_420_888'. Когда я сохраняю файл DNG и используя [Приложение для демонстрации RawDroid] (https://play.google.com/store/apps/details?id=com.anthonymandra.rawdroid&hl=ru), преобразованный в JPEG. был потрясающим.Так что я пытаюсь сделать что-то rawdroid делает – imudin07

+0

Также, используя YUV_420_888, не работал в Google Pixel XL – imudin07

+1

YUV_420_888 должен отлично работать на Pixel XL - вы используете размер, который фактически указан для YUV_420_888, или вы пытались повторно использовать размер RAW? не имеют одинаковых размеров, поскольку обработка до YUV обычно делает изображение немного меньшим (чтобы соответствовать общим соотношениям сторон и т. д.). Adobe DNG SDK работает на Android в наши дни, насколько я знаю (это даже в исходном дереве Android AOSP в Android Nougat). Не знаю, делает ли libraw. Если вы хотите написать свой собственный конвейер для обработки RAW, там есть тонна, и это из-за неясности простого ответа StackOverflow. –

1

После записи данных изображения RAW с помощью простой функции OpenCV считывается из буферной памяти.

Mat mImageMat; 
mImageMat = Imgcodecs.imdecode(new MatOfByte(data), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED); 

где, mImageMat is Mat класс контейнера изображений.

Тогда обработка изображения будет простой.

+0

О, спасибо! Как я могу сделать эту работу в JNI? Я использую opencv в родной части cpp, а не в java – imudin07

+0

Класс Mat может быть передан JNI с использованием '.getNativeObjAddr()' – Gowthaman