【NVIDIA Jetson TK1】四,TK1开发板运行单点光流程序,鼠标点选光流追踪点
2015-12-27 22:33
447 查看
目录
目录说明
程序代码
1 代码说明
2 代码使用说明
运行截图
问题与解决方法
接下来
1 说明
上一篇文章写了在板子上运行光流,但是这个光流的话是全局的光流,也就是整个屏幕的角点进行光流运算,现在把我之前弄得,一个可选追踪单点的单点式光流程序,整个程序的代码贴出来。运行环境:
1,nvidia jetson tk1
2.opencv 2.4.9
3.linux 的 g++
2 程序代码
#include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <opencv2\opencv.hpp> #include <iostream> #include <ctype.h> #include <stdio.h> //#include <unistd.h> #include <stdlib.h> using namespace cv; using namespace std; vector<Point2f> point1, point2; bool left_mouse = false; Point2f point; int pic_info[4]; Mat gray, prevGray, image; const Scalar GREEN = Scalar(0, 255, 0); int rect_width = 0, rect_height = 0; Point tmpPoint; static const double pi = 3.14159265358979323846; static IplImage *frame1 = NULL; static IplImage *framet = NULL; static int line_thickness = 2 ; CvPoint p, q; inline static double square(int a) { return a * a; } static void onMouse(int event, int x, int y, int /*flags*/, void* /*param*/){ Mat mouse_show; image.copyTo(mouse_show); if (event == CV_EVENT_LBUTTONDOWN){ pic_info[0] = x; pic_info[1] = y; left_mouse = true; } else if (event == CV_EVENT_LBUTTONUP){ rectangle(mouse_show, Point(pic_info[0], pic_info[1]), Point(x, y), GREEN, 2); x = (pic_info[0] + x) / 2; y = (pic_info[1] + y) / 2; point = Point2f((float)x, (float)y); point1.clear(); point2.clear(); point1.push_back(point); imshow("LK Demo", mouse_show); left_mouse = false; } else if ((event == CV_EVENT_MOUSEMOVE) && (left_mouse == true)){ rectangle(mouse_show, Point(pic_info[0], pic_info[1]), Point(x, y), GREEN, 2); imshow("LK Demo", mouse_show); } } int main(int argc, char** argv) { //读取摄像头 VideoCapture cap(0); //读取视频文件 //VideoCapture cap; cap.open("optical_flow_input.avi"); if (!cap.isOpened()) { return -1; } TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03); //迭代算法的终止条件 Size winSize(32, 32); CvSize frame_size; frame_size.height = cap.get(CV_CAP_PROP_FRAME_HEIGHT); frame_size.width = cap.get(CV_CAP_PROP_FRAME_WIDTH); //allocateOnDemand(&frame1, frame_size, IPL_DEPTH_8U, 3); namedWindow("LK Demo", CV_WINDOW_NORMAL); setMouseCallback("LK Demo", onMouse, 0); for (;;){ Mat frame; cap.read(frame); if (frame.empty()) break; frame.copyTo(image); cvtColor(image, gray, COLOR_BGR2GRAY); framet = &IplImage(image); if ((!point1.empty())){ vector<uchar> status; vector<float> err; if (prevGray.empty()) gray.copyTo(prevGray); calcOpticalFlowPyrLK(prevGray, gray, point1, point2, status, err, winSize,5, termcrit, 0, 0.001); //使用金字塔Lucas&Kanade方法计算一个稀疏特征集的光流 tmpPoint = point2[0]; rectangle(image, Point(tmpPoint.x - 30, tmpPoint.y - 30), Point(tmpPoint.x + 30, tmpPoint.y + 30), GREEN, 2); p.x = (int)point1[0].x; p.y = (int)point1[0].y; q.x = (int)point2[0].x; q.y = (int)point2[0].y; double angle; angle = atan2((double)p.y - q.y, (double)p.x - q.x); double hypotenuse; hypotenuse = sqrt(square(p.y - q.y) + square(p.x - q.x)); CvScalar line_color; line_color = CV_RGB(255, 0, 0); /*执行缩放*/ q.x = (int)(p.x - 5 * hypotenuse * cos(angle)); q.y = (int)(p.y - 5 * hypotenuse * sin(angle)); /*画箭头主线*/ /* "frame1"要在frame1上作画. * "p" 线的开始点. * "q" 线的终止点. * "CV_AA" 反锯齿. * "0" 没有小数位. */ cvLine(framet, p, q, line_color, line_thickness, CV_AA, 0); /* 画箭的头部*/ p.x = (int)(q.x + 9 * cos(angle + pi / 4)); p.y = (int)(q.y + 9 * sin(angle + pi / 4)); cvLine(framet, p, q, line_color, line_thickness, CV_AA, 0); p.x = (int)(q.x + 9 * cos(angle - pi / 4)); p.y = (int)(q.y + 9 * sin(angle - pi / 4)); cvLine(framet, p, q, line_color, line_thickness, CV_AA, 0); cvShowImage("LK Demo", framet); } imshow("LK Demo", image); waitKey(100); std::swap(point2, point1); cv::swap(prevGray, gray); } return 0; }
2.1 代码说明
简单说一下这个代码,可以单点光流,因为用的是onmouse()这个函数监视鼠标的事件,鼠标左键单击就会返回一个x,y的坐标值,根据这个点的坐标,输入到光流函数里,光流的部分主要就是靠calcOpticalFlowPyrLK()这个函数实现的,来监视这个点的灰度值在整个过程中的位移变化,并且会移植在这个点周围画一个正方形,移动的速度和方向还用经典的光流向量箭头来表示。2.2 代码使用说明
在tk1上的使用方法:1,首先把上面那段代码保存成比如mouse.cpp的文件拷到tk1的某个文件夹位置。
2,然后打开终端,cd进入那个文件夹的位置。
3,在终端中输入
g++ mouse.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_video -lopencv_contrib -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -o mouse
4,能跑通的话,cpp文件应该会消失,在该文件夹中出现一个可执行的文件。
5,要运行这个程序的话,两种方式:
一个是接着上面那短代码接着输入
./mouse
这样会在终端中显示运行情况,如果有错误,或者运行不了,在终端中会有错误的提醒。
第二种方式就是直接点击该文件夹里的那个叫mouse的可执行文件,但不会显示运行的情况,只有一个对话框运行着光流代码。
3 运行截图
4 问题与解决方法
问题一:运行时会报内存错误。解决方法:后来查了一下资料,发现有些函数的接口格式与调用函数时输入进去的格式不符,方法
//先定义一个中间的值 static IplImage *framet = NULL; //对于原来的值image mat image; //用&IplImage()这个小函数转换一下传给暂存值framet framet = &IplImage(image); //之后完美运行 cvShowImage("LK Demo", framet);
问题二:双击可执行文件方式运行程序,程序没法关闭,关了之后还往出冒
解决方法:
首先执行代码:ps -e
调出整个系统的所有进程
看叫 mouse 的这个进程,记住对应的前面四位编号是多少 假设是8888
然后执行 sudo kill 8888
输入密码
进程就结束了,再也不往出冒了
5 接下来
当时弄完这个之后,就开始研究双目视觉的东西,主要就是用两个摄像头来实现对图像深度的测算,目前的进展是:可以完全用一段opencv 的代码在电脑上实现视差图的输出,可以输出指定点的三维坐标,但是三维坐标不是很准,目前怀疑是因为视差图太粗犷缘故,目前在电脑上ok的代码,在tk1上可以编译,但是没法运行,两个摄像头死活启动不起来,目前还没调通。目前,由于被分配了新的任务,估计opencv的东西不可避免的要稍微搁一下了,有时间再把双目视觉的我的理解,和一些代码传上来备份一下。
更多光流算法,可见我之前的文章: /article/7582892.html
相关文章推荐
- iOS中协议和延展的区别
- spring与redis集成之aop整合方案
- 第二百六十九天 how can I 坚持
- Java正则表达式功能及应用(上)
- Subsequence-二分
- MATLAB面向对象编程实现鱼群算法
- 【转】How-To-Ask-Questions-The-Smart-Way
- hdoj N bulbs 5600 (规律)
- linux下opencv的安装
- Hadoop实现接口
- static关键字
- c#webBrowser 获取标签值
- Stack based vs Register based Virtual Machine Architecture
- SQL的查询操作语句
- session如何保存在专门的StateServer服务器中
- 编译源码包httpd
- 序
- JAVAWEB安全开发
- Codeforces Round #337 (Div. 2) B. Vika and Squares 水题
- data-ng-model 指令