Сочетание JavaCV и openCV
У меня следующая проблема: у меня есть приложение Android, которое использует собственный код OpenCV. На первом этапе кадры, отредактированные OpenCV, пришли с камеры. Затем они были обработаны и нарисованы на дисплее.
Однако мои требования сейчас изменились. Кадры, которые нужно редактировать, взяты из видеофайла, хранящегося на SD-карте. Они должны быть обработаны кодом openCV и затем сохранены в новом видеофайле.
Прочитав много вещей, я понял, что в Android нет встроенных программ для правильного чтения видеофайлов по кадрам и обработки кадров. На компьютере OpenCV имеет функцию VideoCapture. Но это не работает на Android, так как openCV не имеет ffmpeg, который идет с ним.
Прочитав больше материала, я обнаружил, что JavaCV поставляется с FFMPEGFrameGrabber, а также с FFMPEGFrameRecorder. Итак, я реализовал все, что теперь позволяет мне получать отдельные кадры из видео, получать кадр IplImage и сохранять этот кадр в новом видео.
Теперь проблема: во время получения и хранения фрейм IplImage должен обрабатываться с использованием исходного кода OpenCV, так как не представляется возможным перенести полный код на JavaCV.
Итак, во-первых, я написал небольшую тестовую функцию JNI, которая получает адрес объекта MAT и рисует на нем маленький круг.
extern "C" {
JNIEXPORT void JNICALL Java_de_vion_postprocessing_step2_EyeTracking_editFrame(
JNIEnv*, jobject, jlong thiz, jlong addrRgba) {
//Convert the mat addresses into the objects
Mat& rgbFrame = *(Mat*) addrRgba;
Point2i scaledSmoothPoint(100,100);
circle(rgbFrame, scaledSmoothPoint, 20, YELLOW, -1);
}
Когда я прочитал, что IplImage расширяет CvArr, я просто вызываю функцию внутри моего кода следующим образом:
captured_frame = grabber.grab();
if (captured_frame == null) {
// no new frames
break;
}
editFrame(captured_frame .address());
Однако теперь я получаю следующую ошибку:
06-12 18:58:23.135: E/cv::error()(6498): OpenCV Error: Assertion failed (cn <= 4) in
void cv::scalarToRawData(const Scalar&, void*, int, int), file
/home/reports/ci/slave_desktop/50-SDK/opencv/modules/core/src/matrix.cpp, line 845
06-12 18:58:23.135: A/libc(6498): Fatal signal 6 (SIGABRT) at 0x00001962 (code=-6),
thread 6526 (AsyncTask #1)
Наконец, у меня вопрос: как я могу обработать кадр IplImage с помощью native OpenCV и, наконец, сохранить этот кадр IplImage, затем в видеомагнитофоне.
Я также открыт для новых идей, которые не обязательно требуют JavaCV, если мне не нужно писать FrameGrabber и FrameRecorder самостоятельно.
С наилучшими пожеланиями, Андре
1 ответ
Intel выпустила новый инструмент под названием INDE, который содержит компонент под названием INDE Media Pack. Это, однако, с помощью Java. Медиапакет берет медиа-каркас Android и сделал некоторые обширные инкапсуляции некоторых функций и добавил несколько вещей, чтобы сделать обработку видео / аудио / изображений очень простой. Вы можете скачать здесь
Вот как вы можете сделать захват видео, начиная с определенного кадра и заканчивая кадром (не полный код, просто чтобы дать вам представление), используя INDE. Вы найдете много примеров кода, как только вы загрузите инструмент
public void start(String videoPath) throws IOException
{
if (isStarted())
{
throw new IllegalStateException(TAG + " already started!");
}
capturer = new GLCapture(new AndroidMediaObjectFactory());
capturer.setTargetFile(videoPath);
capturer.setTargetVideoFormat(videoFormat);
capturer.start();
isStarted = true;
isConfigured = false;
framesCaptured = 0;
}
Надеюсь это поможет.