專案名稱: EmguGPUEx
CUDA版本: cuda7.5.18 windows.exe for win7
Emgu CV版本: emgucv-windows-universal-cuda 3.0.0.2158
如果CUDA版本太舊,會顯示錯誤提示:
windows cuda driver version is insufficient for cuda run time version
解決方案, 升級到新的版本
private void getCudeDeviceInfo()
{
CudaDeviceInfo cdi = new CudaDeviceInfo();
label2.Text = cdi.IsCompatible.ToString();
label4.Text = cdi.MultiProcessorCount.ToString();
label5.Text = cdi.Name;
label7.Text = cdi.TotalMemory.ToString();
}
讀入一張影像3350 x 3350, 測試縮小原始影像長寬各一半大小,比較CPU和GPU花費時間:
CPU: 第一次執行 161 ms, 第二次 6 ms
GPU: 第一次執行 687 ms, 第二次 27 ms
(1) CPU版本
ResizeRunCPU輸入一個Mat來源影像,
利用Resize內建指令將來源影像長寬各降一半,
將結果影像matDst回傳給主程式
private Mat ResizeRunCPU(Mat matSrc)
{
Mat matDst = new Mat();
CvInvoke.Resize(matSrc, matDst, new Size(0, 0), 0.5, 0.5);
return matDst;
}
(2) GPU版本
ResizeRunGPU輸入一個Mat來源影像,
宣告兩個在GPU運行的變數gMatSrc和gMatDst
首先將CPU資料上傳GPU,即 gMatSrc.Upload(matSrc)
執行GPU版本Resize, 將結果儲存在gMatDst
最後,將GPU資料下載至CPU, 即 gMatDst.Download(matDst);
private Mat ResizeRunGPU(Mat matSrc)
{
Mat matDst = new Mat();
using (GpuMat gMatSrc = new GpuMat())
using (GpuMat gMatDst = new GpuMat())
{
gMatSrc.Upload(matSrc);
Emgu.CV.Cuda.CudaInvoke.Resize(gMatSrc, gMatDst, new Size(0, 0), 0.5, 0.5);
gMatDst.Download(matDst);
}
return matDst;
}
========================================
讀入一張影像1024x 768, 測試邊緣偵測,比較CPU和GPU花費時間:
CPU: 第一次執行 457 ms, 第二次 321 ms, 第三次 321 ms
GPU: 第一次執行 791 ms, 第二次 80 ms, 第三次 85 ms
private Mat FindEdgeCPU(Mat matSrc)
{
Mat matDst = new Mat();
using(Mat matGray= new Mat())
using (Mat matEdge = new Mat())
{
matSrc.ConvertTo(matGray, DepthType.Cv8U, 1);
CvInvoke.BilateralFilter(matGray, matEdge, -1, 50, 7);
CvInvoke.Canny(matEdge, matDst, 35, 200, 3);
}
return matDst;
}
CPU版本結果如下
private Mat FindEdgeGPU(Mat matSrc)
{
Mat matDst = new Mat();
using (GpuMat gMatSrc = new GpuMat())
using (GpuMat gMatDst = new GpuMat())
using( GpuMat gMatGray = new GpuMat())
using (GpuMat gMatEdge = new GpuMat())
{
gMatSrc.Upload(matSrc);
CudaInvoke.CvtColor(gMatSrc, gMatGray, ColorConversion.Bgr2Gray);
CudaInvoke.BilateralFilter(gMatGray, gMatEdge, -1, 50, 7);
CudaCannyEdgeDetector edgeDetector = new CudaCannyEdgeDetector(35, 200, 3);
edgeDetector.Detect(gMatEdge, gMatDst);
gMatDst.Download(matDst);
}
return matDst;
}
GPU版本結果如下:
在相同參數, GPU跑出來結果和CPU結果竟然不一樣…@@
由於找不到CudaInvoke.Canny所以改用CudaCannyEdgeDetector
有可能CudaCannyEdgeDetector和CvInvoke.Canny不太一樣
導致結果不一樣
========================================
讀入一張影像1024x 768, 測試邊緣偵測,比較CPU和GPU花費時間:
CPU: 第一次執行 448 ms, 第二次 325 ms, 第三次 313 ms
GPU: 第一次執行 757ms, 第二次 86 ms, 第三次 81 ms
參考資料:
2. OpenCV on a GPU(PDF)

作者您好: 讀完您的網頁後,對我有很大的幫助! 但我在測試 CudaDeviceInfo cdi = new CudaDeviceInfo(); 時 出現了OpenCV: The library is compiled without CUDA support的錯誤 我是安裝emgu3.1 與 cuda8.5.18 windows.exe for win7 可否請作者解惑 感謝
請注意EmguCV並不是每個版本都支援CUDA, 以我這篇文章為例是採用 emgucv-windows-universal-cuda 3.0.0.2158 你若是用其他版號, 請找找看有無cuda這關鍵字的版本囉!
感謝版主的回覆! 受益良多
可否再請教! 利用CudaInvoke與cvInvoke都可以利用GUP加速,只是使用的GUP不同,一個是nvidia的GUP,一個是intel內建的。那這兩個不同的GUP在執行速度上會不會有很大的差異。
cvInvoke是EmguCV包裝的指令模式, 方便呼叫OpenCV底層dll指令(CPU 版本) 此外, 對應的GPU版本就是CudaInvoke, 如果是處理大圖或是convolution相關指令, GPU的效能會大大超越CPU版本, 工你參考
Hi, You say "windows cuda driver version is insufficient for cuda run time version", could you give more information why? Also, in private Mat ResizeRunGPU(Mat matSrc) function, how do we save matDst to hard drive? So far I followed your tutorial but have not been able to save matDst. Thank you
The error message happened when the version of CUDA you installed is too old to run. To save image file, try to use this: cvInvoke.Imwrite(filename, image)