I need to detect object that aren't that much complex: pokestops. Some images of a pokestop:
Screenshot examples:
In the past I have worked with template-matching and a little bit with feature detection and homography but sadly none of my previous work helped me so far in detecting this object.
Snippet of what I've tried so far:
BRISK detectorAndExtractor = BRISK.create();
final MatOfKeyPoint keyPointsLarge = new MatOfKeyPoint();
final MatOfKeyPoint keyPointsSmall = new MatOfKeyPoint();
Mat largeImage = Imgcodecs.imread(filename1, Imgcodecs.IMREAD_COLOR);
Mat smallImage = Imgcodecs.imread(filename2, Imgcodecs.IMREAD_COLOR);
detectorAndExtractor.detect(largeImage, keyPointsLarge);
detectorAndExtractor.detect(smallImage, keyPointsSmall);
//System.out.println("keyPoints.size() : "+keyPointsLarge.size());
//System.out.println("keyPoints2.size() : "+keyPointsSmall.size());
Mat descriptorsLarge = new Mat();
Mat descriptorsSmall = new Mat();
detectorAndExtractor.compute(largeImage, keyPointsLarge, descriptorsLarge);
detectorAndExtractor.compute(smallImage, keyPointsSmall, descriptorsSmall);
//System.out.println("descriptorsA.size() : "+descriptorsLarge.size());
//System.out.println("descriptorsB.size() : "+descriptorsSmall.size());
MatOfDMatch matches = new MatOfDMatch();
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
matcher.match(descriptorsLarge, descriptorsSmall, matches);
//System.out.println("matches.size() : "+matches.size());
MatOfDMatch matchesFiltered = new MatOfDMatch();
List<DMatch> matchesList = matches.toList();
List<DMatch> bestMatches= new ArrayList<DMatch>();
Double max_dist = 0.0;
Double min_dist = 100.0;
for (int i = 0; i < matchesList.size(); i++)
{
Double dist = (double) matchesList.get(i).distance;
if (dist < min_dist && dist != 0)
{
min_dist = dist;
}
if (dist > max_dist)
{
max_dist = dist;
}
}
//System.out.println("max_dist : "+max_dist);
//System.out.println("min_dist : "+min_dist);
if(min_dist > 50 )
{
//System.out.println("No match found");
//System.out.println("Just return ");
return false;
}
double threshold = 3 * min_dist;
double threshold2 = 2 * min_dist;
if (threshold > 75)
{
threshold = 75;
}
else if (threshold2 >= max_dist)
{
threshold = min_dist * 1.1;
}
else if (threshold >= max_dist)
{
threshold = threshold2 * 1.4;
}
//System.out.println("Threshold : "+threshold);
for (int i = 0; i < matchesList.size(); i++)
{
Double dist = (double) matchesList.get(i).distance;
if (dist < threshold)
{
bestMatches.add(matches.toList().get(i));
//System.out.println(String.format(i + " best match added : %s", dist));
}
}
matchesFiltered.fromList(bestMatches);
//System.out.println("matchesFiltered.size() : " + matchesFiltered.size());
if(matchesFiltered.rows() >= 1) //TODO >= 4
{
System.out.println("match found "+matchesFiltered.rows());
System.out.println("bestMatches.size: "+bestMatches.size());
getMatchingPoints(keyPointsLarge,keyPointsSmall,bestMatches);
return true;
}
else
{
return false;
}
I didn't try only Brisk (maybe not the best choice since the object is round), I also tried with SURF following this tutorial: https://docs.opencv.org/3.4/d7/dff/tutorial_feature_homography.html
but I get the following exception:
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.7.0) /tmp/opencv-20230625-23894-1o8sdu5/opencv-4.7.0/modules/calib3d/src/fundam.cpp:385: error: (-28:Unknown error code -28) The input arrays should have at least 4 corresponding point sets to calculate Homography in function 'findHomography'
A friend was suggesting to maybe try with a YOLO algorithm. I found a few examples but none with a thorough explanation. What would you suggest? Thank you.