我有这个功能从数据集读取负图像(约122000)
void load_images(const String & dirname, vector< Mat > & img_lst, bool showImages = false)
{
vector< String > files;
glob(dirname, files);
for (size_t i = 0; i < files.size(); ++i)
{
Mat img = imread(files[i]); // preia imagine
if (img.empty()) // treci peste daca este imagine invalida
{
cout << files[i] << " is invalid!" << endl;
continue;
}
if (showImages)
{
imshow("image", img);
waitKey(1);
}
img_lst.push_back(img);
}
}
并且需要花费大量时间来处理,有时会被阻止。 如何优化它并使其并行?
答案 0 :(得分:2)
我稍微改变了你的代码以使用OpenMP来并行加载 - 实际的更改是最小的 - 我只是在pragma
循环之前放置了一个OpenMP for
并且序列化了对图像矢量的访问权限向量不是线程安全的。
#include <iostream>
#include <vector>
#include <mutex>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void load_images(int start,int end){
vector<Mat>img_lst;
mutex mtx;
#pragma omp parallel for
for(size_t i=start;i<=end;i++){
char filename[16];
sprintf(filename,"%d.jpg",i);
Mat img = imread(filename);
if (img.empty()){
cerr << "ERROR: Failed to load " << filename << endl;
}
mtx.lock();
img_lst.push_back(img);
mtx.unlock();
}
mtx.lock();
cout << "INFO: Loaded " << img_lst.size() << endl;
mtx.unlock();
}
int
main(int argc,char*argv[])
{
load_images(1,122000);
}
您可以像这样控制线程数:
export OMP_NUM_THREADS=2
time ./main
根据我使用的线程数量,加载122,000张图像的时间根据下表而变化:
Threads Time (s)
================
1 44
2 23
4 12.4
8 8.8
然后我决定,如果你这样做经常足以照顾,你可能会想要预先支付一小笔费用来进一步改善时间。因此,您可能希望将图像转换为更简单的读取格式(例如PNM),而不是执行所有CPU密集型代码来解压缩JPEG。因此,我使用 GNU Parallel 将所有JPEG图像转换为PNM,然后加载PNM图像:
所以看起来像:
seq 122000 | parallel convert {}.jpg {}.pnm
代码是:
...
...
#pragma omp parallel for
for(size_t i=start;i<=end;i++){
char filename[16];
sprintf(filename,"%d.pnm",i); <--- ONLY LINE CHANGED
Mat img = imread(filename);
...
...
你可以看到时间相当短:
Nthreads Time(s)
================
1 7
2 4
4 2.5
8 3.2
要使用OpenMP进行编译,请使用:
g++ -fopenmp =O3 -march native ...
答案 1 :(得分:1)
你可以试试这个
PyQt
对它进行了简要测试,但它应该可以读取4个线程的图像。