<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 獨家|OpenCV1.9 如何利用OpenCV的parallel_for_并行化代碼(附代碼)

獨家|OpenCV1.9 如何利用OpenCV的parallel_for_并行化代碼(附代碼)

發(fā)布人:數據派THU 時(shí)間:2021-08-20 來(lái)源:工程師 發(fā)布文章

目標

本教程的目標是展示如何使用OpenCV的parallel_for_框架輕松實(shí)現代碼并行化。為了說(shuō)明這個(gè)概念,我們將編寫(xiě)一個(gè)程序,利用幾乎所有的CPU負載來(lái)繪制Mandelbrot集合。完整的教程代碼可見(jiàn)原文。如果想了解更多關(guān)于多線(xiàn)程的信息,請參考本教程中提及的參考書(shū)或課程。

預備條件

首先是搭建OpenCV并行框架。在OpenCV3.2中,可以按此順序使用以下并行框架:

1. 英特爾線(xiàn)程構建模塊(第三方庫,應該明確啟用)

2. C =并行C / C ++編程語(yǔ)言擴展(第三方庫,應該明確啟用)

3. OpenMP(集成的編譯器,應明確啟用)

4. APPLE GCD(系統層面,自動(dòng)使用(僅適用APPLE))

5. Windows RT并發(fā)(系統層面,自動(dòng)使用(僅適用Windows RT))

6. Windows并發(fā)(部分運行時(shí)間,自動(dòng)使用(僅適用Windows  -  MSVC ++> = 10))

7. Pthreads (如果適用)

正如前面所述,OpenCV庫可以使用多個(gè)并行框架。有些并行庫為第三方提供的庫,建立時(shí)應明確地用CMake(如TBB,C =)啟用,其余均為自動(dòng)可用的平臺(例如APPLE GCD),但是,無(wú)論是直接使用并行框架還是利用CMake啟用并行框架并重建庫,首先要做的是啟用并行框架。

第二個(gè)(弱)預備條件與任務(wù)相關(guān),因為不是所有任務(wù)的計算都可以/適合以并行方式來(lái)運行。為了盡量保持簡(jiǎn)單,可以將任務(wù)分解為與存儲器無(wú)關(guān)的多個(gè)元素,從而使其更加容易實(shí)現并行化。在計算機視覺(jué)處理過(guò)程中,由于大多數時(shí)間里一個(gè)像素的處理不依賴(lài)于其它像素的狀態(tài),所以往往更加容易實(shí)現并行化。

簡(jiǎn)單的示例:繪制Mandelbrot集合

這個(gè)例子中將展示如何繪制Mandelbrot集合,將普通的順序代碼實(shí)現并行化計算。

理論

Mandelbrot集合的名稱(chēng)是數學(xué)家阿德里恩·多迪(Adrien Douady)為悼念數學(xué)家蒙德布羅特(Mandelbrot),以他的名字來(lái)命名的。它在數學(xué)界之外,作為分形類(lèi)的一個(gè)例子,在圖像表示領(lǐng)域非常著(zhù)名。Mandelbrot集合為一組自相似的重復圖案在不同尺度下重復顯示結果。為了進(jìn)一步深入介紹,可以參考Wikipedia article。在這里,僅介紹利用公式繪制Mandelbrot集合(選自維基百科的文章)。

Mandelbrot集合是在復平面中一組值C沿著(zhù)0軌跡的二次迭代映射的邊界。

1.png

即,復數c作為Mandelbrot集的一部分,從 Z0 = 0開(kāi)始重復進(jìn)行迭代,當n趨近于無(wú)窮大時(shí),Zn的絕對值的邊界值,它可以表示為:

2.png

偽代碼

生成Mandelbrot集合的簡(jiǎn)單的算法被稱(chēng)為“逃逸時(shí)間算法”。為渲染圖像中的每個(gè)像素,根據復數值是否在邊界范圍之內,利用遞推關(guān)系進(jìn)行測試。經(jīng)過(guò)數次迭代之后,不屬于Mandelbrot集合的像素將快速逃逸,留下來(lái)的將是屬于Mandelbrot集合的像素。隨著(zhù)計算時(shí)間的增加,迭代后的高階值將產(chǎn)生一個(gè)更詳細的圖像。在這里使用實(shí)現“逃逸”所需要的迭代次數來(lái)描繪圖像中的像素值。

