【发布时间】: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