本次我所要完成的項目是 基於GPU加速的行人檢測系統
前言
GPU 加速的计算是利用一颗图形处理器 (GPU) 以及一颗 CPU 来加速科学、工程以及企业级应用程序。工业与学术界的数据科学家已将 GPU 用于机器学习以便在各种应用上实现开创性的改进,这些应用包括图像分类、视频分析、语音识别以及自然语言处理等等。我們實驗室的方向是無人駕駛,這個領域最近也是非常火熱,更有人直言三至五年無人駕駛將得以普及。而無人駕駛的必要條件之一就是要能快速、準確地識別出道路情況,相比於串行順序工作方式的CPU,那麼以多核並行計算的工作方式的GPU在運算速度方面將提供更大的優勢,這對於識別的實時性是非常有幫助的。
項目工作及環境
硬件:Jetson TK1
軟件:C++、OPENCV、ubuntu
項目分析
我在拿到項目任務之後進行了項目分析,將項目列爲以下兩個要點:
1.GPU加速 --- CUDA編程
2.行人檢測 --- SVM+HOG :OpenCV
實際上OpenCV for linux中就已經集成了CUDA的接口,在安裝好環境之後直接調用運行即可。
於是我將任務分解成如下幾個階段:
1.Jetson TK1的環境配置(包括CUDA、OPENCV以及熟悉linux)
2.SVM+HOG行人圖片檢測(CPU&opencv)
3.行人圖片檢測(GPU&opencv)
4.行人視頻檢測(CPU&GPU&opencv)
5.攝像頭事實檢測(附加)
項目工作及環境
硬件:Jetson TK1
軟件:C++、OPENCV、ubuntu
項目分析
我在拿到項目任務之後進行了項目分析,將項目列爲以下兩個要點:
1.GPU加速 --- CUDA編程
2.行人檢測 --- SVM+HOG :OpenCV
實際上OpenCV for linux中就已經集成了CUDA的接口,在安裝好環境之後直接調用運行即可。
於是我將任務分解成如下幾個階段:
1.Jetson TK1的環境配置(包括CUDA、OPENCV以及熟悉linux)
2.SVM+HOG行人圖片檢測(CPU&opencv)
3.行人圖片檢測(GPU&opencv)
4.行人視頻檢測(CPU&GPU&opencv)
5.攝像頭事實檢測(附加)
一 TK1系统图形界面(ubuntu)设置以及CUDA环境搭建
对于Jetson TK1环境的搭建与熟悉,主要是参照http://www.linuxdiyf.com/linux/16885.htm & http://www.elinux.org/Jetson/Installing_CUDA 教程中的步骤。这里注意installer.sh只能运行一次,运行完之后,熟悉的(其实我不是很熟悉)ubuntu界面就出来了!
在完成好TK1的ubuntu界面设置后,主要是安装好CUDA环境。这里对CUDA做一个简要的介绍:CUDA是NVIDIA公司推出的一款通用并行计算框架,该架构能使GPU通过并行计算解决复杂的计算问题。简单的来说,CUDA就可以看做是一种编程语言,要想使用GPU计算,就得使用CUDA编程。
装好环境以后,我们可以利用nvcc进行CUDA自带samples的编译运行,如deviceQuery,我们可以看到CUDA的各种计算性能的参数,具体参数意义可以参考:http://blog.csdn.net/poisonchry/article/details/16332369
二OpenCV的配置
注意:教程上说明OpenCV需要先配置好CUDA环境,这是因为OpenCV for Linux中直接提供了CUDA的接口,你只需要调用就行,这里就需要用到CUDA的环境。大部分的程序OpenCV中直接可以调用函数,但是若想要进一步优化程序或者实现更加高级的功能可能需要使用混合编程。
三尝试编写
初次接触ubuntu,对编程环境不是很熟悉,索性就用文本写程序,终端直接进行编译。在装好opencv之后,参见http://www.myexception.cn/other/1829048.html博客末尾处对samples的调用,其中有一个CPU vs GPU的霍夫变换直线检测的程序,可以清楚直观地看到GPU的并行运算性能远远高于CPU,于是,我也想尝试一下,编写一个简单的opencv程序,canny处理图像,程序如下:
#include <cmath> #include <iostream> #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/gpu/gpu.hpp" using namespace std; using namespace cv; using namespace cv::gpu; int main(int argc, const char* argv[]) { Mat src, dst, edge, gray; double start = (double)getTickCount(); src = imread("building.jpg"); dst.create(src.size(), src.type()); cvtColor(src, gray, COLOR_BGR2GRAY); Canny(gray, edge, 3, 9, 3); double t = ((double)getTickCount() - start)/getTickFrequency(); cout << "the time is(cpu) : " << 1000 * t << " ms" << endl; GpuMat src_gpu(src); GpuMat dst_gpu, edge_gpu, gray_gpu; double start2 = (double)getTickCount(); dst_gpu.create(src_gpu.size(), src_gpu.type()); gpu::cvtColor(src_gpu, gray_gpu, COLOR_BGR2GRAY); gpu::Canny(gray_gpu, edge_gpu, 3, 9, 3); double t2 = ((double)getTickCount() - start2)/getTickFrequency(); cout << "the time is(gpu) : " << 1000 * t2 << " ms" << endl; Mat temp; edge_gpu.download(temp); imshow("src", src); imshow("canny[cpu]", edge); imshow("canny[gpu]", temp); waitKey(); return 0; }于是得到比较时间:
竟然发现,gpu的运行时间要长于cpu,难道这说明gpu计算能力不如cpu?
在查阅资料以后,发现可能有这么一种解释,就是第一次调用CUDA接口需要耗费大量的时间,于是,将代码修改:
#include <cmath> #include <iostream> #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/gpu/gpu.hpp" #include "cuda.h" #include "cuda_runtime_api.h" using namespace std; using namespace cv; using namespace cv::gpu; int main(int argc, const char* argv[]) { cudaSetDevice(0); cudaFree(0); Mat src, dst, edge, gray; double start = (double)getTickCount(); src = imread("building.jpg"); dst.create(src.size(), src.type()); cvtColor(src, gray, COLOR_BGR2GRAY); Canny(gray, edge, 3, 9, 3); double t = ((double)getTickCount() - start)/getTickFrequency(); cout << "the time is(cpu) : " << 1000 * t << " ms" << endl; GpuMat src_gpu(src); GpuMat dst_gpu, edge_gpu, gray_gpu; double start2 = (double)getTickCount(); dst_gpu.create(src_gpu.size(), src_gpu.type()); gpu::cvtColor(src_gpu, gray_gpu, COLOR_BGR2GRAY); gpu::Canny(gray_gpu, edge_gpu, 3, 9, 3); double t2 = ((double)getTickCount() - start2)/getTickFrequency(); cout << "the time is(gpu) : " << 1000 * t2 << " ms" << endl; Mat temp; edge_gpu.download(temp); imshow("src", src); imshow("canny[cpu]", edge); imshow("canny[gpu]", temp); waitKey(); return 0; }实际上就是添加了一句CUDA的使用,让CUDA先被调用,这样第二次运算速度将快一些!
这里要注意,使用了CUDA的头文件以及函数,一定要确保ubuntu在指定路径下能搜寻得到.h文件和.so文件,并且在编译cpp文件时,要使用类似
g++ 文件名.cpp -l库名 -l库名··· -o 文件名,这样才能保证引入CUDA之后不报错。
但是,残酷的事实是,程序这么改对于结果而言并没有什么作用,gpu的时间还是要略大于cpu
在继续查阅资料之后,发现这么一种解释,对于小量计算而言,gpu的性能未必比cpu强,因为计算量太小,gpu根本用不上几个线程,其192个核的威力根本显现不出来,对于程序运行时间ms级的来说,完全没有必要使用gpu的并行计算,所以,在后面我将进一步地体会gpu并行计算的威力!
相关推荐
《闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU》这篇博文主要探讨了在计算机视觉领域中,OpenCV库的GPU加速与CPU执行的对比。OpenCV是一个广泛使用的开源计算机视觉和机器学习库,它支持多种平台,并且提供了...
Flutter学习之旅----环境搭建与Hello World,对应博客地址为http://blog.csdn.net/zhangxiangliang2/article/details/75566412
CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht
C#发现之旅 --- C#开发Windows Service程序
我的Android进阶之旅------>Android疯狂连连看游戏的实现 可以参考博客:http://blog.csdn.net/ouyang_peng/article/details/14115627
FPGA之旅---例化FPGA开发 FPGA(Field-Programmable Gate Array),即现场可编程门阵列,是一种基于集成电路的可编程逻辑设备。FPGA之旅---例化FPGA开发是FPGA开发的入门教程,本资源将指导读者从基本概念到实际...
精益之旅--制造业效率研究.pdf
游戏之旅--我的编程感悟.part1.rar(共3部分)
游戏之旅--我的编程感悟.part2.rar(共3部分)
游戏之旅--我的编程感悟.part3.rar(共3部分)
在“C#发现之旅 --- C#开发Windows Service程序”中,我们将深入探讨如何利用C#来创建和管理这样的服务。这个实例是根据提供的PDF教程编写的,确保了代码的有效性和实用性。现在,让我们详细了解一下Windows服务以及...
本篇《C#发现之旅 --- C#开发Windows Service程序》将带领读者深入了解如何使用C#来开发Windows Service程序。 ### Windows Service基础 首先,我们需要了解Windows Service的概念和特性。Windows Service是一种...
登月之旅10-19.ppt
_fire__我的NVIDIA开发之旅--实例分割模型YOLACT的TensorRT_API模型搭建_yolact_tensorrt_api
资源名称:游戏之旅-我的编程感悟资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
《Cocos2d-x 3.x 游戏开发之旅》是针对Cocos2d-x 3.x框架的一本深入实践教程,涵盖了从基础到高级的游戏开发全过程。在本资源包中,你将找到该书前17章的源代码,这为学习和理解Cocos2d-x引擎提供了宝贵的实践材料。...
游戏之旅-我的编程感悟part2 163主程从游戏开发的视角讲述程序设计的艺术