图片发自简书App

简介

本篇讲解使用opencv提供的流光法算法接口,实现物体跟踪。范例代码为参考修改tvl1_optical_flow.cpp实现。

具体实现

实现代码

#include

#include

#include "opencv2/video/tracking.hpp"

#include "opencv2/highgui/highgui.hpp"

using namespace cv;

using namespace std;

inline bool isFlowCorrect(Point2f u)

{

return !cvIsNaN(u.x) && !cvIsNaN(u.y) && fabs(u.y) < 1e9;

}

static Vec3b computeColor(float fx, float fy)

{

static bool first = true;

// relative lengths of color transitions:

// these are chosen based on perceptual similarity

// (e.g. one can distinguish more shades between red and yellow

//  than between yellow and green)

const int RY = 15;

const int YG = 6;

const int GC = 4;

const int CB = 11;

const int BM = 13;

const int MR = 6;

const int NCOLS = RY + YG + GC + CB + BM + MR;

static Vec3i colorWheel[NCOLS];

if (first){

int k = 0;

for (int i = 0; i < RY; ++i, ++k)

colorWheel[k] = Vec3i(255, 255 * i / RY, 0);

for (int i = 0; i < YG; ++i, ++k)

colorWheel[k] = Vec3i(255 - 255 * i / YG, 255, 0);

for (int i = 0; i < GC; ++i, ++k)

colorWheel[k] = Vec3i(0, 255, 255 * i / GC);

for (int i = 0; i < CB; ++i, ++k)

colorWheel[k] = Vec3i(0, 255 - 255 * i / CB, 255);

for (int i = 0; i < BM; ++i, ++k)

colorWheel[k] = Vec3i(255 * i / BM, 0, 255);

for (int i = 0; i < MR; ++i, ++k)

colorWheel[k] = Vec3i(255, 0, 255 - 255 * i / MR);

first = false;

}

const float rad = sqrt(fx * fx + fy * fy);

const float a = atan2(-fy, -fx) / (float)CV_PI;

const float fk = (a + 1.0f) / 2.0f * (NCOLS - 1);

const int k0 = static_cast(fk);

const int k1 = (k0 + 1) % NCOLS;

const float f = fk - k0;

Vec3b pix;

for (int b = 0; b < 3; b++)

{

const float col0 = colorWheel[k0][b] / 255.f;

const float col1 = colorWheel[k1][b] / 255.f;

float col = (1 - f) * col0 + f * col1;

if (rad <= 1)

col = 1 - rad * (1 - col); // increase saturation with radius

else

col *= .75; // out of range

pix[2 - b] = static_cast(255.f * col);

}

return pix;

}

static void drawOpticalFlow(const Mat_& flow, Mat& dst, float maxmotion = -1)

{

dst.create(flow.size(), CV_8UC3);

dst.setTo(Scalar::all(0));

// determine motion range:

float maxrad = maxmotion;

if (maxmotion <= 0)

{

maxrad = 1;

for (int y = 0; y < flow.rows; ++y)

{

for (int x = 0; x < flow.cols; ++x)

{

Point2f u = flow(y, x);

if (!isFlowCorrect(u))

continue;

maxrad = max(maxrad, sqrt(u.x * u.x + u.y * u.y));

}

}

}

for (int y = 0; y < flow.rows; ++y)

{

for (int x = 0; x < flow.cols; ++x)

{

Point2f u = flow(y, x);

if (isFlowCorrect(u))

dst.at(y, x) = computeColor(u.x / maxrad, u.y / maxrad);

}

}

}

int main(int argc, const char* argv[])

{

Mat frame0;

Mat frame1;

Mat_ flow;

Ptr tvl1 = createOptFlow_DualTVL1();

Mat out;

if (argc < 2){

cerr << "Usage : " << argv[0] << "" << endl;

return -1;

}

VideoCapture cap;

cap.open(argv[1]);

while(1){

cap >> frame0;

if(frame0.empty()){

cerr<< "video is over!!" << endl;

break;

}

cvtColor(frame0, frame0, CV_BGR2GRAY);

if(!frame1.empty()){

const double start = (double)getTickCount();

tvl1->calc(frame0, frame1, flow);

const double timeSec = (getTickCount() - start) / getTickFrequency();

cout << "calcOpticalFlowDual_TVL1 : " << timeSec << " sec" << endl;

drawOpticalFlow(flow, out);

imshow("out", out);

imshow("src", frame0);

waitKey(10);

}

frame0.copyTo(frame1);

}

waitKey();

return 0;

}

代码讲解

1、创建了一个DenseOpticalFlow实例,同时获得打开了需要跟踪处理的video视频到cap中。

Ptr tvl1 = createOptFlow_DualTVL1();

Mat out;

if (argc < 2){

cerr << "Usage : " << argv[0] << "" << endl;

return -1;

}

VideoCapture cap;

cap.open(argv[1]);

2、在循环中,不断的读取video的帧数据到frame0中,接着cvtColor将frame0中的数据,灰阶化。判断到存储前一帧数据为空,也就是表示

刚刚读取到第一帧数据时候,不进入处理函数中,直接跳过。最后将frame0中的帧数据,保存到frame1中。frame0进入下一次循环,获得新一帧

数据。

while(1){

cap >> frame0;

if(frame0.empty()){

cerr<< "video is over!!" << endl;

break;

}

cvtColor(frame0, frame0, CV_BGR2GRAY);

if(!frame1.empty()){

...........

...........

}

frame0.copyTo(frame1);

}

