在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#图形和图像处理 → 像素处理

像素处理

C#图形和图像处理

下载此实例
  • 开发语言:C#
  • 实例大小:0.02M
  • 下载次数:55
  • 浏览次数:584
  • 发布时间:2016-06-01
  • 实例类别:C#图形和图像处理
  • 发 布 人:竹林风an
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 像素

实例介绍

【实例简介】

【实例截图】

【核心代码】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;

namespace ImageProcessLearn
{
    public partial class FormFeatureDetection : Form
    {
        //成员变量
        private string sourceImageFileName = "wky_tms_2272x1704.jpg";   //源图像文件名
        private Image<Bgr, Byte> imageSource = null;                    //源图像
        private Image<Gray, Byte> imageSourceGrayscale = null;          //灰度源图像

        public FormFeatureDetection()
        {
            InitializeComponent();
        }

        //加载窗体时
        private void FormFeatureDetection_Load(object sender, EventArgs e)
        {
            //加载源图像
            imageSource = new Image<Bgr, byte>(sourceImageFileName);
            imageSourceGrayscale = imageSource.Convert<Gray, Byte>();
            pbSource.Image = imageSource.Bitmap;
            pbResult.Image = imageSourceGrayscale.Bitmap;

            //初始化控件
            //Sobel算子
            cmbSobelXOrder.SelectedItem = "1";
            cmbSobelYOrder.SelectedItem = "0";
            cmbSobelApertureSize.SelectedItem = "3";
            //拉普拉斯变换
            cmbLaplaceApertureSize.SelectedItem = "3";
            //Canny算子
            cmbCannyApertureSize.SelectedItem = "3";
            //Star关键点
            cmbStarMaxSize.SelectedItem = "45";
        }

