【问题标题】:grass fire algorithm taking way too long, how to optimize?草火算法耗时太长,如何优化?
【发布时间】:2015-12-15 00:55:17
【问题描述】:

所以我正在使用 openCV 并尝试“从头开始”编写一堆算法,这样我就可以真正理解库在做什么。我编写了一个修改过的草火算法来从我已经数字化的图像中分割出 BLOB。但是,该算法需要 2 多分钟才能在我功能强大的笔记本电脑(16 gigs ram、四核 i7 等)上运行。我在这里做什么让它变得如此复杂?或者,是否有更好的算法从数字化图像中提取 BLOB? 谢谢!

这是算法

    std::vector<boundingBox> grassFire(cv::Mat digitalImage){
        std::vector<boundingBox> blobList;
        int minY, minX, maxY, maxX, area, yRadius, xRadius, xCenter, yCenter;
        for(int curRow = 0; curRow<digitalImage.rows; curRow++){
                for(int curCol = 0; curCol<digitalImage.cols; curCol++){
                       //if there is something at that spot in the image
                        if((int)digitalImage.at<unsigned char>(curRow, curCol)){
                                minY = curRow;
                                maxY = curRow;
                                minX = curCol;
                                maxX = curCol;
                                area = 0;
                                yRadius = 0;
                                xRadius = 0;
                                for(int fireRow=curRow; fireRow<digitalImage.rows; fireRow++){
                                        //is in keeps track of the row and started keeps track of the col
                                        //is in will break if no pixel in the row is part of the blob
                                        //started will break the inner loop if a nonpixel is reached AFTER a pixel is reached
                                        bool isIn = false;
                                        bool started = false;
                                        for(int fireCol = curCol; fireCol<digitalImage.cols; fireCol++){
                                                //make sure that the pixel is still in
                                                if((int)digitalImage.at<unsigned char>(fireRow, fireCol)){
                                                        //signal that an in pixel has been found
                                                        started = true;
                                                        //signal that the row is still in
                                                        isIn = true;
                                                        //add to the area
                                                        area++;
                                                        //reset the extrema variables
                                                        if(fireCol > maxX){maxX = fireCol;}
                                                        if(fireCol < minX){minX = fireCol;}
                                                        if(fireRow > maxY){maxY = fireRow;}
                                                        //no need to check min y since it is set already by the loop trigger

                                                        //set the checked pixel values to 0 to avoid double counting
                                                        digitalImage.at<unsigned char>(fireRow, fireCol) = 0;
                                                }
                                                //break if the next pixel is not in and youve already seen an in pixel
                                                //do nothing otherwise
                                                else{if(started){break;}}
                                                //if the entire blob has been detected
                                                if(!isIn){break;}
                                        }
                                }
                        }else{}//just continue the loop if the current pixel is not in 
                        //calculate all blob specific values for the blob at hand
                        xRadius =(int)((double)(maxX - minX)/2.);
                        yRadius =(int)((double)(maxY - minY)/2.);
                        xCenter = maxX - xRadius;
                        yCenter = maxY - yRadius;
                        //add the blob to the vector in the appropriate position (largest area first)
                        int pos = 0;
                        for(auto elem : blobList){
                                if(elem.getArea() > area){
                                        pos++;
                                }
                                else{break;}
                        }
                        blobList.insert(blobList.begin() + pos, boundingBox(area, xRadius, yRadius, xCenter, yCenter));
                }
        }

        return blobList;
}

【问题讨论】:

  • 您是否对代码运行了分析器?
  • @Borgleader 我对上述算法不熟悉,所以我不能肯定地告诉你......但是快速谷歌搜索让我相信这与楼梯算法不同。正如我在上面的描述中提到的,我最好将其描述为修改后的草火算法。
  • 你说just continue the loop if the current pixel is not in,但你没有在那里继续循环,而是通过将另一个元素添加到blobList的代码(该代码将在没有点亮的末尾访问元素满足该 for 循环中的条件)。
  • @Jarod42 我没有,因为我不知道存在这样的事情。在快速谷歌搜索后,我认为这是一个很棒的工具,当我开始使用更复杂的算法时,我真的需要学习它(这是我第一次遇到时间复杂度问题,通过代码审查)。您是否有一个特定的 c++ 分析器(对 ubuntu 友好或偏爱)您会推荐?
  • 没有理智的程序员愿意阅读这样的烂摊子。您可能想了解cyclomatic complexity 以及它如何与程序中的缺陷数量相关联。开始将代码拆分为函数,一切都会变得更好。

标签: c++ algorithm opencv time-complexity complexity-theory


【解决方案1】:

你说'如果当前像素不在其中就继续循环,但你不在那里继续循环,然后通过将另一个元素添加到 blobList 的代码(该代码将在 lit 结束后访问没有元素满足该 for 循环中的条件)。

使用这个

for(const auto &elem : blobList)

将避免复制所有这些边界框。

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多