Opencv双阈值处理实现

4

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


为什么你不能使用Canny算法? - Miki
我需要对比不变的方法,像Canny这样的基于梯度的边缘检测方法无法处理我的图像。 - aditya sai
你使用的是哪种编程语言?如果是Python,你可以尝试使用Scikit,它具有作为函数的滞后阈值。详情请见:http://scikit-image.org/docs/dev/auto_examples/filters/plot_hysteresis.html - api55
@api55 我们正在使用C++进行开发。 - giuseppe
我猜你应该寻找一篇关于这个主题的研究论文,并尝试查找是否已经有人实现了它,如果没有,那么尝试自己实现并将进展与问题本身联系起来。 - ZdaR
1个回答

0
我想出了这个解决方案:
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);

不过,我仍在努力弄清楚为什么某些输入时洪水填充需要很长时间(约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是否会变慢? - koe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接