Multiple results in OpenCVSharp3 MatchTemplate

后端 未结 2 584
萌比男神i
萌比男神i 2021-01-06 20:47

I am trying to find image occurences inside an image. I have written the following code to get a single match using OpenCVSharp3:

Mat src = OpenCvSharp.Exten         


        
相关标签:
2条回答
  • 2021-01-06 21:17

    Here's a port of the C++ code. Good luck!

    using OpenCvSharp;
    using OpenCvSharp.Util;
    static void RunTemplateMatch(string reference, string template)
    {
        using (Mat refMat = new Mat(reference))
        using (Mat tplMat = new Mat(template))
        using (Mat res = new Mat(refMat.Rows - tplMat.Rows + 1, refMat.Cols - tplMat.Cols + 1, MatType.CV_32FC1))
        {
            //Convert input images to gray
            Mat gref = refMat.CvtColor(ColorConversionCodes.BGR2GRAY);
            Mat gtpl = tplMat.CvtColor(ColorConversionCodes.BGR2GRAY);
    
            Cv2.MatchTemplate(gref, gtpl, res, TemplateMatchModes.CCoeffNormed);
            Cv2.Threshold(res, res, 0.8, 1.0, ThresholdTypes.Tozero);
    
            while (true)
            {
                double minval, maxval, threshold = 0.8;
                Point minloc, maxloc;
                Cv2.MinMaxLoc(res, out minval, out maxval, out minloc, out maxloc);
    
                if (maxval >= threshold)
                {
                    //Setup the rectangle to draw
                    Rect r = new Rect(new Point(maxloc.X, maxloc.Y), new Size(tplMat.Width, tplMat.Height));
    
                    //Draw a rectangle of the matching area
                    Cv2.Rectangle(refMat, r, Scalar.LimeGreen, 2);
    
                    //Fill in the res Mat so you don't find the same area again in the MinMaxLoc
                    Rect outRect;
                    Cv2.FloodFill(res, maxloc, new Scalar(0), out outRect, new Scalar(0.1), new Scalar(1.0));
                }
                else
                    break;
            }
    
            Cv2.ImShow("Matches", refMat);
            Cv2.WaitKey();
        }
    }
    
    0 讨论(0)
  • 2021-01-06 21:19

    I think that code should help you: http://opencv-code.com/quick-tips/how-to-handle-template-matching-with-multiple-occurences/

    It's C++, but conversion to C# shouldn't be a big deal.

    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    
    int main() 
    {
        cv::Mat ref = cv::imread("reference.png");
        cv::Mat tpl = cv::imread("template.png");
        if (ref.empty() || tpl.empty())
            return -1;
    
        cv::Mat gref, gtpl;
        cv::cvtColor(ref, gref, CV_BGR2GRAY);
        cv::cvtColor(tpl, gtpl, CV_BGR2GRAY);
    
        cv::Mat res(ref.rows-tpl.rows+1, ref.cols-tpl.cols+1, CV_32FC1);
        cv::matchTemplate(gref, gtpl, res, CV_TM_CCOEFF_NORMED);
        cv::threshold(res, res, 0.8, 1., CV_THRESH_TOZERO);
    
        while (true) 
        {
            double minval, maxval, threshold = 0.8;
            cv::Point minloc, maxloc;
            cv::minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);
    
            if (maxval >= threshold)
            {
                cv::rectangle(
                    ref, 
                    maxloc, 
                    cv::Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows), 
                    CV_RGB(0,255,0), 2
                );
                cv::floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(.1), cv::Scalar(1.));
            }
            else
                break;
        }
    
        cv::imshow("reference", ref);
        cv::waitKey();
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题