【问题标题】:Reading frames from video file using openCV and Native code C++使用 openCV 和本机代码 C++ 从视频文件中读取帧
【发布时间】:2013-11-19 10:13:01
【问题描述】:

我正在尝试编写一个应用程序来获取视频的所有帧并对其进行操作,我发现在 Android 上提取帧的最佳方法是使用 OpenCv lib。

我在示例代码中看到使用 VideoCapture 对象接收视频路径并可以从中抓取帧,所以我编写了以下代码,但 capture.open() 并没有真正打开视频文件,捕获.isOpen() 总是假的。

源代码:

#include <jni.h>
//opencv

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/core/mat.hpp>
//C
#include <stdio.h>
#include <string.h>
//C++
#include <iostream>
#include <sstream>
//Android
#include <android/log.h>

//#define  LOGI(TAG,INFO)  __android_log_print(ANDROID_LOG_INFO,INFO,__VA_ARGS__)

using namespace cv;

extern "C" {

JNIEXPORT void JNICALL Java_com_example_nativeopencvcheck_MainActivity_processVideo(JNIEnv* env,
    jobject thsObj,jstring fileName) {

const char * fileNameNative;
jboolean isCopy;
fileNameNative = env->GetStringUTFChars(fileName, &isCopy);

//create the capture object
__android_log_print(ANDROID_LOG_ERROR, "From_Native",
            "trying to open file: %s", fileNameNative);
VideoCapture capture(fileNameNative);
capture.open(fileNameNative);

if (!capture.isOpened()) {  //!!!!!! ALWAYS CLOSED !!!!!
    __android_log_write(ANDROID_LOG_ERROR, "From_Native",
            "capture isn't open. closing..");
    exit( EXIT_FAILURE);
}

Mat iplimage;
capture.retrieve(iplimage,0); 
if (iplimage.size > 0) {
    jclass cls = env->FindClass( "com/example/opencvframesext/MainActivity");
    if (cls == 0) {
        return;
    }

    jmethodID javamethod = env->GetMethodID(cls, "getCurrentFrameFromNative", "()V");
    if (javamethod == 0) {
    //  LOGI("From_Native","GetMethodID error");
        return;
    }

    jobject obj; // TODO
    env->CallVoidMethod(obj, javamethod);

   return;
}


/*bool gotFrame = capture.read(mat);
 while (gotFrame) {
 mats.addref(mat);
 capture.read(mat);
 }*/

//delete capture object
capture.release();
}
}

【问题讨论】:

  • 您好,谢谢您的回复。我对其进行了测试,仍然需要 200 毫秒来构建一个框架。对我来说太慢了,我会继续寻找更快的提取方法。干杯
  • 我调整了测试以提取全帧并显示一些时间数据,并为它提供了一个 720p 的屏幕录像视频。在 Nexus 5 上,我得到大约 17 毫秒(解码)+ 177 毫秒(glReadPixels)+ 110 毫秒(字节重新排序)+ 468 毫秒(PNG 保存)。大概你不需要 reorder+png,但你需要避免 glReadPixels,这可能是在做 YUV->RGB 转换。理论上,API 19 android.media.ImageReader 类可以让您访问 Surface 上的 YUV 数据,但在 Android 4.4 中,它仅适用于 Camera 输出(不适用于 MediaCodec 解码器)。
  • 嗨@fadden,你能运行原生 C++ 代码,在 Nexus 5 上获取相机框架吗?我无法访问相机,与code.opencv.org/issues/3490 中的问题报告相同。拜托我需要你的帮忙。刚买了设备,喜欢价格和质量,但我的最终项目代码无法在那里运行:((
  • FWIW,我在 Nexus 5 上将 glReadPixels() 缩短到几毫秒,但在 Nexus 10(不同的 GPU)上仍然非常缓慢。这篇文章几乎可以正常访问本地缓冲区,但有些地方不太对劲:stackoverflow.com/questions/21151259/…

标签: android opencv android-ndk


【解决方案1】:

是的,不幸的是,这行不通。

Android 上没有用于 VideoCapture 的 ffmpeg 后端。

【讨论】:

  • 难以置信,所以没有办法用 openCv 从视频中提取帧?
  • 除非您想出自己的 ffmpeg 端口,否则不会。 javacv ppl 有点解决了这个问题,但那是一个完全不同的故事
  • 是的,但是 javacv 的许可证是 GPL,如果你将它添加到你的项目中,你必须开源它(或者为从 Play 商店下载的每次付费)
  • 是的。在大多数情况下也使用不推荐使用的 c-api,并且 手动滚动
  • 2020年还是这样吗? (使用 c++)
猜你喜欢
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
相关资源
最近更新 更多