参考http://www.cnblogs.com/dwdxdy/p/3528711.html博客,加之以实践环节,我们可以知道有几种使用到GPU运算的方法:
1.利用OpenCV中提供的GPU模块
2.单独使用Cuda API编程
3.利用OpenCV中提供接口,并结合Cuda API编程
如果仅仅使用OpenCV中的GPU函数,就像博客(三)中演示一下,的确非常的简单而且可以得到比较理想的效果,但是缺点也是显然的,这种直接利用别人的函数是非常不灵活的。很多情况下,并行计算都会存在一个最优的问题,如何使得实际问题计算最优化,这就需要我们自己去思考,而不是仅仅调用别人的函数;
如果光单独使用CUDA编程,那这个工作量是可想而知的了,上文中有说道,GPU是处理计算量大计算繁琐复杂的部分,而其他的部分交给CPU去完成就是,那么这一部分完全可以使用直接提供的函数,例如OpenCV,所以,光使用CUDA进行编程,我也觉得没有必要;
最后,针对我所研究的课题,OpenCV结合CUDA编程是再适合不过的了。
这一次,我主要介绍在Ubuntu下如何将OpenCV与CUDA结合起来,也就是如何将.CU文件和.CPP文件结合起来得到想要的结果。这一部分我在网上查阅过大量的资料,但是资料非常的少,有的也只是很含糊的一笔带过,虽然方法非常简单,但是这里我还是详细地说明一下。
首先,我们的目的是:OpenCV+CUDA,完成对图像的灰度化
方法非常的简单,就是利用平均值算法 gray = ( r + g + b ) / 3得到对应像素点的值,那么这个计算部分我们就交给CUDA完成,最后结果我们将返还给CPU进行进一步处理以及结果显示。
先上代码:
test.cu文件
#include <opencv2/core/cuda_devptrs.hpp> #include "device_launch_parameters.h" #include "cuda.h" #include "cuda_runtime_api.h" #include "book.h" using namespace cv; using namespace cv::gpu; //自定义内核函数 __global__ void swap_rb_kernel(const PtrStepSz<uchar3> src, PtrStep<unsigned char> dst) { int y = blockIdx.y*blockDim.y+threadIdx.y; int x = blockIdx.x*blockDim.x+threadIdx.x; if(x < src.cols && y < src.rows) { dst(y, x) = (src(y, x).x + src(y, x).y + src(y, x).z) / 3; } } extern "C" void swap_rb_caller(const PtrStepSz<uchar3>& src, PtrStep<unsigned char> dst, cudaStream_t stream) { int uint = 8; dim3 grid(src.cols + uint-1/uint,src.rows + uint-1/uint); dim3 block(uint,uint); swap_rb_kernel<<<grid,block>>>(src, dst); if(stream == 0) cudaDeviceSynchronize(); }
testcpp.cpp
#include "stdio.h" #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/gpu/gpu.hpp" #include "opencv2/ml/ml.hpp" #include "opencv2/gpu/gpu.hpp" #include <opencv2/gpu/stream_accessor.hpp> #include "cuda.h" #include "cuda_runtime_api.h" #include <cmath> #include <iostream> #ifdef _DEBUG #pragma comment(lib, "opencv_core249d.lib") #pragma comment(lib, "opencv_imgproc249d.lib") #pragma comment(lib, "opencv_highgui249d.lib") #else #pragma comment(lib, "opencv_core249.lib") #pragma comment(lib, "opencv_imgproc249.lib") #pragma comment(lib, "opencv_highgui249.lib") #endif // DEBUG using namespace cv; using namespace cv::gpu; extern "C" void swap_rb_caller(const PtrStepSz<uchar3>& src, PtrStep<uchar3> dst, cudaStream_t stream); void swap_rb(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null()) { CV_Assert(src.type() == CV_8UC3); dst.create(src.size(), CV_8UC1); cudaStream_t s = StreamAccessor::getStream(stream); swap_rb_caller(src, dst, s); //cuResize(src, src.getWidth(), src.getHeight(), dst, dst.getWidth(), dst.getHeight()) } int main() { cudaSetDevice(0); cudaFree(0); printf("hello\n"); Mat image = imread("test.png"); imshow("src",image); GpuMat gpuMat,output; output.create(image.size(), CV_8UC1); Mat result; result.create(image.size(), CV_8UC1); double start = (double)getTickCount(); gpuMat.upload(image); swap_rb(gpuMat,output); output.download(result); double t = ((double)getTickCount() - start)/getTickFrequency(); printf("gpu time is : %d ms\n", (int)(1000 * t)); Mat result2; start = (double)getTickCount(); cvtColor(image, result2, COLOR_BGR2GRAY); t = ((double)getTickCount() - start)/getTickFrequency(); printf("cpu time is : %d ms\n", (int)(1000 * t)); imshow("gpu", result); imshow("cpu", result2); waitKey(0); return 0; }
这么一看,这个问题实际上就变成了CPP中调用CU中定义的函数
这里我相信大家已经看到了, 从CPU传送数据到GPU实际上就是GpuMat->PtrStepSz的过程,注意,如果Mat是3通道的,就要PtrStepSz<uchar3>,一通道的则为PtrStepSz<unsigned char>。
关于PtrStepSz的具体信息,可以参考http://docs.opencv.org/2.4/modules/gpu/doc/data_structures.html
有了程序,接下来我们尝试运行它。
首先,编译.CU文件,在终端下输入命令:
nvcc test.cu -c -o test
编译成功后生成了一个test的文件,类型暂不明
终端输入命令:
ar cqs libtest5.a test
则生成了一个libtest5.a的静态库,这个库名可以自己另取
接下来我们要将库考入ubuntu默认搜素路径:
sudo cp libtest5.a /usr/lib/
于是,接下来可以编译cpp程序:
g++ testcpp.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_calib3d -lopencv_contrib -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_video -lopencv_videostab -L./ -ltest5 -o testcpp -lcudart -lpthread
这里一定要注意了,如果报出DSO missing from command line这个错误,第一看看相应的包是否导入/usr/iib/中,第二,如果已经导入成功了,就将-l语句写到命令的最后,编译才不会出错!!!!一定注意!
于是,就可以生成我们熟悉的可执行文件
运行得到结果:
运行成功,但是时间表明,对于灰度化处理,gpu运行时间并没有cpu快,这说明,传输消耗的时间远比运行时间长,这样使用gpu计算是划不来的。
但是本人的目的是成功运行cuda+opencv程序,至此,已经成功!
相关推荐
6. **OpenCV与CUDA结合**:结合OpenCV和CUDA,可以创建高效的混合程序,即使用OpenCV的高阶API进行图像预处理,然后利用CUDA进行计算密集型的处理步骤,这样可以充分利用两种工具的优点。 7. **实例与实践**:...
《闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU》这篇博文主要探讨了在计算机视觉领域中,OpenCV库的GPU加速与CPU执行的对比。OpenCV是一个广泛使用的开源计算机视觉和机器学习库,它支持多种平台,并且提供了...
`opencv-contrib-cuda`是OpenCV的一个扩展模块,它利用NVIDIA的CUDA技术,将部分计算任务迁移到GPU上,以实现更高的计算速度和效率,尤其对于需要大量并行计算的图像处理任务。 标题中的"opencv-contrib-cuda-4.8.0...
在本压缩包“opencv4.5.1-cuda10.1-python3.7.rar”中,提供了OpenCV 4.5.1版本,这个版本支持GPU加速,特别针对NVIDIA的CUDA 10.1进行了优化,适用于Python 3.7编程环境。CUDA是NVIDIA开发的一种并行计算架构,允许...
总之,OpenCV与CUDA的混合编程能显著提升图像处理任务的速度,尤其是在处理大数据量时。通过合理地利用GPU的并行计算能力,可以优化计算密集型的计算机视觉算法,从而在实时或高性能应用中发挥重要作用。在实际开发...
opencv_4.8.1_msvc2019_CUDA_cudnn_Qt5.15.2,文件为自释放压缩包,包含Debug和release版本库,附带CUDA以及cudnn。 General configuration for OpenCV 4.8.1 ===================================== Version ...
《OpenCV 4.4.0、CUDA 11.0.2、CuDNN 8.0.2与Visual Studio 2019的整合详解》 在计算机视觉领域,OpenCV是一个不可或缺的库,它提供了丰富的图像处理和计算机视觉功能。本篇文章将深入探讨如何在Visual Studio 2019...
二、cuda与OpenCV结合方法 三、代码实例:图像均值滤波和图像反色 3.1 代码 3.2 代码说明 3.3 网格大小与线程块大小的确定 3.3.1 网格与线程块大小的限制 3.3.2 如何确定网格大小与线程块大小? 3.4 并行与串行的...
opencv4.10.0-cuda12.5.0-cudnn9.2.0-python3.10.15编译包,拷贝到conda的envs环境下解压,修改cv2cuda\Lib\site-packages\cv2文件夹下config.py和config-3.10.py中的相关路径即可用。 其中config.py的第一个路径需...
将OpenCV与CUDA结合使用,可以极大地提升OpenCV在执行GPU加速运算时的性能。 在"opencv-contrib-cuda-4.7.0-win-amd64"这个压缩包中,我们可以期待找到以下内容: 1. `lib`目录:这个目录通常包含了OpenCV和OpenCV...
当OpenCV与CUDA集成时,可以将计算任务卸载到GPU上,显著加快处理速度,这对于实时视频分析、图像处理和机器学习应用来说尤为重要。 在Windows环境下,使用Visual Studio(VS)编译OpenCV 4.5.2并链接CUDA 11,你...
本书详细介绍了将OpenCV与CUDA集成以用于实际应用。 本书涵盖了以下令人兴奋的功能:了解如何从CUDA程序访问GPU设备的属性和功能 了解如何加快搜索和排序算法 检测图像中的线条和圆形等形状 使用算法探索对象跟踪...
总结来说,"opencv4.5.2-contrib-cuda10.2-vtk"是一个专为高性能计算和高级可视化准备的OpenCV版本,它结合了CUDA的并行计算能力和VTK的3D可视化功能。这样的组合对于需要处理大量图像数据、执行复杂计算以及生成高...
在本文中,我们将深入探讨标题提及的“opencv4.7.0-contri-cuda117+dnn”及其相关的技术要点。 OpenCV 4.7.0是该库的一个稳定版本,提供了大量的新特性和性能优化。这个特定的构建版本包含了对CUDA 11.7的支持,这...
《Visual Studio 2019与OpenCV 3.4.16及CUDA 10.1集成详解》 在当今的计算机视觉领域,OpenCV库是不可或缺的一部分,它为图像处理、计算机视觉以及机器学习提供了强大的工具。而Visual Studio(VS)作为微软的旗舰...
在本压缩包“OpenCV-MinGW-Build-OpenCV-4.5.2-x64.zip”中,提供的是一份已经针对MinGW编译器优化的OpenCV 4.5.2版本,适用于64位Windows系统。 OpenCV 4.5.2是该库的一个稳定版本,它包含了众多新特性和性能提升...
在Linux环境下,安装OpenCV并利用CUDA进行加速是提高计算机视觉处理效率的重要步骤。OpenCV是一个开源的计算机视觉库,而CUDA则是NVIDIA提供的并行计算平台,它允许开发者利用GPU的强大运算能力来加速计算密集型任务...
【CUDA与OpenCV的结合】 CUDA(Compute Unified Device Architecture)是由NVIDIA公司推出的统一计算设备架构,它使得程序员能够利用GPU(图形处理器)的强大计算能力来进行通用计算任务,而不仅仅局限于图形渲染。...
当OpenCV与CUDA结合时,可以极大地提升计算机视觉应用的性能。 在"opencv_cuda_opencvcuda_cuda+opencv_opencv_cudaopencv_cuda_源码.zip"这个压缩包中,我们可以找到OpenCV库与CUDA支持相关的源代码。这些源代码...