Mat對象僅僅存儲在內存或者CPU緩存中。爲了得到一個GPU能直接訪問的opencv 矩陣你必須使用GPU對象 GpuMat 。它的工作方式類似於2維 Mat,唯一的限制是你不能直接引用GPU函數。(因爲它們本質上是完全不同的代碼,不能混合引用)。要傳輸*Mat*對象到*GPU*上並創建GpuMat時需要調用上傳函數,在回傳時,可以使用簡單的重載賦值操作符或者調用下載函數。
Mat I1; // 內存對象,可以用imread來創建
gpu::GpuMat gI; // GPU 矩陣 - 現在爲空
gI1.upload(I1); //將內存數據上傳到顯存中
I1 = gI1; //回傳, gI1.download(I1) 也可以
記住:一旦你的數據被傳到GPU顯存中,你就只能調用GPU函數來操作,大部分gpu函數名字與原來CPU名字保持一致,不同的是他們只接收 GpuMat 輸入。可以在: 在線文檔中找到一些說明,或者查閱OpenCV參考手冊。因爲大量的時間都耗費在傳輸數據到顯存這樣的步驟了,大量的計算時間被消耗在內存分配和傳輸上,GPU的高計算能力根本發揮不出來,我們可以利用 gpu::Stream 來進行異步傳輸,從而節約一些時間.
官網GPU文檔:https://docs.opencv.org/2.4/modules/gpu/doc/gpu.html
注意:GPU並不能對圖片的各種通道都能進行有效的處理。 GPU只接受通道數爲一或四的圖片,且數值類型爲char或float。GPU不接受double類型的圖片數據,否則會有異常拋出。對於三通道的圖片數據,要麼在圖片上再加一個通道變爲四通道(但這樣會比較消耗GPU內存不推薦);或者,將圖片按通道劃分成多個單通道圖片依次處理。若對於某些函數,圖片中元素的實際位置不影響處理,那麼比較好的處理辦法是將圖片直接轉爲單通道。
利用opencv gpu進行行人檢測部分c++代碼 如下:
Mat src=frame; // 內存對象,可以用imread來創建
cv::gpu::GpuMat Image_Src,Image_Dst;// GPU 矩陣 - 現在爲空
Image_Src.upload(src);//將內存數據上傳到顯存中
cv::gpu::cvtColor(Image_Src,Image_Dst,CV_BGR2GRAY);//轉換成單通道
vector<Rect> found, found_filtered;//矩形框數組
cv::gpu::HOGDescriptor myHOG; //設置HOGDescriptor的檢測子
myHOG.setSVMDetector(myDetector);
myHOG.detectMultiScale(Image_Dst, found);