草火算法耗时太长,如何优化?
grass fire algorithm taking way too long, how to optimize?
所以我正在使用 openCV 并尝试编写一堆算法 "from scratch" 可以这么说,这样我才能真正理解库在做什么。我编写了一个修改过的草火算法来从我已经数字化的图像中分割 BLOB。但是,该算法在我功能强大的笔记本电脑(16 gigs ram,四核 i7 等...)上需要 2 分钟以上才能 运行。我在这里做什么让它变得如此复杂?或者,是否有更好的算法从数字化图像中提取 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;
}
你说`如果当前像素不在则继续循环,但你不在那里继续循环,然后转到将另一个元素添加到 blobList 的代码(该代码将在没有元素的点亮满足那个for循环中的条件)。
并使用这个
for(const auto &elem : blobList)
将避免复制所有这些边界框。
所以我正在使用 openCV 并尝试编写一堆算法 "from scratch" 可以这么说,这样我才能真正理解库在做什么。我编写了一个修改过的草火算法来从我已经数字化的图像中分割 BLOB。但是,该算法在我功能强大的笔记本电脑(16 gigs ram,四核 i7 等...)上需要 2 分钟以上才能 运行。我在这里做什么让它变得如此复杂?或者,是否有更好的算法从数字化图像中提取 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;
}
你说`如果当前像素不在则继续循环,但你不在那里继续循环,然后转到将另一个元素添加到 blobList 的代码(该代码将在没有元素的点亮满足那个for循环中的条件)。
并使用这个
for(const auto &elem : blobList)
将避免复制所有这些边界框。