C++:OpenCV 扫描图像的性能问题

标签 c++ performance image-processing opencv computer-vision

我有大约 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个像素对应于汽车等等,所以我只想在 map label_to_files_map中记录这个文件(当前图像是扫描)中有一座建筑物(在本例中由特定的 rgb 值表示)。

最佳答案

性能问题是每个像素做了太多工作。

对于每个文件(就在堆叠的 for 循环开始之前),创建 color_for_labels 的拷贝。

        Point3_<uchar> oldPixel;
        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);
                if(*pixel == oldPixel) 
                    continue; // skip extra work
                oldPixel = *pixel
                rgb.red = (int)pixel->z;
                rgb.green = (int)pixel->y;
                rgb.blue =(int)pixel->x;
                string label = copy_of_colors_for_labels[rgb];
                if(label != null) {
                    label_to_files_map[label].insert(file);
                    copy_of_colors_for_labels[rgb] = null;
                    cout << label << endl;
                }
            }
        }

可能存在语法错误(因为我在浏览器中重新编写了它,并且已经很多年没有用 C++ 进行编码了),但是上面的内容应该会消除很多额外的处理工作。

关于C++:OpenCV 扫描图像的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12804708/

相关文章:

c++ - Aero Snap 的无边框窗口在最大化状态下太大

c++ - 为什么我可以将函数引用分配给匿名函数指针变量?

visual-studio-2010 - C#字符串与std:string:传递字符串时出现问题

visual-studio-2010 - 如何找到单 channel 图像来运行 openCV 的方法 cvCanny

c++ - 信号未在此范围内声明/未定义对 class::method 的引用

c++ - 插入功能点到新数据

sql - Dateadd 如何影响 SQL 查询的性能?

performance - 如何查看 GPU 在复杂算法中的瓶颈?

performance - 胖域模型=>低效率?

python - 在python中将图像转换为矩阵