c# OpenCvSharp HoughLinesP 霍夫变换直线检测

c# OpenCvSharp HoughLinesP 霍夫变换直线检测

using OpenCvSharp;
using OpenCvSharp.Extensions;
using DlibDotNet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace app
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 直线检测
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnHoughLinesP_Click(object sender, EventArgs e)
        {
            // 加载图像
            Mat src = Cv2.ImRead(@"img\bianxing1.png");
            Cv2.ImShow("原图", src);

            // 灰度处理
            Mat grayMat = new Mat();
            Cv2.CvtColor(src, grayMat, ColorConversionCodes.BGR2GRAY);
            Cv2.ImShow("灰度处理", grayMat);

            // 模糊处理 降低噪音
            Mat blurMat = new Mat();
            Cv2.GaussianBlur(grayMat, blurMat, new OpenCvSharp.Size(3, 3), 9, 9);
            Cv2.ImShow("高斯滤波", blurMat);

            // 二值处理
            Mat binaryMat = new Mat();
            Cv2.Threshold(blurMat, binaryMat, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
            Cv2.ImShow("二值处理", binaryMat);

            // 形态学操作
            // 闭运算
            // 先膨胀后腐蚀。能够排除小黑点。
            Mat morphMat = new Mat();
            Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(9, 9), new OpenCvSharp.Point(-1, -1));
            Cv2.MorphologyEx(binaryMat, morphMat, MorphTypes.Close, kernel, new OpenCvSharp.Point(-1, -1), 3);
            Cv2.ImShow("形态学操作", morphMat);
            
            // 按位运算
            // opencv非运算不是1变0,0变1。而是 !x = 255 - x
            Cv2.BitwiseNot(morphMat, morphMat, new Mat());
            Cv2.ImShow("按位运算 BitwiseNot", morphMat);

            // 轮廓发现
            OpenCvSharp.Point[][] contours;
            HierarchyIndex[] hierarchy;
            Cv2.FindContours(morphMat, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point());

            // 轮廓绘制
            int width = src.Cols;
            int height = src.Rows;
            Mat drawImg = Mat.Zeros(src.Size(), MatType.CV_8UC3);
            for (int i = 0; i < contours.Length; i++)
            {
                Rect rect = Cv2.BoundingRect(contours[i]);
                // 过滤
                if (rect.Width > width / 4 && rect.Width < width - 10)
                {
                    Cv2.DrawContours(drawImg, contours, i, new Scalar(0, 0, 255), 2, LineTypes.Link8, hierarchy);
                }
            }
            Cv2.ImShow("轮廓", drawImg);

            // 灰度转换
            Mat contoursImg = new Mat();
            int accu = Math.Min(width / 2, height / 2);
            Cv2.CvtColor(drawImg, contoursImg, ColorConversionCodes.BGR2GRAY);

            // 霍夫变换直线检测
            // 参数说明
            /*
            image:输入图像。8 bit 灰度图。
            lines:存储线段极坐标的容器,每一条线由具有四个元素的矢量(x_1, y_1, x_2, y_2) 表示,其中(x_1, y_1)和(x_2, y_2) 是每个检测到的线段的结束点。
            rho:生成极坐标的像素扫描步长。
            theta:生成极坐标的角度步长,一般是π / 180。
            threshold:要“检测” 一条直线所需最少的的曲线交点。
            minLineLength:默认值 0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
            maxLineGap:默认值 0,允许将同一行点与点之间连接起来的最大的距离。
            */
            LineSegmentPoint[] lines = Cv2.HoughLinesP(contoursImg, 1, Math.PI / 180.0, accu / 5, accu / 5);
            Mat linesImg = Mat.Zeros(src.Size(), MatType.CV_8UC3);
            for (int i = 0; i < lines.Length; i++)
            {
                Cv2.Line(linesImg, lines[i].P1, lines[i].P2, new Scalar(0, 255, 0), 1, LineTypes.Link8);
            }
            Cv2.ImShow("霍夫变换直线检测", linesImg);
        }
    }
}

 

发表回复

您的电子邮箱地址不会被公开。