Hi @theodore!
I'm assuming the distance from camera is constant. A simple Template matching with all your different Type of Dots will do the trick! But filtering those dots is all up to you. A sample output using only one dot as a Template is shown below!
bool NMultipleTemplateMatching(Mat Img_Input,Mat Img_Template,float Threshold,float Closeness,vector<Point2f> &List_Matches)
{
Mat Img_Result;
Size Size_Template= Img_Template.size();
Size Size_TemplateCloseRadius((Size_Template.width/2)* Closeness,(Size_Template.height/2)* Closeness);
matchTemplate(Img_Input, Img_Template, Img_Result, TM_CCOEFF_NORMED);
threshold(Img_Result, Img_Result, Threshold, 1.0, THRESH_TOZERO);
while (true)
{
double minval, maxval ;
Point minloc, maxloc;
minMaxLoc(Img_Result, &minval, &maxval, &minloc, &maxloc);
if (maxval >= Threshold)
{
List_Matches.push_back(maxloc);
rectangle(Img_Result,Point2f(maxloc.x-Size_TemplateCloseRadius.width,maxloc.y-Size_TemplateCloseRadius.height),Point2f(maxloc.x+Size_TemplateCloseRadius.width,maxloc.y+Size_TemplateCloseRadius.height),Scalar(0),-1);
}
else
break;
}
//imshow("reference", Img_Debug_Bgr);
return true;
}
main()
{
Mat Img_Source_Gray,Img_Template_Gray,Img_Result_Bgr;
Img_Source_Gray= imread(FileName_S,0);
Img_Template_Gray= imread(FileName_D,0);
cvtColor(Img_Source_Gray,Img_Result_Bgr,COLOR_GRAY2BGR);
float Threshold= m_MinMatchThreshold;// How much percentage the Template should Present in the Range: 0.0 to 1.0
float Closeness= m_MinCloseRadius;// How much close Two Templates can be Range: 0-100
vector<Point2f> List_Matches;
NMultipleTemplateMatching(Img_Source_Gray,Img_Template_Gray,Threshold,Closeness,List_Matches);
t1.stop();
for (int i = 0; i < List_Matches.size(); i++)
{
rectangle(Img_Result_Bgr,List_Matches[i],Point(List_Matches[i].x + Img_Template_Gray.cols, List_Matches[i].y + Img_Template_Gray.rows),Scalar(0,0,255), 2);
}
imshow("Img_Result_Bgr",Img_Result_Bgr);
imshow("Img_Template_Gray",Img_Template_Gray);
}
Sample Output with Cropped Template Template with Match Percentage 80%.