【问题标题】:Opencv hysteresis Thresholding ImplementationOpencv滞后阈值实现
【发布时间】:2019-04-19 23:45:50
【问题描述】:

我有从相位和幅度(单基因信号)计算的边缘的二进制图像,我想在 OpenCv 中应用滞后阈值。不幸的是,我无法将它用作在 opencv 库中的 Canny 边缘检测中实现的。我想知道是否有解决方法或简单的实现方法。

【问题讨论】:

  • 为什么不能用canny?
  • 我需要对比度不变的方法,像 canny 这样的基于梯度的边缘检测不适用于我的图像。
  • 您使用哪种语言?如果是python,你可以尝试使用scikit,它有hysteresis threshold as a function
  • @api55 我们正在用 C++ 开发
  • 我想你应该看看关于这个主题的研究论文,并尝试找出是否有人已经实现了它,如果没有,那么尝试自己实现它并附上问题本身的进展。

标签: opencv edge-detection


【解决方案1】:

我想出了这个解决方案:

Mat threshUpper, threshLower;
threshold(inImage, threshUpper, inThreshold, 128, CV_THRESH_BINARY);
threshold(inImage, threshLower, inThreshold-inHysteresis, 128, CV_THRESH_BINARY);

// Find the contours to get the seed from which starting floodfill
vector<vector<Point>> contoursUpper;
cv::findContours(threshUpper, contoursUpper, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

// Makes brighter the regions that contain a seed
for(auto cnt : contoursUpper){
    cv::floodFill(threshLower, cnt[0], 255, 0, 2, 2, CV_FLOODFILL_FIXED_RANGE);
}
//Threshold the image again to make black the not filled regions
threshold(threshLower, outImg, 200, 255, CV_THRESH_BINARY);

尽管如此,我仍在试图弄清楚为什么 Floodfill 在某些输入上花费大量时间(大约 1.5 秒)而在其他输入上(5 毫秒)平稳运行!

编辑:如果您不关心具有区域的二进制图像但您对轮廓属性感兴趣,则可以只拥有两个阈值图像并执行以下说明。有两种解决方案,一种保证滞后的正确性,但为 O(n^2),另一种用其边界框近似区域并运行在 O(n)

 vector<vector<Point>> contoursUpper, contoursLower;
 cv::findContours(threshUpper, contoursUpper, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
 cv::findContours(threshLower, contoursLower, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

 // Correct solution O(n^2)
 for(auto cntU : contoursUpper){
     for(auto cntL : contoursLower){
         if(cv::pointPolygonTest(cntL, cntU[0], false) >= 0){
             ///@todo: Do something with the cntL region (e.g. compute bounding box etc.)
             break; //Already found the connected region the others cannot be connected too
         }
     }
 }


// Approx. solution: O(n)
double minV, maxV;
for(auto cntL : largerContours){
    auto minBoundingBox = boundingRect(cntL);
    minMaxLoc(narrowThreshold(minBoundingBox), &minV, &maxV);
    if(maxV > 1){
        ///@todo: Do something with the cntL region (e.g. compute bounding box etc.)
    }
}

【讨论】:

  • 当 cnt[0] 的大小很大时(可能 findCountours() 在某些情况下被窃听)或向量未初始化时,floodFill 是否缓慢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
相关资源
最近更新 更多