Emgu-WPF学习使用-Rectangle识别

简介: 原文:Emgu-WPF学习使用-Rectangle识别 环境:Win8 64位 Vs2015Emgu 版本:emgucv-windesktop 3.2.0.2682示例图上部流程:原图->灰度化->截断阈值化->中值模糊->高斯模糊->膨胀->腐蚀->Ostu二值化。
原文: Emgu-WPF学习使用-Rectangle识别

环境:Win8 64位 Vs2015

Emgu 版本:emgucv-windesktop 3.2.0.2682

示例图上部流程:原图->灰度化->截断阈值化->中值模糊->高斯模糊->膨胀->腐蚀->Ostu二值化。

// 灰度化
Image<Gray, byte> imgGray = new Image<Gray, byte>(imgSrc.Size);
CvInvoke.CvtColor(imgSrc, imgGray, ColorConversion.Bgr2Gray);

//截断阈值化
Image<Gray, byte> imgThresholdTrunc = new Image<Gray, byte>(imgGray.Size);
CvInvoke.Threshold(imgGray, imgThresholdTrunc, 60, 255, ThresholdType.Trunc);

// 中值模糊
Image<Gray, byte> imgMedian = imgThresholdTrunc.SmoothMedian(7); //使用5*5的卷积核

// 高斯模糊
Image<Gray, byte> imgGaussian = imgMedian.SmoothGaussian(5);
// 膨胀,消除杂点
Mat oMat2 = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,
    new System.Drawing.Size(5, 5), new System.Drawing.Point(0, 0));
Image<Gray, byte> imgErode = new Image<Gray, byte>(imgGray.Size);
CvInvoke.Erode(imgGaussian, imgErode, oMat2, new System.Drawing.Point(0, 0), 4,
    BorderType.Default, new MCvScalar(255, 0, 0, 255));

// 腐蚀,消除杂点
Image<Gray, byte> imgDilate = new Image<Gray, byte>(imgGray.Size);
CvInvoke.Dilate(imgErode, imgDilate, oMat2, new System.Drawing.Point(0, 0), 4,
    BorderType.Default, new MCvScalar(255, 0, 0, 255));

// Otsu二值化
Image<Gray, byte> imgThresholdOtsu = new Image<Gray, byte>(imgGray.Size);
CvInvoke.Threshold(imgDilate, imgThresholdOtsu, 0, 255, ThresholdType.Otsu);

示例图下部流程:原图->灰度化->截断阈值化->消除裂缝->Ostu二值化->识别Contours->绘制Contours.

// 灰度化
Image<Gray, byte> imgGray = new Image<Gray, byte>(imgSrc.Size);
CvInvoke.CvtColor(imgSrc, imgGray, ColorConversion.Bgr2Gray);

//截断阈值化
Image<Gray, byte> imgThresholdTrunc = new Image<Gray, byte>(imgGray.Size);
CvInvoke.Threshold(imgGray, imgThresholdTrunc, 60, 255, ThresholdType.Trunc);

// 消除裂缝
Mat oMat1 = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,
    new System.Drawing.Size(6, 6), new System.Drawing.Point(0, 0));
Image<Gray, byte> imgMorphologyEx = new Image<Gray, byte>(imgGray.Size);
CvInvoke.MorphologyEx(imgThresholdTrunc, imgMorphologyEx, Emgu.CV.CvEnum.MorphOp.Close, oMat1,
    new System.Drawing.Point(0, 0), 1, BorderType.Default,
    new MCvScalar(255, 0, 0, 255));

// Otsu二值化
Image<Gray, byte> imgThresholdOtsu = new Image<Gray, byte>(imgGray.Size);
CvInvoke.Threshold(imgMorphologyEx, imgThresholdOtsu, 0, 255, ThresholdType.Otsu);

List<RotatedRect> boxList = new List<RotatedRect>(); //a box is a rotated rectangle
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
CvInvoke.FindContours(imgThresholdOtsu, contours, null, RetrType.List,
    ChainApproxMethod.ChainApproxSimple);

Image<Bgr, byte> imgResult = new Image<Bgr, byte>(imgGray.Size);
CvInvoke.CvtColor(imgThresholdOtsu, imgResult, ColorConversion.Gray2Bgr);
MCvScalar oScaler = new MCvScalar(40, 255, 255, 255);
int count = contours.Size;
for (int i = 0; i < count; i++)
{
    using (VectorOfPoint contour = contours[i])
    using (VectorOfPoint approxContour = new VectorOfPoint())
    {
        CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
        double dArea = CvInvoke.ContourArea(approxContour, false);
        if (dArea > imgThresholdOtsu.Rows * imgThresholdOtsu.Cols / 3d)
        {
            if (approxContour.Size == 4)
            {
                #region determine if all the angles in the contour are within [80, 100] degree
                bool isRectangle = true;
                System.Drawing.Point[] pts = approxContour.ToArray();
                LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true);

                for (int j = 0; j < edges.Length; j++)
                {
                    double angle = Math.Abs(
                        edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
                    if (angle < 80 || angle > 100)
                    {
                        isRectangle = false;
                        break;
                    }
                }
                #endregion

                if (isRectangle)
                    CvInvoke.DrawContours(imgResult, contours, i, oScaler, 3);
            }
        }
    }
}

目录
相关文章
|
2月前
|
XML 开发框架 前端开发
WPF学习之基础知识篇
WPF(Windows Presentation Foundation)具有一个复杂且强大的架构,旨在提供丰富的用户界面、图形、动画和多媒体功能。
91 9
|
7月前
|
前端开发 C#
WPF学习小记
WPF学习小记
WPF学习—INotifyPropertyChanged Interface
WPF学习—INotifyPropertyChanged Interface
WPF学习—INotifyPropertyChanged Interface
|
C# 数据库
WPF学习—控件
WPF学习—控件
WPF学习—控件
|
C# 容器
WPF学习—Margin and Padding
WPF学习—Margin and Padding
WPF Binding学习(二)
  Binding作为数据的桥梁,连通业务逻辑层的对象(源对象)和UI的控件对象(目标对象)。在这座桥梁上,我们不仅可以控制在源对象与目标对象是双向通行还是单向通行。还可以控制数据的放行时机,甚至可以在这座桥上搭建一些关卡用来转换数据类型或者检验数据的正确性    我们先做一个最基本的例子,  ...
1189 0