I came up with this solution:
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);
Nevertheless, I am still trying to figure out why floodfill takes a lot of time (about 1.5sec) on some input and run smoothly on others (5 millisec)!
EDIT: If you do not care of having a binary image with the regions but you are interested in the contours property you can just have the two thresholded images and perform the following instructions. There are two solutions, one guarantee the hysteresis correctness but is O(n^2) the other approximate the region with its bounding box and run in 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.)
}
}