I am looking into detecting slightly bright areas (fawns from the roe deer) in thermal images with openCV.
So far I managed to get some code that works somehow, but with to many false negatives and false positives.
I basically know my way around openCV. But from the algorithmic side I a not sure what the best solution should be to result in a most perfect detection.
So far I use a cascade of something like this
- gaussion blur
- some sore of hysteresis thesholding
- blob detection
Code snipped:
cv::GaussianBlur(gray, gray, cv::Size(gauss_size, gauss_size), 0);
Mat threshUpper, threshLower;
threshold(gray, threshUpper, mask_min, mask_max, cv::THRESH_BINARY);
threshold(gray, threshLower, mask_min-mask_thresh, mask_max, cv::THRESH_BINARY);
imshow("threshUpper", threshUpper);
imshow("threshLower", threshLower);
vector<vector<Point>> contoursUpper;
cv::findContours(threshUpper, contoursUpper, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for(auto cnt : contoursUpper){
cv::floodFill(threshLower, cnt[0], 255, 0, 2, 2, cv::FLOODFILL_FIXED_RANGE);
}
threshold(threshLower, out, 200, 255, cv::THRESH_BINARY);
vector<vector<Point>> contours2clean;
cv::findContours(out, contours2clean, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for(const auto& cnt : contours2clean) {
double area = cv::contourArea(cnt);
if ( area > cut_max_size || area < cut_min_size) {
cv::floodFill(out, cnt[0], 0, 0, 2, 2, cv::FLOODFILL_FIXED_RANGE);
}
else {
cv::floodFill(out, cnt[0], 255, 0, 2, 2, cv::FLOODFILL_FIXED_RANGE);
}
}
std::vector<cv::KeyPoint> points;
detector_->detect(out, points);
cv::drawKeypoints(out, points, out, cv::Scalar(0, 0, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
I am looking for some advice for better approaches. Two images (raw and marked) are here:
As the topic is important to me, I reposted this with more pictures here: c++ - Detecting slightly bright areas (fawn of deer) in thermal images - Stack Overflow
Thanks!