我正在尝试编写一个获取视频所有帧并对其进行处理的应用,我发现在 Android 上提取帧的最佳方法是使用 OpenCv 库。
我在示例代码中看到使用接收视频路径并可以从中抓取帧的 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();
}
}
最佳答案
是的,不幸的是,这行不通。
Android 上的视频捕获没有 ffmpeg 后端。
关于android - 使用 openCV 和 native 代码 C++ 从视频文件中读取帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19841485/