Android NDK OpenCV稠密光流调用

点击蓝字关注我

昨天公众号中收到多学多看多体会多感悟的留言问在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中显示的图像只有一个,摄像头也随时可以移动,所以用那篇中只对比第一帧的情况是不行的,所以我这里改为都是当前帧对比前一帧的数据。

核心代码

//
// 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-

Vaccae的往期经典

OpenCV

《C++ OpenCV案例实战---卡号获取

《C++ OpenCV案例实战---卡片截取(附代码)

《C++ OpenCV透视变换---切换手机正面图片》

《C++ OpenCV实战---获取数量

《C++ OpenCV实战---利用颜色分割获取数量》

《OpenCV4Android NDK方式进行Canny边缘检测》

《OpenCV4Android NDK方式TesserartOCR实时进行识别》

《OpenCV4Android NDK级联方式实时进行人脸检测》

Android

《Android利用SurfaceView结合科大讯飞修改语音实别UI

《Android关于语音识别的功能实现分析(一)---结构化思维》

《Android关于语音识别的功能实现分析(二)---语义解析》

《Android根据类生成签名字符串

《Android碎片化布局fragment的实战应用

《Android中RecyclerView嵌套RecyclerView

《Android里用AsyncTask后的接口回调

.Net C#

《C#自定义特性(Attribute)讲解与实际应用

《C#根据类生成签名字符串(附DEMO下载地址)

《C++创建动态库C#调用》

《C#与三菱PLC(型号FX2N)串口通讯类

数据库及其它

《Oracel存储过程写报表实战》

《Delphi轮播视频和图片程序(用于双屏显示程序)

《SQL随机增加销售数据的脚本编写(附脚本下载地址)

SQL Server中With As的介绍与应用(三)--递归的实战应用

《Oracle通过ODBC连接SQL Server数据库

Oracle利用row_number()over()方式解决插入数据时重复键的问题

 

请扫码

给个关注

微卡智享

技术交流与分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vaccae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值