        //加载图像
        private void btnLoadImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.CheckFileExists = true;
            ofd.DefaultExt = "jpg";
            ofd.Filter = "图片文件|*.jpg;*.png;*.bmp|所有文件|*.*";
            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                if (ofd.FileName != "")
                {
                    sourceImageFileName = ofd.FileName;
                    if (imageSource != null)
                        imageSource.Dispose();
                    imageSource = new Image<Bgr, byte>(sourceImageFileName);
                    if (imageSourceGrayscale != null)
                        imageSourceGrayscale.Dispose();
                    imageSourceGrayscale = imageSource.Convert<Gray, Byte>();
                    pbSource.Image = imageSource.Bitmap;
                    pbResult.Image = imageSourceGrayscale.Bitmap;
                }
            }
            ofd.Dispose();
        }

        //关闭窗体时
        private void FormFeatureDetection_FormClosing(object sender, FormClosingEventArgs e)
        {
            //释放资源
            if (imageSource != null)
                imageSource.Dispose();
            if (imageSourceGrayscale != null)
                imageSourceGrayscale.Dispose();
        }

        //计算特征
        private void btnCalcFeature_Click(object sender, EventArgs e)
        {
            string result = "";
            if (tcFeatureDetections.SelectedTab == tpSobel)
                result = SobelFeatureDetect();      //Sobel算子
            else if (tcFeatureDetections.SelectedTab == tpLaplace)
                result = LaplaceFeatureDetect();    //拉普拉斯变换
            else if (tcFeatureDetections.SelectedTab == tpCanny)
                result = CannyFeatureDetect();      //Canny算子
            else if (tcFeatureDetections.SelectedTab == tpHoughLines)
                result = HoughLinesFeatureDetect(); //霍夫线变换
            else if (tcFeatureDetections.SelectedTab == tpHoughCircles)
                result = HoughCirclesFeatureDetect();   //霍夫圆变换
            else if (tcFeatureDetections.SelectedTab == tpHarris)
                result = CornerHarrisFeatureDetect();   //Harris角点
            else if (tcFeatureDetections.SelectedTab == tpShiTomasi)
                result = CornerShiTomasiFeatureDetect();//ShiTomasi角点
            else if (tcFeatureDetections.SelectedTab == tpCornerSubPix)
                result = CornerSubPixFeatureDetect();   //亚像素级角点
            else if (tcFeatureDetections.SelectedTab == tpSurf)
                result = SurfFeatureDetect();           //SURF角点
            else if (tcFeatureDetections.SelectedTab == tpStarKeypoints)
                result = StarKeyPointFeatureDetect();   //Star关键点
            else if (tcFeatureDetections.SelectedTab == tpMser)
                result = MserFeatureDetect();           //MSER区域
            else if (tcFeatureDetections.SelectedTab == tpFASTKeypoints)
                result = FASTKeyPointFeatureDetect();   //FAST关键点
            else if (tcFeatureDetections.SelectedTab == tpSift)
                result = SiftFeatureDetect();           //SIFT关键点
            txtResult.Text  = result;
        }

        //Sobel算子
        private string SobelFeatureDetect()
        {
            //获取参数
            int xOrder = int.Parse((string)cmbSobelXOrder.SelectedItem);
            int yOrder = int.Parse((string)cmbSobelYOrder.SelectedItem);
            int apertureSize = int.Parse((string)cmbSobelApertureSize.SelectedItem);
            if ((xOrder == 0 && yOrder == 0) || (xOrder != 0 && yOrder != 0))
                return "Sobel算子,参数错误:xOrder和yOrder中必须且只能有一个非零。\r\n";
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Image<Gray, Single> imageDest = imageSourceGrayscale.Sobel(xOrder, yOrder, apertureSize);
            sw.Stop();
            //显示
            pbResult.Image = imageDest.Bitmap;
            //释放资源
            imageDest.Dispose();
            //返回
            return string.Format("·Sobel算子,用时{0:F05}毫秒,参数(x方向求导阶数:{1},y方向求导阶数:{2},方形滤波器宽度:{3})\r\n", sw.Elapsed.TotalMilliseconds, xOrder, yOrder, apertureSize);
        }

        //拉普拉斯变换
        private string LaplaceFeatureDetect()
        {
            //获取参数
            int apertureSize = int.Parse((string)cmbLaplaceApertureSize.SelectedItem);
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Image<Gray, Single> imageDest = imageSourceGrayscale.Laplace(apertureSize);
            sw.Stop();
            //显示
            pbResult.Image = imageDest.Bitmap;
            //释放资源
            imageDest.Dispose();
            //返回
            return string.Format("·拉普拉斯变换,用时{0:F05}毫秒,参数(方形滤波器宽度:{1})\r\n", sw.Elapsed.TotalMilliseconds, apertureSize);
        }

        //Canny算子
        private string CannyFeatureDetect()
        {
            //获取参数
            double lowThresh = double.Parse(txtCannyLowThresh.Text);
            double highThresh = double.Parse(txtCannyHighThresh.Text);
            int apertureSize = int.Parse((string)cmbCannyApertureSize.SelectedItem);
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Image<Gray, Byte> imageDest = null;
            Image<Bgr, Byte> imageDest2 = null;
            if (rbCannyUseCvCanny.Checked)
            {
                imageDest = new Image<Gray, byte>(imageSourceGrayscale.Size);
                CvInvoke.cvCanny(imageSourceGrayscale.Ptr, imageDest.Ptr, lowThresh, highThresh, apertureSize);
            }
            else
                imageDest2 = imageSource.Canny(new Bgr(lowThresh, lowThresh, lowThresh), new Bgr(highThresh, highThresh, highThresh));
            sw.Stop();
            //显示
            pbResult.Image = rbCannyUseCvCanny.Checked ? imageDest.Bitmap : imageDest2.Bitmap;
            //释放资源
            if (imageDest != null)
                imageDest.Dispose();
            if (imageDest2 != null)
                imageDest2.Dispose();
            //返回
            return string.Format("·Canny算子,用时{0:F05}毫秒,参数(方式:{1},阀值下限:{2},阀值上限:{3},方形滤波器宽度:{4})\r\n", sw.Elapsed.TotalMilliseconds, rbCannyUseCvCanny.Checked ? "cvCanny" : "Image<TColor, TDepth>.Canny", lowThresh, highThresh, apertureSize);
        }

        //计算自适应的Canny算子阀值
        private void btnCannyCalcAdaptiveThresh_Click(object sender, EventArgs e)
        {
            int apertureSize = int.Parse((string)cmbCannyApertureSize.SelectedItem);
            double lowThresh, highThresh;
            AdaptiveFindCannyThreshold(imageSourceGrayscale, apertureSize, out lowThresh, out highThresh);
            txtCannyLowThresh.Text = lowThresh.ToString();
            txtCannyHighThresh.Text = highThresh.ToString();
        }

        /// <summary>
        /// 计算图像的自适应Canny算子阀值
        /// </summary>
        /// <param name="imageSrc">源图像,只能是256级灰度图像</param>
        /// <param name="apertureSize">方形滤波器的宽度</param>
        /// <param name="lowThresh">阀值下限</param>
        /// <param name="highThresh">阀值上限</param>
        unsafe void AdaptiveFindCannyThreshold(Image<Gray, Byte> imageSrc, int apertureSize, out double lowThresh, out double highThresh)
        {
            //计算源图像x方向和y方向的1阶Sobel算子
            Size size = imageSrc.Size;
            Image<Gray, Int16> imageDx = new Image<Gray, short>(size);
            Image<Gray, Int16> imageDy = new Image<Gray, short>(size);
            CvInvoke.cvSobel(imageSrc.Ptr, imageDx.Ptr, 1, 0, apertureSize);
            CvInvoke.cvSobel(imageSrc.Ptr, imageDy.Ptr, 0, 1, apertureSize);
            Image<Gray, Single> image = new Image<Gray, float>(size);
            int i, j;
            DenseHistogram hist = null;
            int hist_size = 255;
            float[] range_0 = new float[] { 0, 256 };
            double PercentOfPixelsNotEdges = 0.7;
            //计算边缘的强度,并保存于图像中
            float maxv = 0;
            float temp;
            byte* imageDataDx = (byte*)imageDx.MIplImage.imageData.ToPointer();
            byte* imageDataDy = (byte*)imageDy.MIplImage.imageData.ToPointer();
            byte* imageData = (byte*)image.MIplImage.imageData.ToPointer();
            int widthStepDx = imageDx.MIplImage.widthStep;
            int widthStepDy = widthStepDx;
            int widthStep = image.MIplImage.widthStep;
            for (i = 0; i < size.Height; i  )
            {
                short* _dx = (short*)(imageDataDx   widthStepDx * i);
                short* _dy = (short*)(imageDataDy   widthStepDy * i);
                float* _image = (float*)(imageData   widthStep * i);
                for (j = 0; j < size.Width; j  )
                {
                    temp = (float)(Math.Abs(*(_dx   j))   Math.Abs(*(_dy   j)));
                    *(_image   j) = temp;
                    if (maxv < temp)
                        maxv = temp;
                }
            }
            //计算直方图
            range_0[1] = maxv;
            hist_size = hist_size > maxv ? (int)maxv : hist_size;
            hist = new DenseHistogram(hist_size, new RangeF(range_0[0], range_0[1]));
            hist.Calculate<Single>(new Image<Gray, Single>[] { image }, false, null);
            int total = (int)(size.Height * size.Width * PercentOfPixelsNotEdges);
            double sum = 0;
            int icount = hist.BinDimension[0].Size;
            for (i = 0; i < icount; i  )
            {
                sum  = hist[i];
                if (sum > total)
                    break;
            }
            //计算阀值
            highThresh = (i   1) * maxv / hist_size;
            lowThresh = highThresh * 0.4;
            //释放资源
            imageDx.Dispose();
            imageDy.Dispose(); image.Dispose();
            hist.Dispose();
        }

        //霍夫线变换
        private string HoughLinesFeatureDetect()
        {
            //获取参数
            HOUGH_TYPE method = rbHoughLinesSHT.Checked ? HOUGH_TYPE.CV_HOUGH_STANDARD : (rbHoughLinesPPHT.Checked ? HOUGH_TYPE.CV_HOUGH_PROBABILISTIC : HOUGH_TYPE.CV_HOUGH_MULTI_SCALE);
            double rho = double.Parse(txtHoughLinesRho.Text);
            double theta = double.Parse(txtHoughLinesTheta.Text);
            int threshold = int.Parse(txtHoughLinesThreshold.Text);
            double param1 = double.Parse(txtHoughLinesParam1.Text);
            double param2 = double.Parse(txtHoughLinesParam2.Text);
            MemStorage storage = new MemStorage();
            int linesCount = 0;
            StringBuilder sbResult = new StringBuilder();
            //计算,先运行Canny边缘检测(参数来自Canny算子属性页),然后再用计算霍夫线变换
            double lowThresh = double.Parse(txtCannyLowThresh.Text);
            double highThresh = double.Parse(txtCannyHighThresh.Text);
            int apertureSize = int.Parse((string)cmbCannyApertureSize.SelectedItem);
            Image<Gray, Byte> imageCanny = new Image<Gray, byte>(imageSourceGrayscale.Size);
            CvInvoke.cvCanny(imageSourceGrayscale.Ptr, imageCanny.Ptr, lowThresh, highThresh, apertureSize);
            Stopwatch sw = new Stopwatch();
            sw.Start();
            IntPtr ptrLines = CvInvoke.cvHoughLines2(imageCanny.Ptr, storage.Ptr, method, rho, theta, threshold, param1, param2);
            Seq<LineSegment2D> linesSeq = null;
            Seq<PointF> linesSeq2 = null;
            if (method == HOUGH_TYPE.CV_HOUGH_PROBABILISTIC)
                linesSeq = new Seq<LineSegment2D>(ptrLines, storage);
            else
                linesSeq2 = new Seq<PointF>(ptrLines, storage);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            if (linesSeq != null)
            {
                linesCount = linesSeq.Total;
                foreach (LineSegment2D line in linesSeq)
                {
                    imageResult.Draw(line, new Bgr(255d, 0d, 0d), 4);
                    sbResult.AppendFormat("{0}-{1},", line.P1, line.P2);
                }
            }
            else
            {
                linesCount = linesSeq2.Total;
                foreach (PointF line in linesSeq2)
                {
                    float r = line.X;
                    float t = line.Y;
                    double a = Math.Cos(t), b = Math.Sin(t);
                    double x0 = a * r, y0 = b * r;
                    int x1 = (int)(x0   1000 * (-b));
                    int y1 = (int)(y0   1000 * (a));
                    int x2 = (int)(x0 - 1000 * (-b));
                    int y2 = (int)(y0 - 1000 * (a));
                    Point pt1 = new Point(x1, y1);
                    Point pt2 = new Point(x2, y2);
                    imageResult.Draw(new LineSegment2D(pt1, pt2), new Bgr(255d, 0d, 0d), 4);
                    sbResult.AppendFormat("{0}-{1},", pt1, pt2);
                }
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageCanny.Dispose();
            imageResult.Dispose();
            storage.Dispose();
            //返回
            return string.Format("·霍夫线变换,用时{0:F05}毫秒,参数(变换方式:{1},距离精度:{2},弧度精度:{3},阀值:{4},参数1:{5},参数2:{6}),找到{7}条直线\r\n{8}",
                sw.Elapsed.TotalMilliseconds, method.ToString("G"), rho, theta, threshold, param1, param2, linesCount, linesCount != 0 ? (sbResult.ToString()   "\r\n") : "");
        }

        //霍夫圆变换
        private string HoughCirclesFeatureDetect()
        {
            //获取参数
            double dp = double.Parse(txtHoughCirclesDp.Text);
            double minDist = double.Parse(txtHoughCirclesMinDist.Text);
            double param1 = double.Parse(txtHoughCirclesParam1.Text);
            double param2 = double.Parse(txtHoughCirclesParam2.Text);
            int minRadius = int.Parse(txtHoughCirclesMinRadius.Text);
            int maxRadius = int.Parse(txtHoughCirclesMaxRadius.Text);
            StringBuilder sbResult = new StringBuilder();
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            CircleF[][] circles = imageSourceGrayscale.HoughCircles(new Gray(param1), new Gray(param2), dp, minDist, minRadius, maxRadius);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            int circlesCount = 0;
            foreach (CircleF[] cs in circles)
            {
                foreach (CircleF circle in cs)
                {
                    imageResult.Draw(circle, new Bgr(255d, 0d, 0d), 4);
                    sbResult.AppendFormat("圆心{0}半径{1},", circle.Center, circle.Radius);
                    circlesCount  ;
                }
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            //返回
            return string.Format("·霍夫圆变换,用时{0:F05}毫秒,参数(累加器图像的最小分辨率:{1},不同圆之间的最小距离:{2},边缘阀值:{3},累加器阀值:{4},最小圆半径:{5},最大圆半径:{6}),找到{7}个圆\r\n{8}",
                sw.Elapsed.TotalMilliseconds, dp, minDist, param1, param2, minRadius, maxRadius, circlesCount, sbResult.Length > 0 ? (sbResult.ToString()   "\r\n") : "");
        }

        //Harris角点
        private string CornerHarrisFeatureDetect()
        {
            //获取参数
            int blockSize = int.Parse(txtCornerHarrisBlockSize.Text);
            int apertureSize = int.Parse(txtCornerHarrisApertureSize.Text);
            double k = double.Parse(txtCornerHarrisK.Text);
            //计算
            Image<Gray, Single> imageDest = new Image<Gray, float>(imageSourceGrayscale.Size);
            Stopwatch sw = new Stopwatch();
            sw.Start();
            CvInvoke.cvCornerHarris(imageSourceGrayscale.Ptr, imageDest.Ptr, blockSize, apertureSize, k);
            sw.Stop();
            //显示
            pbResult.Image = imageDest.Bitmap;
            //释放资源
            imageDest.Dispose();
            //返回
            return string.Format("·Harris角点,用时{0:F05}毫秒,参数(邻域大小:{1},方形滤波器宽度:{2},权重系数:{3})\r\n", sw.Elapsed.TotalMilliseconds, blockSize, apertureSize, k);
        }

        //ShiTomasi角点
        private string CornerShiTomasiFeatureDetect()
        {
            //获取参数
            int cornerCount = int.Parse(txtGoodFeaturesCornerCount.Text);
            double qualityLevel = double.Parse(txtGoodFeaturesQualityLevel.Text);
            double minDistance = double.Parse(txtGoodFeaturesMinDistance.Text);
            int blockSize = int.Parse(txtGoodFeaturesBlockSize.Text);
            bool useHarris = cbGoodFeaturesUseHarris.Checked;
            double k = double.Parse(txtGoodFeaturesK.Text);
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            PointF[][] corners = imageSourceGrayscale.GoodFeaturesToTrack(cornerCount, qualityLevel, minDistance, blockSize, useHarris, k);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            int cornerCount2 = 0;
            StringBuilder sbResult = new StringBuilder();
            int radius = (int)(minDistance / 2)   1;
            int thickness = (int)(minDistance / 4)   1;
            foreach (PointF[] cs in corners)
            {
                foreach (PointF p in cs)
                {
                    imageResult.Draw(new CircleF(p, radius), new Bgr(255d, 0d, 0d), thickness);
                    cornerCount2  ;
                    sbResult.AppendFormat("{0},", p);
                }
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            //返回
            return string.Format("·ShiTomasi角点,用时{0:F05}毫秒,参数(最大角点数目:{1},最小特征值:{2},角点间的最小距离:{3},邻域大小:{4},角点类型:{5},权重系数:{6}),检测到{7}个角点\r\n{8}",
                sw.Elapsed.TotalMilliseconds, cornerCount, qualityLevel, minDistance, blockSize, useHarris ? "Harris" : "ShiTomasi", k, cornerCount2, cornerCount2 > 0 ? (sbResult.ToString()   "\r\n") : "");
        }

        //亚像素级角点
        private string CornerSubPixFeatureDetect()
        {
            //获取参数
            int winWidth = int.Parse(txtCornerSubPixWinWidth.Text);
            int winHeight = int.Parse(txtCornerSubPixWinHeight.Text);
            Size win = new Size(winWidth, winHeight);
            int zeroZoneWidth = int.Parse(txtCornerSubPixZeroZoneWidth.Text);
            int zeroZoneHeight = int.Parse(txtCornerSubPixZeroZoneHeight.Text);
            Size zeroZone = new Size(zeroZoneWidth, zeroZoneHeight);
            int maxIter=int.Parse(txtCornerSubPixMaxIter.Text);
            double epsilon=double.Parse(txtCornerSubPixEpsilon.Text);
            MCvTermCriteria criteria = new MCvTermCriteria(maxIter, epsilon);
            //先计算得到易于跟踪的点(ShiTomasi角点)
            int cornerCount = int.Parse(txtGoodFeaturesCornerCount.Text);
            double qualityLevel = double.Parse(txtGoodFeaturesQualityLevel.Text);
            double minDistance = double.Parse(txtGoodFeaturesMinDistance.Text);
            int blockSize = int.Parse(txtGoodFeaturesBlockSize.Text);
            bool useHarris = cbGoodFeaturesUseHarris.Checked;
            double k = double.Parse(txtGoodFeaturesK.Text);
            PointF[][] corners = imageSourceGrayscale.GoodFeaturesToTrack(cornerCount, qualityLevel, minDistance, blockSize, useHarris, k);
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            imageSourceGrayscale.FindCornerSubPix(corners, win, zeroZone, criteria);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            int cornerCount2 = 0;
            StringBuilder sbResult = new StringBuilder();
            int radius = (int)(minDistance / 2)   1;
            int thickness = (int)(minDistance / 4)   1;
            foreach (PointF[] cs in corners)
            {
                foreach (PointF p in cs)
                {
                    imageResult.Draw(new CircleF(p, radius), new Bgr(255d, 0d, 0d), thickness);
                    cornerCount2  ;
                    sbResult.AppendFormat("{0},", p);
                }
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            //返回
            return string.Format("·亚像素级角点,用时{0:F05}毫秒,参数(搜索窗口:{1},死区:{2},最大迭代次数:{3},亚像素值的精度:{4}),检测到{5}个角点\r\n{6}",
                sw.Elapsed.TotalMilliseconds, win, zeroZone, maxIter, epsilon, cornerCount2, cornerCount2 > 0 ? (sbResult.ToString()   "\r\n") : "");
        }

        //SURF角点
        private string SurfFeatureDetect()
        {
            //获取参数
            bool getDescriptors = cbSurfGetDescriptors.Checked;
            MCvSURFParams surfParam = new MCvSURFParams();
            surfParam.extended=rbSurfBasicDescriptor.Checked ? 0 : 1;
            surfParam.hessianThreshold=double.Parse(txtSurfHessianThreshold.Text);
            surfParam.nOctaves=int.Parse(txtSurfNumberOfOctaves.Text);
            surfParam.nOctaveLayers=int.Parse(txtSurfNumberOfOctaveLayers.Text);
            //计算
            SURFFeature[] features = null;
            MKeyPoint[] keyPoints = null;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            if (getDescriptors)
                features = imageSourceGrayscale.ExtractSURF(ref surfParam);
            else
                keyPoints = surfParam.DetectKeyPoints(imageSourceGrayscale, null);
            sw.Stop();
            //显示
            bool showDetail = cbSurfShowDetail.Checked;
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            StringBuilder sbResult = new StringBuilder();
            int idx = 0;
            if (getDescriptors)
            {
                foreach (SURFFeature feature in features)
                {
                    imageResult.Draw(new CircleF(feature.Point.pt, 5), new Bgr(255d, 0d, 0d), 2);
                    if (showDetail)
                    {
                        sbResult.AppendFormat("第{0}点(坐标:{1},尺寸:{2},方向:{3}°,hessian值:{4},拉普拉斯标志:{5},描述:[",
                            idx, feature.Point.pt, feature.Point.size, feature.Point.dir, feature.Point.hessian, feature.Point.laplacian);
                        foreach (float d in feature.Descriptor)
                            sbResult.AppendFormat("{0},", d);
                        sbResult.Append("]),");
                    }
                    idx  ;
                }
            }
            else
            {
                foreach (MKeyPoint keypoint in keyPoints)
                {
                    imageResult.Draw(new CircleF(keypoint.Point, 5), new Bgr(255d, 0d, 0d), 2);
                    if (showDetail)
                        sbResult.AppendFormat("第{0}点(坐标:{1},尺寸:{2},方向:{3}°,响应:{4},octave:{5}),",
                            idx, keypoint.Point, keypoint.Size, keypoint.Angle, keypoint.Response, keypoint.Octave);
                    idx  ;
                }
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            //返回
            return string.Format("·SURF角点,用时{0:F05}毫秒,参数(描述:{1},hessian阀值:{2},octave数目:{3},每个octave的层数:{4},检测到{5}个角点\r\n{6}",
                sw.Elapsed.TotalMilliseconds, getDescriptors ? (surfParam.extended == 0 ? "获取基本描述" : "获取扩展描述") : "不获取描述", surfParam.hessianThreshold,
                surfParam.nOctaves, surfParam.nOctaveLayers, getDescriptors ? features.Length : keyPoints.Length, showDetail ? sbResult.ToString()   "\r\n" : "");
        }

        //Star关键点
        private string StarKeyPointFeatureDetect()
        {
            //获取参数
            StarDetector starParam = new StarDetector();
            starParam.MaxSize = int.Parse((string)cmbStarMaxSize.SelectedItem);
            starParam.ResponseThreshold = int.Parse(txtStarResponseThreshold.Text);
            starParam.LineThresholdProjected = int.Parse(txtStarLineThresholdProjected.Text);
            starParam.LineThresholdBinarized = int.Parse(txtStarLineThresholdBinarized.Text);
            starParam.SuppressNonmaxSize = int.Parse(txtStarSuppressNonmaxSize.Text);
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            MCvStarKeypoint[] keyPoints = imageSourceGrayscale.GetStarKeypoints(ref starParam);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            StringBuilder sbResult = new StringBuilder();
            int idx = 0;
            foreach (MCvStarKeypoint keypoint in keyPoints)
            {
                imageResult.Draw(new CircleF(new PointF(keypoint.pt.X, keypoint.pt.Y), keypoint.size / 2), new Bgr(255d, 0d, 0d), keypoint.size / 4);
                sbResult.AppendFormat("第{0}点(坐标:{1},尺寸:{2},强度:{3}),", idx, keypoint.pt, keypoint.size, keypoint.response);
                idx  ;
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            //返回
            return string.Format("·Star关键点,用时{0:F05}毫秒,参数(MaxSize:{1},ResponseThreshold:{2},LineThresholdProjected:{3},LineThresholdBinarized:{4},SuppressNonmaxSize:{5}),检测到{6}个关键点\r\n{7}",
                sw.Elapsed.TotalMilliseconds, starParam.MaxSize, starParam.ResponseThreshold, starParam.LineThresholdProjected, starParam.LineThresholdBinarized, starParam.SuppressNonmaxSize, keyPoints.Length, keyPoints.Length > 0 ? (sbResult.ToString()   "\r\n") : "");
        }

        //获取默认的Star关键点检测参数
        private void btnStarGetDefaultParams_Click(object sender, EventArgs e)
        {
            StarDetector starParam = new StarDetector();
            starParam.SetDefaultParameters();
            cmbStarMaxSize.SelectedItem = starParam.MaxSize.ToString();
            txtStarResponseThreshold.Text = starParam.ResponseThreshold.ToString();
            txtStarLineThresholdProjected.Text = starParam.LineThresholdProjected.ToString();
            txtStarLineThresholdBinarized.Text = starParam.LineThresholdBinarized.ToString();
            txtStarSuppressNonmaxSize.Text = starParam.SuppressNonmaxSize.ToString();
        }

        //获取默认的MSER参数
        private void btnMserGetDefaultParams_Click(object sender, EventArgs e)
        {
            MCvMSERParams param = MCvMSERParams.GetDefaultParameter();
            txtMserDelta.Text = param.delta.ToString();
            txtMserMaxArea.Text = param.maxArea.ToString();
            txtMserMinArea.Text = param.minArea.ToString();
            txtMserMaxVariation.Text = param.maxVariation.ToString();
            txtMserMinDiversity.Text = param.minDiversity.ToString();
            txtMserMaxEvolution.Text = param.maxEvolution.ToString();
            txtMserAreaThreshold.Text = param.areaThreshold.ToString();
            txtMserMinMargin.Text = param.minMargin.ToString();
            txtMserEdgeBlurSize.Text = param.edgeBlurSize.ToString();
        }

        //MSER(区域)特征检测
        private string MserFeatureDetect()
        {
            //获取参数
            MCvMSERParams mserParam = new MCvMSERParams();
            mserParam.delta = int.Parse(txtMserDelta.Text);
            mserParam.maxArea = int.Parse(txtMserMaxArea.Text);
            mserParam.minArea = int.Parse(txtMserMinArea.Text);
            mserParam.maxVariation = float.Parse(txtMserMaxVariation.Text);
            mserParam.minDiversity = float.Parse(txtMserMinDiversity.Text);
            mserParam.maxEvolution = int.Parse(txtMserMaxEvolution.Text);
            mserParam.areaThreshold = double.Parse(txtMserAreaThreshold.Text);
            mserParam.minMargin = double.Parse(txtMserMinMargin.Text);
            mserParam.edgeBlurSize = int.Parse(txtMserEdgeBlurSize.Text);
            bool showDetail = cbMserShowDetail.Checked;
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            MemStorage storage = new MemStorage();
            Seq<Point>[] regions = imageSource.ExtractMSER(null, ref mserParam, storage);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            StringBuilder sbResult = new StringBuilder();
            int idx = 0;
            foreach (Seq<Point> region in regions)
            {
                imageResult.DrawPolyline(region.ToArray(), true, new Bgr(255d, 0d, 0d), 2);
                if (showDetail)
                {
                    sbResult.AppendFormat("第{0}区域,包含{1}个顶点(", idx, region.Total);
                    foreach (Point pt in region)
                        sbResult.AppendFormat("{0},", pt);
                    sbResult.Append(")\r\n");
                }
                idx  ;
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            storage.Dispose();
            //返回
            return string.Format("·MSER区域,用时{0:F05}毫秒,参数(delta:{1},maxArea:{2},minArea:{3},maxVariation:{4},minDiversity:{5},maxEvolution:{6},areaThreshold:{7},minMargin:{8},edgeBlurSize:{9}),检测到{10}个区域\r\n{11}",
                sw.Elapsed.TotalMilliseconds, mserParam.delta, mserParam.maxArea, mserParam.minArea, mserParam.maxVariation, mserParam.minDiversity,
                mserParam.maxEvolution, mserParam.areaThreshold, mserParam.minMargin, mserParam.edgeBlurSize, regions.Length, showDetail ? sbResult.ToString() : "");
        }

        //FAST关键点
        private string FASTKeyPointFeatureDetect()
        {
            //获取参数
            int threshold = int.Parse(txtFASTThreshold.Text);
            bool nonmaxSuppression = cbFASTNonmaxSuppression.Checked;
            bool showDetail = cbFASTShowDetail.Checked;
            //计算
            Stopwatch sw = new Stopwatch();
            sw.Start();
            MKeyPoint[] keyPoints = imageSourceGrayscale.GetFASTKeypoints(threshold, nonmaxSuppression);
            sw.Stop();
            //显示
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            StringBuilder sbResult = new StringBuilder();
            int idx = 0;
            foreach (MKeyPoint keypoint in keyPoints)
            {
                imageResult.Draw(new CircleF(keypoint.Point, (int)(keypoint.Size / 2)), new Bgr(255d, 0d, 0d), (int)(keypoint.Size / 4));
                if (showDetail)
                    sbResult.AppendFormat("第{0}点(坐标:{1},尺寸:{2},方向:{3}°,响应:{4},octave:{5}),",
                                idx, keypoint.Point, keypoint.Size, keypoint.Angle, keypoint.Response, keypoint.Octave);
                idx  ;
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            imageResult.Dispose();
            //返回
            return string.Format("·FAST关键点,用时{0:F05}毫秒,参数(阀值:{1},nonmaxSupression:{2}),检测到{3}个关键点\r\n{4}",
                sw.Elapsed.TotalMilliseconds, threshold, nonmaxSuppression, keyPoints.Length, showDetail ? (sbResult.ToString()   "\r\n") : "");
        }

        //SIFT关键点
        private string SiftFeatureDetect()
        {
            //获取参数
            int noctaves = int.Parse(txtSiftNumberOfOctaves.Text);
            int nlevels = int.Parse(txtSiftNumberOfLayersPerOctave.Text);
            int o_min = int.Parse(txtSiftOmin.Text);
            bool showDetail = cbSiftShowDetail.Checked;
            bool usePinvoke = rbSiftPinvoke.Checked;
            if (usePinvoke)
                return SiftFeatureDetectByPinvoke(noctaves, nlevels, o_min, showDetail);
            else
                return SiftFeatureDetectByDotNet(noctaves, nlevels, o_min, showDetail);
        }

        //通过P/Invoke调用vlfeat函数来进行SIFT检测
        unsafe private string SiftFeatureDetectByPinvoke(int noctaves, int nlevels, int o_min, bool showDetail)
        {
            StringBuilder sbResult = new StringBuilder();
            //初始化
            IntPtr ptrSiftFilt = VlFeatInvoke.vl_sift_new(imageSource.Width, imageSource.Height, noctaves, nlevels, o_min);
            if (ptrSiftFilt == IntPtr.Zero)
                return "Sift特征检测:初始化失败。";
            //处理
            Image<Gray, Single> imageSourceSingle = imageSourceGrayscale.ConvertScale<Single>(1d, 0d);
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            int pointCount = 0;
            int idx = 0;
            //依次遍历每一组
            if (VlFeatInvoke.vl_sift_process_first_octave(ptrSiftFilt, imageSourceSingle.MIplImage.imageData) != VlFeatInvoke.VL_ERR_EOF)
            {
                while (true)
                {
                    //计算每组中的关键点
                    VlFeatInvoke.vl_sift_detect(ptrSiftFilt);
                    //遍历并绘制每个点
                    VlSiftFilt siftFilt = (VlSiftFilt)Marshal.PtrToStructure(ptrSiftFilt, typeof(VlSiftFilt));
                    pointCount  = siftFilt.nkeys;
                    VlSiftKeypoint* pKeyPoints = (VlSiftKeypoint*)siftFilt.keys.ToPointer();
                    for (int i = 0; i < siftFilt.nkeys; i  )
                    {
                        VlSiftKeypoint keyPoint = *pKeyPoints;
                        pKeyPoints  ;
                        imageResult.Draw(new CircleF(new PointF(keyPoint.x, keyPoint.y), keyPoint.sigma / 2), new Bgr(255d, 0d, 0d), 2);
                        if (showDetail)
                            sbResult.AppendFormat("第{0}点,坐标:({1},{2}),阶:{3},缩放:{4},s:{5},", idx, keyPoint.x, keyPoint.y, keyPoint.o, keyPoint.sigma, keyPoint.s);
                        idx  ;
                        //计算并遍历每个点的方向
                        double[] angles = new double[4];
                        int angleCount = VlFeatInvoke.vl_sift_calc_keypoint_orientations(ptrSiftFilt, angles, ref keyPoint);
                        if (showDetail)
                            sbResult.AppendFormat("共{0}个方向,", angleCount);
                        for (int j = 0; j < angleCount; j  )
                        {
                            double angle = angles[j];
                            if (showDetail)
                                sbResult.AppendFormat("【方向:{0},描述:", angle);
                            //计算每个方向的描述
                            IntPtr ptrDescriptors = Marshal.AllocHGlobal(128 * sizeof(float));
                            VlFeatInvoke.vl_sift_calc_keypoint_descriptor(ptrSiftFilt, ptrDescriptors, ref keyPoint, angle);
                            float* pDescriptors = (float*)ptrDescriptors.ToPointer();
                            for (int k = 0; k < 128; k  )
                            {
                                float descriptor = *pDescriptors;
                                pDescriptors  ;
                                if (showDetail)
                                    sbResult.AppendFormat("{0},", descriptor);
                            }
                            sbResult.Append("】,");
                            Marshal.FreeHGlobal(ptrDescriptors);
                        }
                    }
                    //下一阶
                    if (VlFeatInvoke.vl_sift_process_next_octave(ptrSiftFilt) == VlFeatInvoke.VL_ERR_EOF)
                        break;
                }
            }
            //显示
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            VlFeatInvoke.vl_sift_delete(ptrSiftFilt);
            imageSourceSingle.Dispose();
            imageResult.Dispose();
            //返回
            return string.Format("·SIFT特征检测(P/Invoke),用时:未统计,参数(阶数:{0},每阶层数:{1},最小阶索引:{2}),{3}个关键点\r\n{4}",
                noctaves, nlevels, o_min, pointCount, showDetail ? (sbResult.ToString()   "\r\n") : "");
        }

        //通过dotnet封装的SiftDetector类来进行SIFT检测
        private string SiftFeatureDetectByDotNet(int noctaves, int nlevels, int o_min, bool showDetail)
        {
            //初始化对象
            SiftDetector siftDetector = new SiftDetector(imageSource.Size, noctaves, nlevels, o_min);
            //计算
            Image<Gray, Single> imageSourceSingle = imageSourceGrayscale.Convert<Gray, Single>();
            Stopwatch sw = new Stopwatch();
            sw.Start();
            List<SiftFeature> features = siftDetector.Process(imageSourceSingle, showDetail ? SiftDetectorResultType.Extended : SiftDetectorResultType.Basic);
            sw.Stop();
            //显示结果
            Image<Bgr, Byte> imageResult = imageSourceGrayscale.Convert<Bgr, Byte>();
            StringBuilder sbResult = new StringBuilder();
            int idx=0;
            foreach (SiftFeature feature in features)
            {
                imageResult.Draw(new CircleF(new PointF(feature.keypoint.x, feature.keypoint.y), feature.keypoint.sigma / 2), new Bgr(255d, 0d, 0d), 2);
                if (showDetail)
                {
                    sbResult.AppendFormat("第{0}点,坐标:({1},{2}),阶:{3},缩放:{4},s:{5},",
                        idx, feature.keypoint.x, feature.keypoint.y, feature.keypoint.o, feature.keypoint.sigma, feature.keypoint.s);
                    sbResult.AppendFormat("共{0}个方向,", feature.keypointOrientations != null ? feature.keypointOrientations.Length : 0);
                    if (feature.keypointOrientations != null)
                    {
                        foreach (SiftKeyPointOrientation orientation in feature.keypointOrientations)
                        {
                            if (orientation.descriptors != null)
                            {
                                sbResult.AppendFormat("【方向:{0},描述:", orientation.angle);
                                foreach (float descriptor in orientation.descriptors)
                                    sbResult.AppendFormat("{0},", descriptor);
                            }
                            else
                                sbResult.AppendFormat("【方向:{0},", orientation.angle);
                            sbResult.Append("】,");
                        }
                    }
                }
            }
            pbResult.Image = imageResult.Bitmap;
            //释放资源
            siftDetector.Dispose();
            imageSourceSingle.Dispose();
            imageResult.Dispose();
            //返回
            return string.Format("·SIFT特征检测(.net),用时:{0:F05}毫秒,参数(阶数:{1},每阶层数:{2},最小阶索引:{3}),{4}个关键点\r\n{5}",
                sw.Elapsed.TotalMilliseconds, noctaves, nlevels, o_min, features.Count, showDetail ? (sbResult.ToString()   "\r\n") : "");
        }
    }
}

标签: 像素

实例下载地址

像素处理

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警