專案名稱: 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)
留言列表