31-角点检测(EmguCV学习)

本文介绍并演示了使用EmguCV库进行Harris、Shi-Tomasi角点检测及亚像素级角点精确化的步骤与效果。通过调整阈值,Harris角点检测能灵活控制角点数量;Shi-Tomasi方法则提供了更稳定的角点定位;最后,亚像素级角点检测进一步提高了角点定位精度。

文章目录

说明

1、EmguCV中Harris角点检测函数:CvInvoke.CornerHarris()
参数harrisResponse为CV_32FC1的图像,计算后需要进行归一化或者阈值化,转换为CV8U再显示;
参数blockSize : 领域大小,和协方差矩阵M的计算有关(影响M的值)
在这里插入图片描述

在这里插入图片描述

2、Harris检测的结果衡量(角点响应度量):M为协方差矩阵,度量R判断是否为角点,需要自己选择判断合适的阈值;
在这里插入图片描述
在这里插入图片描述

3、Shi-Tomasi角点检测:EmguCV没有封装goodFeatureToTrack()方法,只能使用GFTTDetector类的Detect()方法来检测特征点;可以自己控制想要的角点数,使用更方便;
参数minDistance控制角点之间的距离;
在这里插入图片描述
在这里插入图片描述

4、亚像素级角点检测:cornerSubPix()
在这里插入图片描述

Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using System.Drawing;
using Emgu.CV.Features2D;

namespace lesson31
{
    class Program
    {
        static void Main(string[] args)
        {
            ///Harris角点检测
            //Mat src = CvInvoke.Imread("3.jpg");
            //CvInvoke.Imshow("input", src);
            //Mat gray = new Mat();
            //CvInvoke.CvtColor(src, gray, ColorConversion.Bgr2Gray);
            //Mat dst = new Mat();
            //CvInvoke.CornerHarris(gray, dst, 2, 3, 0.04);//角点检测
            //CvInvoke.Threshold(dst, dst, 0.005, 255, ThresholdType.Binary);
            //Console.WriteLine("Depth: {0}\nChannels: {1}", dst.Depth, dst.NumberOfChannels);
            //dst.ConvertTo(dst, DepthType.Cv8U);
            //CvInvoke.Imshow("CornerHarris", dst);
            //Image<Gray, Byte> img = dst.ToImage<Gray, Byte>();
            //for (int i = 0; i < img.Rows; i++)
            //{
            //    for (int j = 0; j < img.Cols; j++)
            //    {
            //        if (img.Data[i, j, 0] == 255)
            //        {
            //            CvInvoke.Circle(src, new Point(j, i), 2, new MCvScalar(0, 255, 0), -1);
            //        }
            //    }
            //}
            //CvInvoke.Imshow("result", src);
            //CvInvoke.WaitKey(0);

            ///另一种方法
            //Mat src = CvInvoke.Imread("3.jpg");
            //Mat grayImg = new Mat();
            //CvInvoke.CvtColor(src, grayImg, ColorConversion.Bgr2Gray);

            //Mat dst = new Mat();
            //CvInvoke.CornerHarris(grayImg, dst, 2, 3, 0.04, BorderType.Default);
            //Mat scaleImg = new Mat();
            //CvInvoke.Normalize(dst, dst, 0, 255, NormType.MinMax, DepthType.Cv32F);
            //CvInvoke.ConvertScaleAbs(dst, scaleImg, 1, 0);
            //Image<Gray, Byte> img = scaleImg.ToImage<Gray, Byte>();
            //for(int i = 0; i < img.Rows;i++)
            //{
            //    for(int j =0; j < img.Cols; j++)
            //    {
            //        if(img.Data[i,j,0] > 100)           //阈值选取很重要,控制角点个数
            //        {
            //            CvInvoke.Circle(src, new Point(j, i), 3, new MCvScalar(0, 255, 0), -1);
            //        }
            //    }
            //}
            //CvInvoke.Imshow("result", src);
            //CvInvoke.WaitKey(0);

            ///Shi-Tomasi角点检测
            //Mat src = CvInvoke.Imread("mask2.jpg");
            //Mat grayImg = new Mat();
            //CvInvoke.CvtColor(src, grayImg, ColorConversion.Bgr2Gray);
            //GFTTDetector gFTT = new GFTTDetector(12, 0.01, 1, 3, false, 0.04);
            //MKeyPoint[] points = gFTT.Detect(grayImg);      //使用Shi-Tomasi检测算法检测特征点
            //for(int i = 0; i < points.Length; i++)
            //{
            //    Point pt = new Point();
            //    pt.X = (int)points[i].Point.X;
            //    pt.Y = (int)points[i].Point.Y;

            //    CvInvoke.Circle(src, pt, 3, new MCvScalar(0, 0, 255), -1);
            //}
            //CvInvoke.Imshow("result", src);
            //CvInvoke.WaitKey(0);

            ///亚像素角点检测
            Mat src = CvInvoke.Imread("3.jpg");
            CvInvoke.Imshow("input", src);

            Mat grayImg = new Mat();
            CvInvoke.CvtColor(src, grayImg, ColorConversion.Bgr2Gray);
            Mat harrisImg = new Mat();
            CvInvoke.CornerHarris(grayImg, harrisImg, 2, 3, 0.04);
            CvInvoke.Threshold(harrisImg, harrisImg, 0.01, 255, ThresholdType.Binary);
            Mat dst = new Mat();
            harrisImg.ConvertTo(dst, DepthType.Cv8U);
            CvInvoke.Imshow("mask", dst);


            VectorOfPointF corners = new VectorOfPointF();
            Image<Gray, Byte> img = dst.ToImage<Gray, Byte>();
            for(int i = 0; i < img.Rows; i++)
            {
                for(int j = 0; j < img.Cols; j++)
                {
                    if(img.Data[i,j,0] == 255)
                    {
                        CvInvoke.Circle(src, new Point(j, i), 3, new MCvScalar(0, 0, 255), -1);
                        PointF[] pt = new PointF[1];
                        pt[0].X = j;
                        pt[0].Y = i;
                        corners.Push(pt);
                    }
                }
            }
            CvInvoke.Imshow("result", src);
            MCvTermCriteria termCriteria = new MCvTermCriteria(40, 0.001);
            CvInvoke.CornerSubPix(grayImg, corners, new Size(5, 5), new Size(-1, -1), termCriteria); //亚像素级角点精确化
            for(int i = 0; i < corners.Size; i++)
            {
                Console.WriteLine("corner {0} : ({1:F2},{1:F2})", i, corners[i].X, corners[i].Y);
            }

            CvInvoke.WaitKey(0);
        }
    }
}

效果

1、Harris角点检测:
在这里插入图片描述
使用不同阈值,检测到的角点数也不同:
在这里插入图片描述
2、Shi-Tomasi检测:(GFTTDetector)
在这里插入图片描述

3、亚像素级角点精确化:
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值