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