Android NDK OpenCV稠密光流调用

2019-08-13 16:54:57 浏览数 (1)

昨天公众号中收到多学多看多体会多感悟的留言问在Android OpenCV里是否能能调用稠密光流,由于我也没有试过,所以我们就专门来做了一次这个操作,也感谢留言的小伙伴提出的问题,我们也是在不断地解决问题中学习成长的。

经过自己的测试,Android利用NDK方式实现稠密光流还是可以的,不过和我在《C OpenCV视频操作之稠密光流对象跟踪》里提到过的,稠密光流算法(即图像上所有像素点的光流都计算出来),由于要计算图像上所有点的光流,故计算耗时,速度慢。

视频效果

点击边框调出视频工具条

稠密光流代码实现

稠密光流的API及简单的例子在《C OpenCV视频操作之稠密光流对象跟踪》中已经提到了,这里我就不再提了,主要是说在Android中怎么实现的,源码我会在文章最后贴出地址,主要还是用了《Android通过OpenCV和TesserartOCR实时进行识别》中的程序,以后OpenCV4Android中的实现一般还是在在那个程序中来做测试,主要是从头搭建也比较麻烦。

创建C 文件

我们在CPP下面新建了opticalflow的头文件和源文件

头文件中两个方法,一个是native-lib中调用的方法,一个是在源图上进行绘制的方法

Opticalflow.cpp

定义两个Mat,一个是上一帧的灰度图,一个是稠密光流处理的数据。

绘制结果函数

外部调用稠密光流的方法

上面两个红框,一个是20的参数是把偏移量大于20的才进行绘制处理,另一个是将当前的灰度图存放到前一帧灰度图中等处理,在《C OpenCV视频操作之稠密光流对象跟踪》中我们是只取了第一帧,显示出来的就是从第一帧中不停的进行变化的绘制,但是我们这个Demo中显示的图像只有一个,摄像头也随时可以移动,所以用那篇中只对比第一帧的情况是不行的,所以我这里改为都是当前帧对比前一帧的数据。

核心代码

代码语言:javascript复制
//
// Created by 36574 on 2019-08-11.
//

#include "opticalflow.h"

//定义前一帧灰度图
Mat prev_gray;
//定义数据
Mat flowdata;

//绘制结果的函数
void opticalflow::drawcalcFlowHF(Mat &flowdata, Mat &image, int step) {
    for (size_t row = 0; row < flowdata.rows; row  ) {
        for (size_t col = 0; col < flowdata.cols; col  ) {
            const Point2f fxy = flowdata.at<Point2f>(row, col);
            //判断大于输入的step后进入
            if (fxy.x > step || fxy.y > step) {
                //用绿色画线点到前一帧的差
                line(image, Point(col, row),
                     Point(cvRound(col   fxy.x), cvRound(row   fxy.y)),
                     Scalar(0, 255, 0));
                //用红色画点为当前的点
                circle(image, Point(col, row), 2, Scalar(255, 0, 0), -1);
            }
        }
    }
}

//稠密光流
vector<Mat> opticalflow::dealOpticalFlow(Mat &src) {
    Mat gray;
    //转为灰度图
    cvtColor(src, gray, COLOR_BGRA2GRAY);
    //判断是否有前一帧图像
    if (!prev_gray.empty()) {
        //存在前一帧进行稠密光流操作
        calcOpticalFlowFarneback(prev_gray, gray, flowdata,
                                 0.5, 3, 15, 3, 5, 1.2, 0);

        //将结果绘画出来,这里参数为20就是变化大的才显示出来
        drawcalcFlowHF(flowdata, src, 20);
    }
    //将前一帧图像存放到
    gray.copyTo(prev_gray);

    return vector<Mat>();
}

视频截图

源码地址

GitHub:https://github.com/Vaccae/AndroidOpenCVTesserartOCR

-END-

0 人点赞