日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【OpenCV开发】使用OpenCV的OpenCL(ocl)模块

發布時間:2024/9/5 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OpenCV开发】使用OpenCV的OpenCL(ocl)模块 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


參加OpenCV的OpenCL模塊(以下稱OCL)移植工作已經有2個月了。這里我說移植而不是開發,是因為大部分OCL模塊的函數都是從已經很成熟的GPU模塊移植過來的。于是目前階段OCL模塊所支持的函數接口只是GPU模塊的一個子集。


OpenCV的版本控制系統已經轉移到了git上面(見https://github.com/itseez/opencv),最新的trunk的master分支正式加入了OCL模塊。今天逛OpenCV的開發者社區,我發現有人提問在OpenCV庫中如何進行使用OCL模塊的函數;回答問題的同時,由于網上還沒有針對OpenCV的OCL模塊的資料,我決定寫一篇文章簡單介紹下OCL模塊以方便開發者使用。



Introduction to OpenCL


對于OpenCL已經有所了解的,可以直接跳過這一節。

"OpenCL是用于編寫在異構平臺上運行程序的框架,所謂異構平臺,一般情況我們指GPU和CPU兩種處理器混合的平臺。OpenCL由一門用于編寫kernels (在OpenCL設備上運行的函數)的語言(基于C99)和一組用于定義并控制平臺的API組成。"?
OpenCL可以實現GPGPU(General-purpose computing on graphics processing units, 通用圖形處理器)運算, "是一種利用處理圖形任務的GPU來計算原本由CPU處理的通用計算任務。這些通用計算常常與圖形處理沒有任何關系。由于現代圖形處理器強大的并行處理能力和可編程流水線,令流處理器可以處理非圖形數據。特別在面對單指令流多數據流(SIMD),且數據處理的運算量遠大于數據調度和傳輸的需要時,通用圖形處理器在性能上大大超越了傳統的中央處理器應用程序。" -- 摘自wikipedia


簡單解釋一下這段話中幾個重點:

利用GPU強大的并行能力代替CPU進行運算
GPU的并行能力特別適合于關于矩陣的運算。利用GPU,我們可以發起很多個輕量級線程,每個線程僅處理一個元素的計算來實現數據并行;而對于CPU,我們只能按順序每個元素迭代運算。GPU和CPU運算對比起來可以想象成4輛坦克與1萬個士兵的戰斗力水平的對比;孰勝孰劣,還要看具體進行的任務。因此,并不是所有的OpenCV函數都適合移植到GPU上進行運算。


OpenCL由在OpenCL設備上運行的kernel函數語言和控制平臺的API組成
OpenCL包含兩個主要部分:device和host。在CPU和GPU組成的異構平臺中,我們一般把運行核函數的GPU處理器部分稱為device,把控制平臺API的CPU稱為host。相應的,把host上的內存(就是內存)稱為host memory;而把device上的內存(GPU顯存)稱為device memory或者device buffer。在OpenCV里,我們把這兩種內存封裝為cv::Mat和cv::ocl::oclMat結構。


數據調度和傳輸
OpenCV的OCL模塊中,在GPU上進行運算之前我們必須把內存轉成GPU可以直接調用的顯存。而在GPU上的運算結束后,我們還需要將在GPU顯存上的數據轉移到CPU可用的內存上。這兩個操作在oclMat中定義為兩個成員函數,分別為oclMat::download和oclMat::upload。由于這兩個數據傳輸操作受PCI總線寬帶的限制,在實際應用中應盡量減少數據傳輸,把盡可能多的運算在gpu device上計算完成后,再把數據傳回cpu host,以達到最大的數據吞吐量。


OpenCV's CUDA Module

介紹OpenCL模塊前,不得不先提一下OpenCV的GPU(以下特指CUDA模塊)模塊。由于OCL模塊是直接移植自GPU的代碼,所以我們可以先來了解下他的前身。

來源:http://opencv.org/platforms/cuda.html

歷史

GPU模塊最初由NVIDIA公司在2010年起支持開發,2011年春發布了第一個帶有GPU模塊的OpenCV版本。GPU模塊包含并加速了很大一部分原先只能運行在CPU設備上的庫函數,并且隨著新的計算技術和GPU架構不斷發展和更新。

目標

?

  • 為開發者提供一個便于使用CUDA的計算機視覺框架,同時在概念上保持了當前的CPU的功能性。
  • 把用最高效的方式優化GPU模塊函數作為目標。這些優化方法包含:適應最新的硬件架構;非同步模式核函數執行;重疊式拷貝和零拷貝等。
  • 功能完整性。意思就是說即使有些函數性能并沒有提高的情況下,盡可能的把CPU模塊函數移植到GPU上去做,以減少數據傳輸產生的延遲。
  • ?

    性能


    模塊設計

    OpenCV的GPU模塊還加入了CUDA第三方函數的支持,如NVIDIA NPP和CUFFT。(相應的,OCL模塊也加入了AMD提供的amdBlas和amdFft庫)

    GPU模塊被設計成host上能調用的CUDA API擴展集。這個設計模式讓開發者能明確的控制數據在CPU和GPU的內存間的傳輸。盡管用戶必須要多寫一點代碼來開始使用GPU模塊,但是這個過程是靈活的,并且允許用戶對GPU數據控制的代碼進行優化。

    GPU模塊的gpu::GpuMat類是一個封裝了儲存在在GPU顯存的容器,而他的接口與CPU的cv::Mat類非常相似。所有的GPU模塊函數以GpuMat作為輸入輸出函數,這樣的設計允許多個GPU算法在數據不下載到CPU內存就能完全調用,增加了數據吞吐效率。并且GPU函數接口也盡可能的和CPU函數保持移植,這樣熟悉OpenCV CPU操作的開發者能直接轉移到GPU模塊上進行開發。


    由于OpenCL的開發模式與CUDA非常類似,包括host API和device上運行的核函數語法,所以移植工作并不困難。移植過程中,我們保持了GPU模塊的設計理念,并且在保證代碼質量的基礎上,盡可能的讓OCL模塊的函數跟上GPU模塊的更新節奏。


    -----------------------------------------------------------------------------------

    Compile Latest OpenCV trunk repository

    以下以windows 7 32bit + visual studio 2010 + AMD顯卡為例。

    由于ocl模塊剛剛加入OpenCV的主版本,用戶想要基于ocl開發的話,需要從OpenCV的git服務器上pull一下最新trunk repository的OpenCV代碼。git地址如下:
    git://code.opencv.org/opencv.git
    或者github的鏡像
    https://github.com/itseez/opencv

    下載完成后,你還需要一個新的OpenCL SDK。以AMD顯卡系列為例,APP SDK v2.7下載地址http://developer.amd.com/sdks/amdappsdk/downloads/pages/default.aspx

    你還需要CMake2.8版本來生成Visual Studio的sln項目。cmake的使用方法就不多說了,網上有很詳細的教程。

    應注意的是在用CMake對OpenCV項目進行配置時,要手動打開WITH_OPENCL選項,這個是默認關閉的。如果一切正常的話,在CMake的命令行輸出終究會提示找到OpenCL的靜態庫和include文件夾;如果提示沒有找到的話,需要自己手動在cmake中找到這兩個選項,添加include文件夾和動態庫路徑。

    上面步驟完成后,就可以打開OpenCL.sln文件編譯OpenCV了~



    Using OCL module

    使用ocl模塊的方法跟gpu非常類似(本來就是無腦無縫移植什么的)。調用ocl模塊的任何模塊前,必須明確的調用一下ocl名字空間下的getDevice函數。

    [cpp]?view plaincopy
  • vector<ocl::Info>?info;??
  • ocl::getDevice(info);??
  • getDevice函數會在你電腦中尋找是否有合適的含有GPU的OpenCL平臺,并且返回可用的device設備數量,并生成并注冊可用的上下文(cl_context)和一個命令執行隊列。
    上文提到,所有的ocl模塊調用的矩陣類型格式是oclMat。oclMat跟Mat結構類似,包含大部分的成員函數和成員變量,但是最重要的是封裝了OpenCL的buffer數據(cl_mem)并控制他的內存釋放與傳輸。
    把一個Mat轉化成oclMat非常簡單,你可以調用oclMat的構造函數:
    [cpp]?view plaincopy
  • oclMat?myOclMat(mat);?//?mat?is?a?Mat?object??
  • oclMat的構造函數會自動復制據Mat的矩陣頭,如列、行數,元素類型,通道數等等,并且隱式的把cpu host上的內存轉移到gpu device的顯存上。如果用戶想顯示的轉移(或者稱為“上傳”),可以調用:
    [cpp]?view plaincopy
  • oclMat?myOclMat;??
  • myOclMat.upload(mat);??
  • 這樣我們就有了一個上傳到device上的oclMat矩陣。這個矩陣數據就可以傳遞給ocl模塊的函數,進行你所需要的運算。但是由于oclMat矩陣的數據是儲存在gpu顯存上的,我們在host(cpp文件中)是不能直接去取值的。如果計算完畢后,我們想取得oclMat的結果,需要把在顯存上的oclMat數據轉移成Mat格式,這個操作叫做”下載”。跟上傳類似,我們也有隱式和顯示兩種方法:
    [cpp]?view plaincopy
  • mat?=?Mat(myOclMat);??
  • [cpp]?view plaincopy
  • myOclMat.download(mat);???
  • 一般情況下,你不必擔心oclMat數據的釋放問題,因為在oclMat被解體的時候,會自動調用數據的釋放。

    概括地說,使用ocl模塊有這么幾個過程:

    ?

  • 注冊全局OpenCL設備。 //調用getDevice
  • 把內存的數據上傳到顯存。//把Mat轉化成oclMat
  • 在OpenCL設備上進行計算。//調用ocl模塊函數
  • 把顯存的數據下載到內存。//把oclMat轉化成Mat
  • 在host上進行剩余的運算。//調用cv::函數
  • PS
    下載到的OpenCV的trunk代碼中包含了幾個OpenCL的sample程序可以作為開發者的參考。

    謝謝閱讀~
    鵬?
    August 19, 2012
    【原文地址】http://blog.csdn.net/pengx17/article/details/7880642

    轉載于:https://www.cnblogs.com/huty/p/8517556.html

    總結

    以上是生活随笔為你收集整理的【OpenCV开发】使用OpenCV的OpenCL(ocl)模块的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。