簡體   English   中英

C ++:OpenCV性能問題掃描圖像

[英]C++: OpenCV performance issues scanning images

我大約有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值表示)。

性能問題是您在每個像素上做太多的工作。

對於每個文件(恰好在堆積的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 ++編寫代碼了),但是以上內容應該消除了很多額外的處理工作。

您使用了錯誤的數據類型和錯誤的函數。 這是關於如何改進的建議。 我想它將在幾秒鍾內運行。

工作的第一步是從3通道圖像到單通道圖像的查找表。 您可以使用cv :: LUT。 但是,您需要技巧以使其快速。

將其轉換為每個像素4個字節:

cv::Mat mat4bytes;
// add 8 bits to each pixel. the fill value is 255
cv::cvtColor(img, mat4bytes, CV_RGB2RGBA); 
// this is a nice hack to interpret 
// the RGBA pixels of the input image as integers 
cv::Mat pseudoInteger(img.size(), CV_32UC1, mat4bytes.data);

現在,您可以應用LUT。

cv::Mat colorCoded;
// you have to convert your colors_for_labels lookup table
// like this: 
lookupTable[i] = 
      ((unsigned int)colors_for_labels.first.x << 24 ) + 
      ((unsigned int)colors_for_labels.first.y << 16 ) +        
      ((unsigned int)colors_for_labels.first.z << 8  ) +        
      255; 
// make sure it is correct!!!
// and lookupTable data MUST be unsigned integer

cv::LUT(pseudoInteger, colorCoded, lookupTable);

編輯此時,您在lookupTable中具有在label計算的值

計算的最后一步實際上是直方圖。 那么,為什么不使用OpenCV的直方圖功能呢? 檢查calcHist()的文檔,並查看它如何最適合您的算法。 請注意, calcHist()可以一次執行更多圖像的直方圖,因此您可能希望將colorCoded圖像保留在矢量中,然后將所有圖像的直方圖提取為一個。

除其他有關代碼優化的答案外,請考慮處理圖像直方圖。 圖像中的幾個像素將具有完全相同的顏色,因此請首先計算直方圖,然后對圖像中的每種不同顏色進行處理。 那應該大大加快速度

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM