OpenCV使用ParallelLoopBody進行平行計算
環境:Windows 10 x64, VS2017 x64, OpenCV 4.3.0 x64
步驟:
1,宣告一個 ParallelLoopBody 的子類(取名為FillParallel),並實現其純虛擬函式 virtual void operator() (const Range& range) const的功能;
2,例項化子類(FillParallel)的物件(取名為 fill) ;
3,呼叫 cv::parallel_for_()方式進行平行計算。
詳細與程式碼:
step 1:
// Step 1: 宣告 ParallelLoopBody 的一個子類,取名為 FillParallel (並行填充顏色)
class FillParallel : public cv::ParallelLoopBody {
public:
// 通過建構函式進行填充引數(填充影像,填充區域,顏色等)的設定
FillParallel(cv::Mat& image, const std::vector<cv::Rect>& rects, const std::vector<cv::Scalar>& colors) {
_image = image;
_rects = rects;
_colors = colors;
}
// OpenCV 平行計算的內部呼叫介面約定
// 【重點】實現此介面的功能
virtual void operator() (const cv::Range& range) const {
for (int i = range.start; i < range.end; ++i) {
_image(_rects[i]).setTo(_colors[i]);
printf("curr thread: %d, all %d.\r\n", cv::getThreadNum(), cv::getNumThreads());
}
}
// 填充引數
private:
mutable cv::Mat _image; // 此處關注 mutable 關鍵字
std::vector<cv::Rect> _rects;
std::vector<cv::Scalar> _colors;
};
step 2:
// Step 2: 例項化子類(FillParallel)的物件(取名為 fill) ;
FillParallel fill(image, vec_rects, vec_colors);
step 3:
// Step 3: 呼叫 cv::parallel_for_()方式進行平行計算。
cv::parallel_for_(cv::Range(0, vec_rects.size()), fill);
完整程式碼;
// Mylaf
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#define TICK2TIME(tick) ((tick)*1000/cv::getTickFrequency())
bool SubRectangle(std::vector<cv::Rect> & rects,
int width, int height, // 大區域的尺寸
int subwidth, int subheight, // 子區域的尺寸
int stepx, int stepy, // 子區域間的步進
int offx = 0, int offy = 0) { // 子區域左上點偏移
//
for (int y = 0; y < height; y += stepy) {
for (int x = 0; x < width; x += stepx) {
rects.emplace_back(x + offx, y + offy, subwidth, subheight);
if (x + subwidth >= width) break;
}
if (y + subheight >= height) break;
}
return true;
}
// Step 1: 宣告 ParallelLoopBody 的一個子類,取名為 FillParallel (並行填充顏色)
class FillParallel : public cv::ParallelLoopBody {
public:
// 通過建構函式進行填充引數(填充影像,填充區域,顏色等)的設定
FillParallel(cv::Mat& image, const std::vector<cv::Rect>& rects, const std::vector<cv::Scalar>& colors) {
_image = image;
_rects = rects;
_colors = colors;
}
// OpenCV 平行計算的內部呼叫介面約定
// 【重點】實現此介面的功能
// 本填充的range=填充區域(顏色)的個數, 見Step 3中的range
virtual void operator() (const cv::Range& range) const {
for (int i = range.start; i < range.end; ++i) {
_image(_rects[i]).setTo(_colors[i]);
printf("curr thread: %d, all %d.\r\n", cv::getThreadNum(), cv::getNumThreads());
}
}
// 填充引數
private:
mutable cv::Mat _image; // 此處關注 mutable 關鍵字
std::vector<cv::Rect> _rects;
std::vector<cv::Scalar> _colors;
};
void Test0001() {
cv::Mat image = cv::Mat::zeros(8000, 12000, CV_8UC3);
// 劃分不同的填充區域和顏色
std::vector<cv::Rect> vec_rects;
ocv_geom::SubRectangle(vec_rects,
image.cols, image.rows,
100, 100, 100, 100);
std::cout << "subrect size=" << vec_rects.size() << std::endl;
std::vector<cv::Scalar> vec_colors(vec_rects.size());
for (int i = 0; i < vec_colors.size(); ++i) {
vec_colors[i][0] = (32 * i) & 0xFF;
vec_colors[i][1] = (48 * (i + 1)) & 0xFF;
vec_colors[i][2] = 255 - MIN(vec_colors[i][0], vec_colors[i][1]);
}
// Step 2: 例項化子類(FillParallel)的物件(取名為 fill) ;
FillParallel fill(image, vec_rects, vec_colors);
double tick = cv::getTickCount();
for (int i = 0; i < vec_colors.size(); ++i) {
image(vec_rects[i]).setTo(vec_colors[i]);
}
tick = cv::getTickCount() - tick;
std::cout << "0 time: " << TICK2TIME(tick) << " ms." << std::endl;
tick = cv::getTickCount();
// Step 3: 呼叫 cv::parallel_for_()方式進行平行計算。
cv::parallel_for_(cv::Range(0, vec_rects.size()), fill);
tick = cv::getTickCount() - tick;
std::cout << "1 time: " << TICK2TIME(tick) << " ms." << std::endl;
cv::imwrite("image.png", image);
}
// mylaf unit test entry-point
int main(int argc, const char* argv[]) {
Test0001();
//
return 0;
}
圖片:
Mylaf
廈門 2020-12-09 0020
相關文章
- 使用 QuTrunk+Amazon ParallelCluster3 進行平行計算Parallel
- 淺談.NET下的多執行緒和平行計算(十四)平行計算前言執行緒
- 平行計算π值
- Oracle平行計算Oracle
- 平行計算cuda
- GPU:平行計算利器GPU
- 推薦文章:多執行緒平行計算執行緒
- [索引]Oracle RAC資料庫平行計算的使用索引Oracle資料庫
- .NET4.0平行計算技術基礎(2)
- .NET4.0平行計算技術基礎(1)
- 在vim中使用bc進行算術計算
- Java執行緒(十一):Fork/Join-Java平行計算框架Java執行緒框架
- 雲端計算分散式平行計算:系統架構分散式架構
- iOS下使用OpenCV進行影象識別iOSOpenCV
- 大文字平行計算實現方式
- wxPython使用delayedresult進行耗時計算Python
- 世界是並行的:平行計算的機遇與挑戰並行
- 完數的Java多執行緒並行程式設計-平行計算Java執行緒並行行程程式設計
- 談談如何使用 opencv 進行影像識別OpenCV
- iOS中使用opencv進行影象識別操作iOSOpenCV
- PostgreSQL11preview-ParallelAppend(多表平行計算)sharding架構平行計算核心功能之一SQLViewParallelAPP架構
- 瞭解Flow -- elixir的平行計算庫
- 引文——平行計算的學習之殤
- 多核平行計算時代的來臨
- 請問,平行計算和資料庫資料庫
- 後端請求中的非同步計算與平行計算後端非同步
- .NET並行程式設計實踐(一:.NET平行計算基本介紹、並行迴圈使用模式)並行行程程式設計模式
- 黃仁勳:序列計算過時平行計算是未來
- [原始碼解析] PyTorch 流水線並行實現 (6)--平行計算原始碼PyTorch並行
- opencv使用convexityDefects計算輪廓凸缺陷OpenCV
- 使用位運算進行加法運算
- [930]python平行計算框架pathos模組Python框架
- 【1】Embarrassingly Parallel(易平行計算問題)Parallel
- 大資料平行計算利器之MPI/OpenMP大資料
- JDK7的平行計算功能升級JDK
- HPC高效能運算知識: 異構平行計算
- 完數的OpenMP並行程式設計-平行計算並行行程程式設計
- 完數的MPI並行程式設計-平行計算並行行程程式設計