3、当检测到frame1保存了前一帧数据之后,进入到流光法计算中。首先获得当前时钟getTickCount。使用tvl1->calc分别传入当前

帧(frame0)和前一帧(frame1),将获得的位置偏移保存到flow中。接着计算出calc函数处理花费的时间,之后使用函数

drawOpticalFlow,利用flow中的位置偏移,根据偏移位置的方向和速度,从而在out图像,对应位置赋予不同的颜色和饱和度。最后将

当前帧图像和处理之后的out图像分别显示出来。

const double start = (double)getTickCount();

tvl1->calc(frame0, frame1, flow);

const double timeSec = (getTickCount() - start) / getTickFrequency();

cout << "calcOpticalFlowDual_TVL1 : " << timeSec << " sec" << endl;

drawOpticalFlow(flow, out);

imshow("out", out);

imshow("src", frame0);

waitKey(10);

android流光字体实现,【流光算法代码实现】Demo相关推荐

  1. android wheelview 字体颜色,百行代码实现Android WheelView

    先说下实现思路,这里,我打算使用ListView来实现. 第一步:无限滑动,这个比较简单,类似于Banner图的无限滑动原理,在Adapter中处理一下count即可,代码如下 // 为Count设置 ...

  2. 好看的css预加载旋转动画 与 流光字体

    今天刚好在做这个功能,就实现一个 预加载的动画效果,随手记录 一.预加载旋转动画 Html <view class="concentric_round"></vi ...

  3. html流光按钮,【CSS】css实现流光效果-按钮流光显示效果-自发光

    [CSS]css实现流光效果-按钮流光显示效果-自发光 [CSS]css实现流光效果-按钮流光显示效果-自发光 废话不多说,直接上代码 Streamer * { padding: 0; margin: ...

  4. Android图片缓存之Lru算法

    前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发 ...

  5. android 变化字体,android 字体修改

    android字体的设置有以下方法: 1)直接在代码设置Typeface customFont = Typeface.createFromAsset(this.getAssets(), "1 ...

  6. android 点击字体,图片背景效果一起变换Demo

    android  点击字体,图片背景效果一起变换Demo 运行效果: 点击前: 点击后: 这里我就不贴上所有的代码了,说一下他的思路: 1.分别为账号.背景图片(红色区域为一个linealayout, ...

  7. Android系统性能优化(59)----代码、图片和布局优化

    Android优化系列--代码.图片和布局优化 这篇文章分为三个部分代码优化.图片优化.布局优化,尽量每个方法都写了小的Demo! 代码优化:不要做多余的工作,尽量避免次数过多的内存的分配,(需要对a ...

  8. android 自定义字体_Android自定义字体教程

    android 自定义字体 In this tutorial, we'll explain how to set up android custom fonts in TextViews and Bu ...

  9. Android 中文字体的设置方法和使用技巧

    Android TextView字体颜色等样式具体解释连接:http://blog.csdn.net/pcaxb/article/details/47341249 1.使用字体库(自己定义字体的使用) ...

  10. android 获取默认字体,Android默认字体

    Android默认字体 (2012-03-09 17:29:53) 标签: 杂谈 分类: APP 简言之三种: monospace:sans: serif. 并有四种表现形式:正常:斜体:粗体:粗斜体 ...

最新文章

  1. Could not find 'cudnn64_6.dll'
  2. Jquery在线引用地址:
  3. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 14丨重新格式化部门表【难度中等】
  4. 阿里仿真灰度变更测试简介
  5. python selenium系列(六)实战技巧之弹框处理
  6. MySQL笔记-binlog理论及binlog回滚恢复数据
  7. lintcode-easy-Delete Node in the Middle of Singly Linked List
  8. AndroidDeveloper Weekly NO.4
  9. C语言实现银行管理系统
  10. MySQL免安装版本的配置
  11. 侍魂微信新服务器,侍魂手游2019年3月23日微信问答试炼答案
  12. 02.虚拟功能介绍虚拟机网络配置xshell远程连接
  13. 学区摇号软件设计_多校划片、电脑摇号之后,拼娃、拼钱、拼房的9种对应方案...
  14. 朋友可以分成三大类 对付虚伪的人3招
  15. 温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 2 Kotlin语法
  16. 线性代数·关于线性相关和线性组合
  17. NOIP2014 寻找道路
  18. RX的使用一:RXjava初级入门
  19. quick-lua中脚本和资源的加密
  20. ezpdf Android6,PDF阅读器专业版(ezPDF Reader Multimedia PDF) 安卓版 v2.6.6.0 中文免费版

热门文章

  1. php ucenter home登录,UCenter Home 2.0 正式版现正式下载!!
  2. 基于Matlab的数字水印设计实现
  3. 【阿里102句土话集锦】菜鸟必备
  4. C++写入并追加内容到txt中
  5. ANSYS APDL循环建模时的一些注意事项
  6. python 查看所有变量_CentOS6.查看 Python中变量的信息(名称类型内容等)
  7. PyTorch中文教程 | (6) torch.nn是什么?
  8. 深度 | Authing CTO 尚斯年:云时代下的数字身份自动化
  9. 《三体》与《西部世界》
  10. 嵌入式Linux驱动笔记(四)------USB键盘驱动程序