色分けされた約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
このファイル (スキャンされている現在の画像) に建物が含まれていることをマップに記録したいだけです (このケースは特定の RGB 値で示されます)。