Способы получения высокого FPS для обработки компьютерного зрения в реальном времени - PullRequest
2 голосов
/ 28 декабря 2011

Моя цель - получить как можно более высокий FPS. Я буду счастлив с маленькими кадрами BW, но FPS должен быть максимальным. getSupportedPreviewFpsRange в HTC WildFire S возвращает (9, 30). Но когда я пытаюсь нарисовать предварительное изображение с самой простой обработкой, оно визуально достигает примерно 12-15 FPS максимум. После установки параметров и вызова метода startPreview() я делаю это:

camera.setPreviewCallback(new Camera.PreviewCallback() {
          @Override
          public void onPreviewFrame(byte[] bytes, Camera camera) {
            Bitmap bitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
            int[] colors = new int[size.width * size.height];
            for (int i=0; i < colors.length; i++){
              colors[i] = getBWColor(bytes[i]);
            }
            bitmap.setPixels(colors, 0, size.width, 0, 0, size.width, size.height);
            secondView.setImageBitmap(bitmap);
          }
        });
      }

private static int getBWColor(byte b){
    int res = 255;
    for(int i=0;i<3;i++){
      res = (res << 8) + b;
    }
    return res;
  }

Есть ли способ сделать это как можно быстрее? = (

Ответы [ 3 ]

5 голосов
/ 29 декабря 2011

Во-первых, используйте setPreviewCallbackWithBuffer () , он повторно использует один буфер и не должен выделять новый буфер в каждом кадре.Проверьте мой более старый ответ , есть пример, как его использовать.

Чем, не делайте дорогих операций в onPreviewFrame (), время данных ограничено, оно переписанона каждом новом кадре.Вы должны выполнить обработку в другом потоке.

И, конечно, не создавайте новое растровое изображение с массивом цветов в каждом кадре, сделайте это только один раз.

3 голосов
/ 28 декабря 2011

Я не совсем понимаю, что вы делаете, но я предполагаю, что вы убиваете себя при обработке.

1) Не создавайте новый растровое изображение каждый раз.Повторно использовать 1 растровое изображение.2) Управляйте своими растровыми изображениями в C / C ++ с помощью NDK.Посмотрите на «плазменный» пример.Это НАМНОГО быстрее, чем Java.Не потому, что на самом деле это C ++, а потому, что Java-версия API имеет тенденцию преобразовывать все, когда вы помещаете массив данных для пикселей.В версии C ++ вы можете напрямую манипулировать значениями пикселей.

1 голос
/ 28 декабря 2011

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

SufaceHolder mHolder;
mHolder = getHolder();
mHolder.addCallback(this); // this is the SurfaceView class
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.setKeepScreenOn(true);
...