【 OpenCV 】基于OpenCV的多角度(带旋转角度)模板匹配算法 C#&OpenCVSharp4

1/模板匹配方法

        /// 
        /// 多角度模板匹配方法
        /// 
        /// 待匹配图像
        /// 模板图像
        /// 起始角度
        /// 角度范围
        /// 角度步长
        /// 金字塔层级
        /// 得分阈值
        /// 
        private ResultPoint CircleMatchNcc(Mat srcImage, Mat modelImage, double angleStart, double angleRange, double angleStep, int numLevels, double thresScore,int nccMethod)
        {
            double step = angleRange / ((angleRange / angleStep) / 100);
            double start = angleStart;
            double range = angleRange;

            //定义图片匹配所需要的参数
            int resultCols = srcImage.Cols - modelImage.Cols + 1;
            int resultRows = srcImage.Rows - modelImage.Cols + 1;
            Mat result = new Mat(resultCols, resultRows, MatType.CV_8U);
            Mat src = new Mat();
            Mat model = new Mat();
            srcImage.CopyTo(src);
            modelImage.CopyTo(model);

            //对模板图像和待检测图像分别进行图像金字塔下采样
            for (int i = 0; i < numLevels; i++)
            {
                Cv2.PyrDown(src, src, new Size(src.Cols / 2, src.Rows / 2));
                Cv2.PyrDown(model, model, new Size(model.Cols / 2, model.Rows / 2));
            }

            TemplateMatchModes matchMode = TemplateMatchModes.CCoeffNormed;
            switch (nccMethod)
            {
                case 0:
                    matchMode = TemplateMatchModes.SqDiff;
                    break;
                case 1:
                    matchMode = TemplateMatchModes.SqDiffNormed;
                    break;
                case 2:
                    matchMode = TemplateMatchModes.CCorr;
                    break;
                case 3:
                    matchMode = TemplateMatchModes.CCorrNormed;
                    break;
                case 4:
                    matchMode = TemplateMatchModes.CCoeff;
                    break;
                case 5:
                    matchMode = TemplateMatchModes.CCoeffNormed;
                    break;
            }

            //在没有旋转的情况下进行第一次匹配
            Cv2.MatchTemplate(src, model, result, matchMode);
            Cv2.MinMaxLoc(result, out double minVal, out double maxVal, out Point minLoc, out Point maxLoc, new Mat());

            Point location = maxLoc;
            double temp = maxVal;
            double angle = 0;

            Mat newImg;    

            //以最佳匹配点左右十倍角度步长进行循环匹配,直到角度步长小于参数角度步长
            if (nccMethod == 0 || nccMethod == 1)
            {
                do
                {
                    for (int i = 0; i <= (int)range / step; i++)
                    {
                        newImg = ImageRotate(model, start + step * i);
                        Cv2.MatchTemplate(src, newImg, result, matchMode);
                        Cv2.MinMaxLoc(result, out double minval, out double maxval, out Point minloc, out Point maxloc, new Mat());
                        if (maxval < temp)
                        {
                            location = maxloc;
                            temp = maxval;
                            angle = start + step * i;
                        }
                    }
                    range = step * 2;
                    start = angle - step;
                    step = step / 10;
                } while (step > angleStep);
                return new ResultPoint(location.X * Math.Pow(2, numLevels) + modelImage.Width / 2, location.Y * Math.Pow(2, numLevels) + modelImage.Height / 2, -angle, temp);
            }
            else
            {
                do
                {
                    for (int i = 0; i <= (int)range / step; i++)
                    {
                        newImg = ImageRotate(model, start + step * i);
                        Cv2.MatchTemplate(src, newImg, result, matchMode);
                        Cv2.MinMaxLoc(result, out double minval, out double maxval, out Point minloc, out Point maxloc, new Mat());
                        if (maxval > temp)
                        {
                            location = maxloc;
                            temp = maxval;
                            angle = start + step * i;
                        }
                    }
                    range = step * 2;
                    start = angle - step;
                    step = step / 10;
                } while (step > angleStep);
                if (temp > thresScore)
            {
                return new ResultPoint(location.X * Math.Pow(2, numLevels), location.Y * Math.Pow(2, numLevels), -angle, temp);
            }
            }
            return new ResultPoint();
        }

2/其他准备

            public ResultPoint(double x, double y, double t, double score)
            {
                X = (int)x;
                Y = (int)y;
                T = t;
                Score = score;
            }

            /// 
            /// 图像旋转
            /// 
            /// 输入图像
            /// 旋转的角度
            /// 旋转后图像
            static Mat ImageRotate(Mat image, double angle)
            {
                Mat newImg = new Mat();
                Point2f pt = new Point2f((float)image.Cols / 2, (float)image.Rows / 2);
                Mat r = Cv2.GetRotationMatrix2D(pt, angle, 1.0);
                Cv2.WarpAffine(image, newImg, r, image.Size());

                return newImg;
            }

            /// 
            /// 金字塔下采样
            /// 
            /// 输入图像
            /// 下采样完图像
            private Mat ImagePyrDown(Mat image)
            {
                for (int i = 0; i < MyConfig.NumLevels; i++)
                {
                    Cv2.PyrDown(image, image, new Size(image.Cols / 2, image.Rows / 2));
                }

                return image;
            }

 

你可能感兴趣的:(OpenCV)