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); } } }