android - 结合 JavaCV 和 openCV

标签 android c++ opencv ffmpeg javacv

我有以下问题: 我有一个使用 native OpenCV 代码的 Android 应用程序。第一步,由 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 extends 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)

最后,我的问题: 如何使用 nativeOpenCV 处理 IplImage 帧并最终将此 IplImage 帧存储在录像机中。

我也乐于接受不一定需要 JavaCV 的新想法,只要我不必自己编写 FrameGrabber 和 FrameRecorder。

最好的问候, 安德烈

最佳答案

Intel 发布了一个名为 INDE 的新工具,其中包含一个名为 INDE Media Pack 的组件。然而,这是使用 Java。 Media pack 采用 Android 媒体框架,对某些功能进行了大量封装,并添加了一些东西使视频/音频/图像处理变得非常简单。您可以从here下载

下面是如何使用 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;
    }

希望这对您有所帮助。

关于android - 结合 JavaCV 和 openCV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24190234/

相关文章:

c++ - 如何验证 C++ 链表中的节点是否已解除分配?

c - OpenCV 错误(cvCreateFileCapture())

android - Google 开发人员控制台 - 项目 ID 或项目编号

c++ - 使用 C++ 序列化对象的首选方法

android - 选项卡式 Activity 中的 ScrollView 向下跳转

c++ - 按下按键后如何 'enter'?

python - Blob 的稳健跟踪

python - Opencv 在本地使用 raspberry pi 但不能通过网络使用

android - 如何仅以编程方式为我的应用禁用移动数据

java - GridView 将最后一个项目显示为一半项目,有些经常不展开