Opencv hysteresis阈值实现

问题描述 投票:4回答:1

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

opencv edge-detection
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.)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.