2015-03-04 2 views
8

Я реализую приложение, которое использует обработку изображений в реальном времени на живые изображения с камеры. Он работал с ограничениями, используя теперь устаревшую android.hardware.Camera; для повышения гибкости & Производительность Я бы хотел использовать новый API android.hardware.camera2. Однако у меня возникают проблемы с получением необработанных данных изображения. Это на Samsung Galaxy S5. (К сожалению, у меня нет другого устройства Lollipop, пригодного для тестирования на другом оборудовании).Данные изображения из камеры Android2 API перевернуты и склеены на Galaxy S5

Я получил общую структуру (с вдохновением от образцов «HdrViewFinder» и «Camera2Basic»), а живое изображение рисуется на экране через SurfaceTexture и GLSurfaceView. Тем не менее, мне также необходимо получить доступ к данным изображения (оттенки серого только прекрасны, по крайней мере на данный момент) для пользовательской обработки изображений. Согласно документации к StreamConfigurationMap.isOutputSupportedFor(class), рекомендуемая поверхность для получения данных изображения напрямую будет ImageReader (правильно?).

Так я создал мои запросы захвата, как:

mSurfaceTexture.setDefaultBufferSize(640, 480); 
mSurface = new Surface(surfaceTexture); 
... 
mImageReader = ImageReader.newInstance(640, 480, format, 2); 
... 
List<Surface> surfaces = new ArrayList<Surface>(); 
surfaces.add(mSurface); 
surfaces.add(mImageReader.getSurface()); 
... 
mCameraDevice.createCaptureSession(surfaces, mCameraSessionListener, mCameraHandler); 

и в onImageAvailable обратного вызова для ImageReader, я доступ к данным следующим образом:

Image img = reader.acquireLatestImage(); 
ByteBuffer grayscalePixelsDirectByteBuffer = img.getPlanes()[0].getBuffer(); 

... но пока (как сказано), просмотр живого изображения работает, что-то не так с данными, которые я получаю здесь (или с тем, как я его получаю). Согласно

mCameraInfo.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputFormats(); 

... следующие ImageFormats должны быть поддержаны: NV21, JPEG, YV12, YUV_420_888. Я пробовал все (подключено к «формату» выше), все они поддерживают разрешение набора в соответствии с getOutputSizes(format), но ни один из них не дают желаемый результат:

  • NV21: ImageReader.newInstance броски java.lang.IllegalArgumentException : Формат NV21 не поддерживается
  • JPEG: Это действительно работает, но для приложения в реальном времени не имеет смысла пропускать JPEG-кодирование и декодировать для каждого кадра ...
  • YV12 и YUV_420_888: это самый странный результат - я вижу изображение полутонового изображения, но оно перевернуто вертикально (да, перевернуто, не повернуто!) и значительно squished (масштабируется значительно горизонтально, но не вертикально).

Что мне здесь не хватает? Что заставляет изображение переворачиваться и сжиматься? Как я могу получить геометрически корректный буфер оттенков серого? Должен ли я использовать другой тип поверхности (вместо ImageReader)?

Любые намеки приветствуются.

+0

Когда вы добавляете две цели для работы с необработанными кадрами, вы постоянно получаете кадры. Я также обновляю свое приложение на Api 2, но оно зависает от приложения с добавлением двух выходных целевых объектов. mPreviewRequestBuilder.addTarget (поверхность); mPreviewRequestBuilder.addTarget (mImageReader.getSurface()); – user1154390

ответ

4

Я нашел объяснение (хотя и не обязательно удовлетворительное решение): выясняется, что соотношение размеров матрицы датчика составляет 16: 9 (найдено через mCameraInfo.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);).

По крайней мере, когда запрашивается YV12/YUV_420_888, стример каким-либо образом не обрезает изображение, а масштабирует его неравномерно, чтобы достичь требуемого размера кадра. Изображения имеют правильные пропорции при запросе формата 16: 9 (из которых, к сожалению, есть только два варианта с более высоким разрешением). Кажется немного странным для меня - похоже, это не происходит при запросе JPEG или с аналогичными функциями API старой камеры или для неподвижных изображений; и я не уверен, что это неравномерно масштабированные кадры.

Я чувствую, что это не очень удовлетворительное решение, потому что это означает, что вы не можете полагаться на список выходных форматов, но вместо этого сначала нужно найти размер датчика, найти форматы с одинаковым соотношением сторон, а затем уменьшить изображение самостоятельно (по мере необходимости) ...

Я не знаю, является ли это ожидаемым результатом здесь или «особенностью» S5. Комментарии или предложения по-прежнему приветствуются.

+1

То же самое происходит на Moto X 2014. Я все еще смотрю на него, но я предполагаю, что это поведение для любого устройства, использующего устаревший режим Camera2. –

+0

Полезно знать, спасибо. Может кто-нибудь подтвердить, что это не происходит, например, с Nexus 6 ...? –

+1

Он отлично работает на Nexus 5, который имеет «ограниченный» уровень поддержки для камеры2. –

0

У меня была такая же проблема и у вас есть решение. Первая часть задачи настройки размера буфера поверхности:

// We configure the size of default buffer to be the size of camera preview we want. 
    //texture.setDefaultBufferSize(width, height); 

Это где изображение получает перекос, а не в камере. Вы должны прокомментировать это, а затем установить масштабирование изображения при его отображении.

  int[] rgba = new int[width*height]; 
      //getImage(rgba); 
      nativeLoader.convertImage(width, height, data, rgba); 

      Bitmap bmp = mBitmap; 
      bmp.setPixels(rgba, 0, width, 0, 0, width, height); 

      Canvas canvas = mTextureView.lockCanvas(); 

      if (canvas != null) { 
       //canvas.drawBitmap(bmp, 0, 0, null);//configureTransform(width, height), null); 
       //canvas.drawBitmap(bmp, configureTransform(width, height), null); 
       canvas.drawBitmap(bmp, new Rect(0,0,320,240), new Rect(0,0, 640*2,480*2), null); 

       //canvas.drawBitmap(bmp, (canvas.getWidth() - 320)/2, (canvas.getHeight() - 240)/2, null); 

       mTextureView.unlockCanvasAndPost(canvas); 
      } 

      image.close(); 

Вы можете поиграть со значениями, чтобы точно настроить решение проблемы.

+1

TIL setDefaultBufferSize - зло –

 Смежные вопросы

  • Нет связанных вопросов^_^