Combining JavaCV and openCV

Combining JavaCV and openCV

本文关键字:openCV and JavaCV Combining      更新时间:2023-10-16

我有以下问题:我有一个使用原生OpenCV代码的Android应用程序。在第一步中,OpenCV编辑的帧来自相机。然后它们被处理并绘制在显示器上。

然而,我的要求现在已经改变了。需要编辑的帧来自存储在SD卡上的视频文件。它们必须经过openCV代码的处理,然后存储在一个新的视频文件中。

在阅读了很多东西之后,我意识到Android没有内置的东西来正确地逐帧读取视频文件并允许在这样做时处理帧。在计算机上,OpenCV具有视频捕获功能。但这在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)

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

我也对新的想法持开放态度,这些想法不一定需要JavaCV,只要我不需要自己编写FrameGrabber和frameecorder。

最诚挚的问候,安德烈

英特尔发布了一个名为INDE的新工具,其中包含一个名为INDE Media Pack的组件。然而,这是使用Java的。Media pack采用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;
    }

希望这对你有帮助。