Обработка кадров камеры Android в режиме реального времени
Я пытаюсь создать приложение для Android, которое будет обрабатывать кадры камеры в режиме реального времени. Для начала я просто хочу отобразить версию в оттенках серого, что видит камера. Мне удалось извлечь соответствующие значения из массива байтов в методе onPreviewFrame
. Ниже приведен фрагмент моего кода:
byte[] pic;
int pic_size;
Bitmap picframe;
public void onPreviewFrame(byte[] frame, Camera c)
{
pic_size = mCamera.getParameters().getPreviewSize().height * mCamera.getParameters().getPreviewSize().width;
pic = new byte[pic_size];
for(int i = 0; i < pic_size; i++)
{
pic[i] = frame[i];
}
picframe = BitmapFactory.decodeByteArray(pic, 0, pic_size);
}
Первыми [width*height]
значениями массива byte[]
являются значения яркости (оттенки серого). Как только я их извлечу, как мне отображать их на экране в качестве изображения? Это не 2D-массив, так как бы я указал ширину и высоту?
Ответы
Ответ 1
Вы можете получить обширное руководство от OpenCV4Android SDK. Изучите их доступные примеры, в частности Tutorial 1 Basic. 0 Android Camera
Но, как это было в моем случае, для интенсивной обработки изображений это будет медленнее, чем это приемлемо для приложения обработки изображений в режиме реального времени.
Хорошая замена для преобразования массива onPreviewFrame
в YUVImage:
YuvImage yuvImage = new YuvImage(frame, ImageFormat.NV21, width, height, null);
Создайте прямоугольник того же размера, что и изображение.
Создайте ByteArrayOutputStream и передайте это, прямоугольник и значение сжатия для сжатияToJpeg():
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(imageSizeRectangle, 100, baos);
byte [] imageData = baos.toByteArray();
Bitmap previewBitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length);
Рендеринг этих предварительных кадров на поверхности и лучших практических методах - это новое измерение. =)
Ответ 2
Этот старый пост привлек мое внимание.
API, доступный в '11, был гораздо более ограниченным. Сегодня можно использовать SurfaceTexture (см. пример) для предварительного просмотра потока камеры после (некоторых) манипуляций.
Ответ 3
Вы можете попробовать openFramworks (http://www.openframeworks.cc/). Существует CameraExample! Поэтому вам не нужно делать материал низкого уровня.
Ответ 4
Это нелегкая задача для достижения текущих инструментов Android/API. В общем, обработка изображений в реальном времени лучше выполняется на уровне NDK. Чтобы просто показать черно-белое изображение, вы все равно можете сделать это в java. Байт-массив, содержащий данные фрейма, находится в формате YUV, где сначала идет Y-Plane. Итак, если вы получите только Y-плоскость (первая ширина x высота байтов), она уже дает вам черный и белый.
Я добился этого благодаря обширной работе и испытаниям. Вы можете просмотреть приложение в google:
https://play.google.com/store/apps/details?id=com.nm.camerafx