我有大约 20 张经过颜色编码的图像。我想扫描每个图像并将像素与与该颜色关联的标签匹配。我已经编写了下面的代码,但是运行这个看似简单的任务大约需要 30 分钟。图像的分辨率为 960 x 720。
我的代码:
void go_through_pixels(path &image_dir, string& ground_truth_suffix, string image_format, unordered_map<RGB, string> colors_for_labels){
if(!exists(image_dir)){
cerr << image_dir << " does not exist, prematurely returning" << endl;
exit(-1);
}
unordered_map<string, set<path> > label_to_files_map;
//initialise label_to_files_map
for(unordered_map<RGB, string>::iterator it = colors_for_labels.begin(); it != colors_for_labels.end(); it++){
label_to_files_map[it->second] = set<path>();
}
directory_iterator end_itr; //default construction provides an end reference
for(directory_iterator itr(image_dir); itr != end_itr; itr++){
path file = itr->path();
string filename = file.filename().string();
RGB rgb(0,0,0); //default rgb struct, values will be changed in the loop
if(extension(file) == image_format && filename.find(ground_truth_suffix) != string::npos){
//ground truth file
Mat img = imread(file.string(), CV_LOAD_IMAGE_COLOR);
for(int y = 0; y < img.rows; y++){
for(int x = 0; x < img.cols; x++){
//gives data as bgr instead of rgb
Point3_<uchar>* pixel = img.ptr<Point3_<uchar> >(y,x);
rgb.red = (int)pixel->z;
rgb.green = (int)pixel->y;
rgb.blue =(int)pixel->x;
string label = colors_for_labels[rgb];
label_to_files_map[label].insert(file);
cout << label << endl;
}
}
}
}
}
之后我会用这些数据做更多的事情,但我已经将我的代码简化到这个只是为了尝试找出性能问题。
我发现这label_to_files_map[label].insert(file)
是导致大部分延迟的原因,因为删除后只需扫描图像大约需要 3 分钟。我仍然认为这太长了,但可能是错的?
此外,由于该集合insert
需要很长时间(因为它必须在插入之前检查重复项),任何人都可以建议在这里使用更好的数据结构吗?
本质上,一张图片可以有 100 个像素对应于建筑物,100 个像素对应于汽车等等,所以我只想在地图label_to_files_map
中记录这个文件(正在扫描的当前图像)里面有一个建筑物(在这个case 由特定的 rgb 值表示)。