close

專案名稱: 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

解決方案, 升級到新的版本

image

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花費時間:

image

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版本結果如下

image

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不太一樣

導致結果不一樣

image

========================================

讀入一張影像1024x 768, 測試邊緣偵測,比較CPU和GPU花費時間:

image

CPU: 第一次執行 448 ms, 第二次 325 ms, 第三次 313 ms

GPU: 第一次執行 757ms, 第二次 86 ms, 第三次 81 ms

image

image


參考資料:

1. OpenCV GPU 簡單紀錄

2. OpenCV on a GPU(PDF)

3. 使用OpenCV的OpenCL(ocl)模块

arrow
arrow
    全站熱搜

    me1237guy 發表在 痞客邦 留言(4) 人氣()