Ask Your Question

Revision history [back]

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!

Hi @theodore! @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!below! image description

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! below!

bool MaskedTemplateMatching(Mat Img_Input,Mat Img_Template,Mat Img_TemplMask,float MinMatchPerncentage,float Closeness,vector<Point2f> &List_Matches)
{
    Mat Img_Result;
    int MinMatchThreshold = MinMatchPerncentage * 2.55;//Percentage
    Size szTemplate= Img_Template.size();
    Size szTemplateCloseRadius((szTemplate.width/2)* Closeness,(szTemplate.height/2)* Closeness);

    MatchTemplatewithMask(Img_Input,Img_Template,Img_TemplMask,Img_Result);
    threshold(Img_Result,Img_Result,MinMatchThreshold,255,THRESH_TOZERO);
    while (true) 
    {
        double minval, maxval ;
        cv::Point minloc, maxloc;
        cv::minMaxLoc(Img_Result, &minval, &maxval, &minloc, &maxloc);

        if (maxval >= MinMatchThreshold)
        {
            rectangle(Img_Result,Point2f(maxloc.x-szTemplateCloseRadius.width,maxloc.y-szTemplateCloseRadius.height),Point2f(maxloc.x+szTemplateCloseRadius.width,maxloc.y+szTemplateCloseRadius.height),Scalar(0),-1);
            List_Matches.push_back(maxloc);
        }
        else
            break;
    }
    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%.

image description

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 MaskedTemplateMatching(Mat NMultipleTemplateMatching(Mat Img_Input,Mat Img_Template,Mat Img_TemplMask,float MinMatchPerncentage,float Img_Template,float Threshold,float Closeness,vector<Point2f> &List_Matches)
{
    Mat Img_Result;
    int MinMatchThreshold = MinMatchPerncentage * 2.55;//Percentage
    Size szTemplate= Size_Template= Img_Template.size();
    Size szTemplateCloseRadius((szTemplate.width/2)* Closeness,(szTemplate.height/2)* Size_TemplateCloseRadius((Size_Template.width/2)* Closeness,(Size_Template.height/2)* Closeness);

    MatchTemplatewithMask(Img_Input,Img_Template,Img_TemplMask,Img_Result);
    threshold(Img_Result,Img_Result,MinMatchThreshold,255,THRESH_TOZERO);
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 ;
        cv::Point Point minloc, maxloc;
        cv::minMaxLoc(Img_Result, minMaxLoc(Img_Result, &minval, &maxval, &minloc, &maxloc);

        if (maxval >= MinMatchThreshold)
Threshold)
        {
            rectangle(Img_Result,Point2f(maxloc.x-szTemplateCloseRadius.width,maxloc.y-szTemplateCloseRadius.height),Point2f(maxloc.x+szTemplateCloseRadius.width,maxloc.y+szTemplateCloseRadius.height),Scalar(0),-1);
            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%.

image description