1 #include<opencv2/opencv.hpp> 2 using namespace cv; 3 #include <numeric> // std::iota 4 5 const int g_num = 1000; 6 7 void my_test1(double* p_arr) 8 { 9 for (size_t i = 0; i < g_num; i++) 10 { 11 int p_arr_i = p_arr[i]; 12 for (size_t j = 0; j < g_num; j++) 13 { 14 double num1 = p_arr_i * (j > 10 ? 10 : j); 15 double num2 = std::pow(num1, 2); 16 double num3 = std::sqrt(num2); 17 p_arr[i] = num3; 18 p_arr[i] = p_arr_i * num3; 19 p_arr[i] = p_arr[i] / num3; 20 } 21 } 22 } 23 24 void my_test2(double* p_arr) 25 { 26 27 parallel_for_(Range(0, g_num), [&](const Range& r) 28 { 29 for (int oc = r.start; oc < r.end; oc++) 30 { 31 // 类似于核函数部分 32 int p_arr_i = p_arr[oc]; 33 for (size_t j = 0; j < g_num; j++) 34 { 35 double num1 = p_arr_i * (j > 10 ? 10 : j); 36 double num2 = std::pow(num1, 2); 37 double num3 = std::sqrt(num2); 38 p_arr[oc] = num3; 39 p_arr[oc] = p_arr_i * num3; 40 p_arr[oc] = p_arr[oc] / num3; 41 } 42 } 43 }); 44 } 45 46 int main() 47 { 48 double numbers[g_num]; 49 int st = 0; 50 std::iota(numbers, numbers + g_num, st); // 100 101 102 103 51 52 53 54 55 double t = (double)getTickCount(); 56 my_test1(numbers); 57 t = (double)getTickCount() - t; 58 59 double t2 = (double)getTickCount(); 60 my_test2(numbers); 61 t2 = (double)getTickCount() - t2; 62 63 printf("conv3x3 time = %.1fms\n", t * 1000 / getTickFrequency()); 64 printf("conv3x3_parallel time = %.1fms\n", t2 * 1000 / getTickFrequency()); 65 66 67 68 system("pause"); 69 return 0; 70 }
任务必须足够复杂再有加速效果,例如:每个像素+1这种简单的任务,还不如for循环单线程快
使用简单,无非就是把适合并行的“核函数”部分写到合适位置,例如:
parallel_for_(Range(0, g_num), [&](const Range& r) { for (int oc = r.start; oc < r.end; oc++) { // 类似于核函数部分 int p_arr_i = p_arr[oc]; for (size_t j = 0; j < g_num; j++) { double num1 = p_arr_i * (j > 10 ? 10 : j); double num2 = std::pow(num1, 2); double num3 = std::sqrt(num2); p_arr[oc] = num3; p_arr[oc] = p_arr_i * num3; p_arr[oc] = p_arr[oc] / num3; } } });
文心一言回答
opencv多线程
是的,OpenCV提供了多线程处理的API。从OpenCV 4.5版本开始,它引入了对C++11标准的并行算法的支持。这意味着你可以使用多线程来加速你的OpenCV代码。
在OpenCV中,你可以使用parallel::ThreadPool
类来创建和管理线程池。这个类提供了一种简单的方法来分配任务并在线程池中并行执行它们。
下面是一个简单的示例代码,演示了如何使用OpenCV的线程池:
cpp复制代码
1 #include <opencv2/opencv.hpp> 2 #include <opencv2/core.hpp> 3 #include <opencv2/highgui.hpp> 4 #include <opencv2/imgproc.hpp> 5 #include <opencv2/parallel/thread_pool.hpp> 6 7 using namespace cv; 8 using namespace cv::parallel; 9 10 int main() 11 { 12 // 创建一个线程池,包含4个线程 13 ThreadPool pool(4); 14 15 // 加载图像 16 Mat image = imread("example.jpg"); 17 18 if (image.empty()) { 19 std::cerr << "Could not load image file." << std::endl; 20 return -1; 21 } 22 23 // 将图像传递给线程池中的任务进行并行处理 24 pool.enqueueJob([&](int) { 25 // 在这里对图像进行处理,例如进行灰度转换 26 cvtColor(image, image, COLOR_BGR2GRAY); 27 }); 28 29 // 等待所有任务完成 30 pool.waitAll(); 31 32 // 显示处理后的图像 33 imshow("Processed Image", image); 34 waitKey(0); 35 36 return 0; 37 }
在上面的示例中,我们创建了一个包含4个线程的线程池,并将图像传递给线程池中的任务进行并行处理。每个任务对图像进行灰度转换操作。然后我们等待所有任务完成,并显示处理后的图像。
需要注意的是,多线程处理可能会引入一些额外的开销,包括线程创建和管理、数据同步等。因此,在使用多线程之前,你需要仔细评估你的应用场景和代码性能,并根据实际情况进行调整和优化。