Emgucv使用Harris角点检测和Fast角点检测

来源:互联网 发布:js改变div内容 编辑:程序博客网 时间:2024/06/05 21:29

角点是两个边缘的连接点,代表了两个边缘变化的方向上的点,在这点上图像梯度有很高的变化。是图像中的重要特征点。在opencv中还有改进版的Harris角点检测:Shi-Tomasi 角点检测算法,但在Emgucv里并没有封装,所以目前无法直接使用。
一、Harris角点检测
Harris角点检测通过判断点在水平和竖直方向上的变化程度来判断是否为角点,使用CornerHarris函数,处理后再用阈值来判断是否为角点。

public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();            Image<Bgra, byte> a = new Image<Bgra, byte>("7f6a384c510fd9f9da3ee67b232dd42a2834a40d.jpg");            Image<Gray, float> b = new Image<Gray, float>(a.Width, a.Height);            Image<Gray, byte> c = new Image<Gray, byte>(a.Width, a.Height);            CvInvoke.CornerHarris(a.Convert<Gray,byte>(), b, 2);     //注意:角点检测传出的为Float类型的数据            CvInvoke.Normalize(b, b, 0, 255,NormType.MinMax,DepthType.Cv32F);  //标准化处理            double min = 0, max = 0;            Point minp = new Point(0, 0);            Point maxp = new Point(0, 0);            CvInvoke.MinMaxLoc(b, ref min, ref max, ref minp, ref maxp);            double scale = 255 / (max - min);            double shift = min * scale;            CvInvoke.ConvertScaleAbs(b, c,scale,shift);//进行缩放,转化为byte类型            byte[] data = c.Bytes;            for (int i = 0; i < b.Height; i++)            {                for (int j = 0; j < b.Width; j++)                {                    int k = i * a.Width + j;                    if (data[k] > 100)    //通过阈值判断                    {                        CvInvoke.Circle(a, new Point(j, i), 1, new MCvScalar(0, 0, 255, 255),2);                    }                }            }            imageBox1.Image = a;        }    }

效果:
这里写图片描述
二、Fast角点检测
Fast角点检测时一中比较快的角点检测算法,是通过将点与周边的其他点比较得来的
需要添加using Emgu.CV.Features2D;

public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();            Image<Bgra, byte> a = new Image<Bgra, byte>("7f6a384c510fd9f9da3ee67b232dd42a2834a40d.jpg");            FastDetector aaa = new FastDetector(60); //阈值设置为60            MKeyPoint[] points = aaa.Detect(a.Convert<Gray, byte>());            Image<Bgra, byte> ee = a.Copy();            foreach (var point in points)            {                CvInvoke.Circle(ee, new Point((int)point.Point.X, (int)point.Point.Y), 1, new MCvScalar(0, 0, 255, 255), 2);            }            imageBox1.Image = ee;        }    }

附图为上述两种方法的对比图,右图为Fast算法(可能是我在Harris算法中阈值取得比较大)
这里写图片描述

0 0