3.png

將偽代碼和理論相關(guān)聯(lián)之后,得到:

4.png

在上圖中,復數的實(shí)部在x軸上,復數的虛部在y軸上。通過(guò)對圖形局部放大,可以看到整個(gè)形狀均重復可見(jiàn)。

代碼實(shí)現

逃逸時(shí)間算法的實(shí)現

5.png

在這里,我們使用了std::complex模板類(lèi)來(lái)表示復數。利用這個(gè)函數來(lái)進(jìn)行測試,以檢查像素是否在集合之中,并返回“逃逸”迭代。

順序的Mandelbrot實(shí)現

6.png

在此程序中,通過(guò)依次遍歷渲染圖像中的像素來(lái)進(jìn)行測試,以檢查像素是否屬于Mandelbrot集合。

需要做的另一件事是把像素坐標轉換Mandelbrot集合空間:

7.png

最后,將灰度值分配給像素,使用以下規則:

當迭代次數達到最大值時(shí),像素為黑色(假定像素在Mandelbrot集合中);

否則根據逃脫“逃逸迭代”和縮放尺度,為像素分配一個(gè)灰度值,以適應灰度范圍。

8.png

使用線(xiàn)性縮放轉換不足以感知的灰度變化。為了克服這個(gè)問(wèn)題,使用一個(gè)平方根轉換來(lái)提升感知度(引用了Jeremy D. Frens博客中的內容): 9.png

10.png

綠色曲線(xiàn)對應于簡(jiǎn)單的線(xiàn)性縮放轉換,藍色曲線(xiàn)對應于平方根轉換,可以從中觀(guān)察到的最低值如何沿著(zhù)斜坡正向上升。

并行Mandelbrot實(shí)現

在順序的Mandelbrot實(shí)現中,每個(gè)像素被獨立計算。為了優(yōu)化計算,我們可以利用現代處理器的多核架構并行執行多個(gè)像素的計算,利用OpenCV的CV :: parallel_for_框架可以輕松實(shí)現。

11.png

第一件事是聲明一個(gè)繼承CV :: ParallelLoopBody的自定義類(lèi),覆蓋virtual void operator ()(const cv::Range& range) const。

 operator ()表示將通過(guò)一個(gè)獨立的線(xiàn)程來(lái)處理像素的子集,這種拆分是自動(dòng)完成的,以平均分配計算負荷,為此必須將像素索引坐標轉換成2D [行,列]坐標。還要注意的是,必須保持圖像的mat對象引用值,以便能夠適時(shí)地對圖像進(jìn)行修改。

調用并行執行程序:

12.png

在這里,range表示將要執行的操作總數,即圖像中的像素總數。使用CV :: setNumThreads設置線(xiàn)程數,還可以使用CV :: parallel_for_中的 nstripes參數指定拆分的數量CV :: parallel_for_。例如,如果處理器有4個(gè)線(xiàn)程,則設置CV :: setNumThreads(2)或者設置nstripes = 2應該是一樣的,默認情況下它會(huì )使用所有可用的處理器線(xiàn)程,但拆分后只有兩個(gè)線(xiàn)程。

為了簡(jiǎn)化并行的實(shí)現,C ++ 11標準刪除了ParallelMandelbrot類(lèi),采用lambda表達式代替它:

13.png

運行結果

可以在原文找到完整的教程源代碼,并行實(shí)現的性能取決于CPU的種型。例如,在4核/ 8線(xiàn)程的CPU上,可以提速6.9倍左右。如果要問(wèn),為什么達不到8倍速,其中有很多因素;主要原因是由于:

創(chuàng )建和管理線(xiàn)程的額外開(kāi)銷(xiāo);

并行運行的后臺進(jìn)程;

帶2個(gè)邏輯線(xiàn)程的4硬件核與8硬件核之間是有區別的。

由教程代碼生成的輸出圖像(可以對代碼進(jìn)行修改,以使用更多次的迭代,根據逃逸迭代次數來(lái)分配像素顏色,并使用調色板以獲得更美的圖像):

14.png

Mandelbrot集合XMIN = -2.1,XMAX = 0.6,YMIN = -1.2,YMAX = 1.2,maxIterations = 500

原文鏈接:

https://docs.opencv.org/4.5.2/d7/dff/tutorial_how_to_use_OpenCV_parallel_for_.html

*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>