Reputation: 41
i've searched a bit online and using the search here on stackoverflow but haven't found quite what i was looking for on this issue. So basicaly i'm using simple blob detection, from opencv, to get the white areas in my image(which is already binary) and in very similar images i get very diferent results in terms of which blobs are detected and which are not, here is an example followed by my parameters when defining simpleblobdetector.
As you can see some of the blobs are not beeing detected, here is my configuration of the detector:
void blobDetect(cv::Mat img) {
cv::SimpleBlobDetector::Params params;
if (Daytime) {
params.minThreshold = 23;
params.maxThreshold = 25;
}
else {
params.minThreshold = 3;
params.maxThreshold = 5;
}
params.thresholdStep = 1;
params.filterByColor = true;
params.blobColor = 255;
params.filterByArea = true;
params.minArea = 300;
params.maxArea = 400000;
params.filterByCircularity = false;
//params.minCircularity = "";
params.filterByConvexity = false;
//params.minConvexity = "";
params.filterByInertia = false;
//params.minInertiaRatio = "";
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params);
std::vector<cv::KeyPoint> keypoints;
detector->detect(img, keypoints);
cv::Mat im_with_keypoints;
std::cout << keypoints.size() << std::endl;
drawKeypoints(img, keypoints, im_with_keypoints, cv::Scalar(0, 0, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("display4", im_with_keypoints);
}
So i ask, is it because of the shape and size of the blobs?(i doubt this option since in some cases it can find big areas of wierd shapes) I thought simple blob detection could find any group of pixels, is it more apropriate for circular blobs or something like that? should i think about using another algorithm or building my own? or is there a way for me to get around this and increase the accuracy of simple blob detection?
I know those are a lot of questions, but thank you in advance for any help you can give!
Upvotes: 1
Views: 2722
Reputation: 41
Just like Alexander Reynolds sugested "Blob detector is pretty old OpenCV, why not find contours and sort by area?"
I used this link to get a starting point.
After having the contours of the image i use this: "if (cv::contourArea(contours[i]) > 500)" to threshold small areas and it works perfectly, plus it works much faster than blobdetection.
Again, Alexander, thank you very much for pointing me in the right direction :)
ps: as sugested, here is the full solution.
void findContours(cv::Mat img) {
// find contours:
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
// draw contours:
cv::Mat imgWithContours = cv::Mat::zeros(img.rows, img.cols, CV_8UC3);
cv::RNG rng(12345);
for (int i = 0; i < contours.size(); i++)
{
if (cv::contourArea(contours[i]) > 500) {
cv::Scalar color = cv::Scalar(rng.uniform(50, 255), rng.uniform(50, 255), rng.uniform(50, 255));
drawContours(imgWithContours, contours, i, color, 1, 8, hierarchy, 0);
}
}
imshow("display4", imgWithContours);
}
Upvotes: 2