//read image // var refMat = new Mat("001f.png", ImreadModes.Unchanged); // var tplMat = new Mat("001.png", ImreadModes.Unchanged); using (Mat refMat = new Mat("001f.png", ImreadModes.Unchanged)) using (Mat tplMat = new Mat("001.png", ImreadModes.Unchanged)) 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) { //draw a rectangle of the matching area Rect r = new Rect(new Point(maxloc.X, maxloc.Y), new Size(tplMat.Width, tplMat.Height)); Cv2.Rectangle(refMat, r, Scalar.Red, 2); //debug String msg = $"MinVal={minval.ToString()} MaxVal={maxval.ToString()} MinLoc={minloc.ToString()} MaxLoc={maxloc.ToString()} Rect={r.ToString()}"; Console.WriteLine(msg); //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), FloodFillFlags.Link4); Cv2.FloodFill(res, maxloc, new Scalar(0)); } else { break; } } }