##GPU模塊小記
接觸一下OpenCV里一個之前沒有接觸的模塊:GPU。這里只是根據教程和網上一些文章進行簡單的記敘,歡迎大家批評指正。
注:在使用GPU模塊之前,需要確認在使用CMake編譯OpenCV時,勾選了選項WITH_CUDA和WITH_TBB使其生效生效。


若以上配置已經完成,在使用GPU模塊的函數之前,還做一下檢查:調用函數gpu::getCudaEnabledDeviceCount,如果你在使用的OpenCV模塊編譯時不支持GPU,這個函數返回值為0;否則返回值為已安裝的CUDA設備的數量。
OpenCV的GPU模塊只支持NVIDIA的顯卡,原因是該部分是基于NVIDIA的CUDA和NVIDIA的NPP模塊實現的。而該模塊的好處在于使用GPU模塊無需安裝CUDA工具,也無需學習GPU編程,因為不需要編寫GPU相關的代碼。但如果你想重新編譯OpenCV的GPU模塊的話,還是需要CUDA的toolkit。
由于GPU模塊的發展,使大部分函數使用起來和之前在CPU下開發非常類似。首先,就是把GPU模塊鏈接到你的工程中,并包含必要的頭文件gpu.hpp。其次,就是GPU模塊下的數據結構,原本在cv名字空間中的現在都在gpu名字空間中,使用時可以gpu::和cv::來防止混淆。
在GPU模塊中,矩陣的類型為:GpuMat而不是OpenCV中使用的cv::Mat,其他的函數命名和CPU模塊中相同。OpenCV中GPU模塊函數的使用步驟如下:
~~~
1.驗證OpenCV是否已啟用GPU模塊。
2.上傳待處理數據到GPU (Mat --> GpuMat)。
3.調用OpenCV支持的GPU的處理函數。
4.下載處理結果到CPU (GpuMat ---> Mat)。
~~~
根據[http://blog.csdn.net/yang_xian521/article/details/7249532](http://blog.csdn.net/yang_xian521/article/details/7249532)?所提到的,一個問題是對于2.0的GPU模塊,多通道的函數支持的并不好,推薦使用GPU模塊處理灰度的圖像。有些情況下,使用GPU模塊的運行速度還不及CPU模塊下的性能,所以可以認為,GPU模塊相對而言還不夠成熟,需要進一步優化。很重要的一個原因就是內存管理部分和數據轉換部分對于GPU模塊而言消耗了大量的時間。
一段自帶的示例代碼如下,實現求矩陣轉置的功能:
~~~
#include <iostream>
#include "cvconfig.h"
#include "opencv2/core/core.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/core/internal.hpp" // For TBB wrappers
using namespace std;
using namespace cv;
using namespace cv::gpu;
struct Worker { void operator()(int device_id) const; };
int main()
{
int num_devices = getCudaEnabledDeviceCount();
if (num_devices < 2)
{
std::cout << "Two or more GPUs are required\n";
return -1;
}
for (int i = 0; i < num_devices; ++i)
{
DeviceInfo dev_info(i);
if (!dev_info.isCompatible())
{
std::cout << "GPU module isn't built for GPU #" << i << " ("
<< dev_info.name() << ", CC " << dev_info.majorVersion()
<< dev_info.minorVersion() << "\n";
return -1;
}
}
// Execute calculation in two threads using two GPUs
int devices[] = {0, 1};
parallel_do(devices, devices + 2, Worker());
return 0;
}
void Worker::operator()(int device_id) const
{
setDevice(device_id);
Mat src(1000, 1000, CV_32F);
Mat dst;
RNG rng(0);
rng.fill(src, RNG::UNIFORM, 0, 1);
// CPU works
transpose(src, dst);
// GPU works
GpuMat d_src(src);
GpuMat d_dst;
transpose(d_src, d_dst);
// Check results
bool passed = norm(dst - Mat(d_dst), NORM_INF) < 1e-3;
std::cout << "GPU #" << device_id << " (" << DeviceInfo().name() << "): "
<< (passed ? "passed" : "FAILED") << endl;
// Deallocate data here, otherwise deallocation will be performed
// after context is extracted from the stack
d_src.release();
d_dst.release();
}
~~~
CUDA的基本使用方法:[http://www.cnblogs.com/dwdxdy/archive/2013/08/07/3244508.html](http://www.cnblogs.com/dwdxdy/archive/2013/08/07/3244508.html)
- 前言
- Win8.1下OpenCV2.4.9+Qt5.3.2開發環境搭建
- OpenCV2學習筆記(一)
- OpenCV2學習筆記(二)
- OpenCV2學習筆記(三)
- OpenCV2學習筆記(四)
- OpenCV2學習筆記(五)
- OpenCV2學習筆記(六)
- OpenCV2學習筆記(七)
- OpenCV2學習筆記(八)
- OpenCV2學習筆記(九)
- OpenCV2學習筆記(十)
- OpenCV2學習筆記(十一)
- OpenCV2學習筆記(十二)
- OpenCV2學習筆記(十三)
- OpenCV2學習筆記(十四)
- OpenCV2學習筆記(十五)
- OpenCV2學習筆記(十六)
- OpenCV2學習筆記(十七)
- OpenCV2學習筆記(十八)
- OpenCV2學習筆記(十九)
- OpenCV2學習筆記(二十)
- OpenCV2學習筆記(二十一)
- OpenCV2學習筆記(二十二)