EmguCV学习笔记 C# 6.3 轮廓外接多边形

news2024/12/27 16:33:14

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。

教程VB.net版本请访问:EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问:EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码,请移步:EmguCV学习笔记

学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客

 学习C#知识,请移步:C# 教程 目录_c#教程目录-CSDN博客

6.3 轮廓外接多边形

6.3.1 最大外接矩形BoundingRectangle 

CvInvoke.BoundingRectangle方法用于获得轮廓的最大外接矩形。该方法其中一个声明:

public static Rectangle BoundingRectangle(

           IInputArray points

)

参数说明:

  1. points:要计算最大外接矩形的轮廓。这是一个VectorOfPoint类型。对应使用FindContours方法获得的contours所包含的成员。

返回值:

返回一个Rectangle对象,表示计算得到的最大矩形的位置和大小。

代码参看6.3.2节【minAreaRect】中的示例。

6.3.2 最小外接矩形minAreaRect

在Emgu.CV中,CvInvoke.MinAreaRect函数用于计算轮廓的最小外接矩形。它的用法如下:

public static RotatedRect MinAreaRect(

           IInputArray points

)

参数说明:

  1. points:要计算最大外接矩形的轮廓。这是一个VectorOfPoint类型。对应使用FindContours方法获得的contours所包含的成员。

返回值:

返回一个RotatedRect对象,表示计算得到的最小外接矩形。通过RotatedRect的GetVertices方法返回四个顶点,然后可使用CvInvoke.Polylines绘制。

【代码位置:frmChapter6】Button8_Click

       private void Button8_Click(object sender, EventArgs e)

        {

            Mat msrc = new Mat("C:\\learnEmgucv\\shape2.jpg", ImreadModes.Color);

            //转灰度

            Mat mgray = new Mat();

            CvInvoke.CvtColor(msrc, mgray, ColorConversion.Bgr2Gray);

            //二值化

            Mat mmid = new Mat();

            CvInvoke.Threshold(mgray, mmid, 150, 255, ThresholdType.BinaryInv);

            ImageBox1.Image = mmid;

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            VectorOfRect hierarchy = new VectorOfRect();

            //获得轮廓

            CvInvoke.FindContours(mmid, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

            //绘制最大外接矩形的图像

            Mat mmax = new Mat();

            mmax = msrc.Clone();

            //绘制最小外接矩形的图像

            Mat mmin = new Mat();

            mmin = msrc.Clone();

            for(int i = 0;i< contours.Size;i++)

            {

                //获得最大外接矩形

                Rectangle rectmax = CvInvoke.BoundingRectangle(contours[i]);

                CvInvoke.Rectangle(mmax, rectmax, new MCvScalar(255), 2);

                //获得最小外接矩形

                RotatedRect rectmin = CvInvoke.MinAreaRect(contours[i]);

                PointF[] pf = rectmin.GetVertices();

                //实现数组PointF到数组Point的转换

                Point[] pf1= Array.ConvertAll(pf, new Converter<PointF, Point>(PointFToPoint));

                //不能按照矩形绘制,只能绘制多边形

                CvInvoke.Polylines(mmin, pf1, true, new MCvScalar(255, 0, 0), 2);

            }

            ImageBox2.Image = mmax;

            ImageBox3.Image = mmin;

        }

运行后如下图所示:

 

图6-9 绘制轮廓的最大外接矩形和最小外接矩形

【代码位置:frmChapter6】Button9_Click

        //外接多边形:最大外接矩形 最小外接矩形

        //Image来代替mat完成最后的绘制

        private void Button9_Click(object sender, EventArgs e)

        {

            Mat m1 = new Mat("C:\\learnEmgucv\\shape2.jpg", ImreadModes.Grayscale);

            ImageBox1.Image = m1;

            Mat mid1 = new Mat();

            CvInvoke.Threshold(m1, mid1, 150, 255, ThresholdType.BinaryInv);

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            VectorOfRect hierarchy = new VectorOfRect();

            CvInvoke.FindContours(mid1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

            Image<Bgr, byte> m2 = new Image<Bgr, byte>("C:\\learnEmgucv\\shape2.jpg");

            //最大外接矩形

            Image<Bgr, byte> mmax = new Image<Bgr, byte>(m2.Width, m2.Height);

            mmax = m2.Clone();

            //最小外接矩形

            Image<Bgr, byte> mmin = new Image<Bgr, byte>(m2.Width, m2.Height);

            mmin = m2.Clone();

            for (int i = 0; i < contours.Size;i++)

            {

                //最大外接矩形

                Rectangle rectmax = CvInvoke.BoundingRectangle(contours[i]);

                mmax.Draw(rectmax, new Bgr(0, 255, 0), 2);

                //或者以下代码:

                //CvInvoke.Rectangle(mmax, rectmax, new MCvScalar(255), 2);

                RotatedRect rectmin = CvInvoke.MinAreaRect(contours[i]);

                mmin.Draw(rectmin, new Bgr(0, 255, 0), 2);

                //或者以下代码:

                //PointF[] pf = rectmin.GetVertices();

                //Point[] pf1 = Array.ConvertAll(pf, new Converter<PointF, Point>(PointFToPoint));

                //CvInvoke.Polylines(mmin, pf1, true, new MCvScalar(255, 0, 0), 2);

            }

            ImageBox2.Image = mmax;

            ImageBox3.Image = mmin;

        }

运行后如下图所示:

 

图6-10 绘制轮廓的最大外接矩形和最小外接矩形

6.3.3 多边形逼近ApproxPolyDP       

CvInvoke.ApproxPolyDP方法用于对轮廓进行多边形逼近。声明如下:

public static void ApproxPolyDP(

           IInputArray curve,

                    IOutputArray approxCurve,

                    double epsilon,

           bool closed

)

参数说明:

  1. curve:要进行逼近的轮廓。这是一个VectorOfPoint类型。对应使用FindContours方法获得的contours所包含的成员。
  2. approxCurve:输出逼近后的多边形曲线。
  3. epsilon:逼近精度,即逼近后的多边形曲线与原轮廓的最大距离。
  4. closed:表示逼近后的多边形曲线是否是闭合的。如果为True,表示闭合;如果为False,表示开放。

【代码位置:frmChapter6】Button10_Click

        //外接多边形

        private void Button10_Click(object sender, EventArgs e)

        {

            Mat msrc = new Mat("C:\\learnEmgucv\\shape2.jpg", ImreadModes.Grayscale);

            ImageBox1.Image = msrc;

            Mat mid1 = new Mat();

            CvInvoke.Threshold(msrc, mid1, 150, 255, ThresholdType.BinaryInv);

            ImageBox2.Image = mid1;

            //查找轮廓

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            VectorOfRect hierarchy = new VectorOfRect();

            CvInvoke.FindContours(mid1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

            Mat mpoly = new Mat(msrc.Size, DepthType.Cv8U, 3);

            mpoly.SetTo(new MCvScalar(255, 255, 255));

        for(int i = 0;i< contours.Size;i++)

            {

                VectorOfPoint result = new VectorOfPoint();

                //获得逼近后的多边形曲线

                CvInvoke.ApproxPolyDP(contours[i], result, 4, true);

                Point[] p = result.ToArray();

                //绘制多边形

                CvInvoke.Polylines(mpoly, p, true, new MCvScalar(255, 0, 0), 2);

                //输出多边形的边数

                CvInvoke.PutText(mpoly, p.Length.ToString(), new Point(p[p.Length - 1].X - 20, p[p.Length - 1].Y), FontFace.HersheyComplex, 1, new MCvScalar(0, 0, 255), 1);

            }

            ImageBox3.Image = mpoly;

        }

运行后如下图所示:

 

图6-11 绘制轮廓外接多边形

6.3.4 最小外接圆MinEnclosingCircle

CvInvoke.MinEnclosingCircle方法用于计算轮廓的最小外接圆。它的声明之一:

public static CircleF MinEnclosingCircle(

           IInputArray points

)

示例参看6.3.6节 【FitEllipse】代码。

6.3.5 最小外接三角形MinEnclosingTriangle

CvInvoke.MinEnclosingTriangle方法用于计算轮廓的最小外接三角形。它的声明如下:

public static double MinEnclosingTriangle(

    IInputArray points,

    IOutputArray triangles

)

示例参看6.3.6节 【FitEllipse】代码。

6.3.6 拟合椭圆FitEllipse     

CvInvoke.FitEllipse方法用于拟合给定点集的椭圆。它的声明如下:

public static RotatedRect FitEllipse(

           IInputArray points

)

【代码位置:frmChapter6】Button11_Click

        //最小外接三角形、最小外接圆、拟合椭圆

        private void Button11_Click(object sender, EventArgs e)

        {

            Mat m1 = new Mat("C:\\learnEmgucv\\shape2.jpg", ImreadModes.Grayscale);

            //ImageBox1.Image = m1;

            Mat mid1 = new Mat();

            CvInvoke.Threshold(m1, mid1, 150, 255, ThresholdType.BinaryInv);

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            VectorOfRect hierarchy = new VectorOfRect();

            CvInvoke.FindContours(mid1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

            Mat m2 = new Mat("C:\\learnEmgucv\\shape2.jpg", ImreadModes.AnyColor);

            //外接三角形

            Mat mtriangle = new Mat();

            mtriangle = m1.Clone();

            //外接圆形

            Mat mcircle = new Mat();

            mcircle = m1.Clone();

            //拟合椭圆

            Mat mEllipse = new Mat();

            mEllipse = m1.Clone();

            VectorOfPoint triangle = new VectorOfPoint();

            for (int i = 0; i < contours.Size; i++)

            {

                //获得外接三角形

                Double trianglearea = CvInvoke.MinEnclosingTriangle(contours[i], triangle);

                //使用封闭多边形来绘制三角形,也可以用line来绘制

                CvInvoke.Polylines(mtriangle, triangle, true, new MCvScalar(0), 2);

                CircleF cf = CvInvoke.MinEnclosingCircle(contours[i]);

                //获得外接圆形

                CvInvoke.Circle(mcircle, new Point((int)(cf.Center.X), (int)(cf.Center.Y)), (int)cf.Radius, new MCvScalar(0), 2);

                //获得拟合椭圆

                RotatedRect rr = CvInvoke.FitEllipse(contours[i]);

                CvInvoke.Ellipse(mEllipse, rr, new MCvScalar(0), 2);

            }

            ImageBox1.Image = mtriangle;

            ImageBox2.Image = mcircle;

            ImageBox3.Image = mEllipse;

        }

运行后如下图所示:

 

图6-12 轮廓的最小外接三角形、最小外接圆、拟合椭圆

6.3.7 拟合直线FitLine

拟合直线是指利用图像中的点集,找到一条最匹配点集的直线,使得该直线能够尽可能地覆盖所有的点。通过拟合直线,可以得到图像中点的分布情况,从而可以进行轮廓提取、边缘检测等操作。例如,在目标检测中,可以通过拟合直线来定位目标对象的位置和方向;在图像处理中,可以通过拟合直线来进行图像的分割、去除噪声、边缘检测等。

在Emgu.CV中,CvInvoke.FitLine函数用于拟合给定点集的直线,它的声明如下:

public static void FitLine(

           IInputArray points,

                    IOutputArray line,

                    DistType distType,

                    double param,

                    double reps,

           double aeps

)

参数说明:

  1. input:输入的点集。
  2. line:输出的直线,这是一个VectorOfFloat类型,包含四个元素,其中line(0),line(1)是一个方向向量;line(2),line(3)是直线上一个点。可以通过此输出获得直线的斜率和截距:

斜率 = line (1) / line (0)

截距 = line (3) – 斜率 * line (2)

  1. distType:距离类型,可以是DistType.L1或者DistType.L2。
  2. param:距离类型的参数,和所选的距离类型有关,值可以设置为0,FitLine本身会自动选择最优化的值。
  3. reps:拟合直线的径向精度,默认为0.01。
  4. aeps:拟合直线的角度精度,默认为0.01。

【代码位置:frmChapter6】Button12_Click

        //FitLine

        private void Button12_Click(object sender, EventArgs e)

        {

            Mat m = new Mat(500, 500, DepthType.Cv8U, 3);

            Random rand = new Random();

            Point[] pts = new Point[20];

            //设置随机点

            for (int i = 0; i < 20; i++)

            {

                int x = rand.Next(0, 500);

                int y = rand.Next(0, 500);

                pts[i] = new Point(x, y);

                CvInvoke.Circle(m, pts[i], 3, new MCvScalar(0, 0, 255), -1);

            }

            VectorOfPoint vop = new VectorOfPoint(pts);

            VectorOfFloat vof = new VectorOfFloat();

            CvInvoke.FitLine(vop, vof, DistType.L2, 0, 0.01, 0.01);

            //计算斜率

            Double k = vof[1] / vof[0];

            //计算截距

            Double b = vof[3] - k * vof[2];

            //获得直线起点

            Point startpoint = new Point(0, (int)(b));

            //获得直线终点

            Point endpoint = new Point(m.Width - 1, (int)(k * (m.Width - 1) + b));

            CvInvoke.Line(m, startpoint, endpoint, new MCvScalar(255, 0, 0), 2);

            ImageBox1.Image = m;

        }

运行后如下图所示:

 

图6-13 获得拟合直线

6.3.8 最短距离pointPolygonTest      

CvInvoke.PointPolygonTest方法用于计算给定点到多边形的最短距离,或判断点是否在多边形内部。该方法声明如下:

public static double PointPolygonTest(

           IInputArray contour,

                    PointF pt,

           bool measureDist

)

参数说明:

  1. contour:轮廓。这是一个VectorOfPoint类型。对应使用FindContours方法获得的contours所包含的成员。
  2. pt:要计算的点的坐标。
  3. measureDist:如果设置为true,则计算最短距离;如果设置为false,则仅判断点是否在多边形内部。

返回值:

如果measureDist设置为true,则返回给定点到多边形的最短距离,正值表示点在多边形外部,负值表示点在多边形内部。

如果measureDist设置为false,则返回一个整数值:1表示点在多边形内部,0表示点在多边形边界上,-1表示点在多边形外部。

【代码位置:frmChapter6】Button13_Click

        //PointPolygonTest 轮廓外一点到轮廓的距离

        private void Button13_Click(object sender, EventArgs e)

        {

            Mat m = new Mat(400, 400, DepthType.Cv8U, 1);

            m.SetTo(new MCvScalar(0));

            //绘制一个矩形轮廓和一个圆形轮廓

            CvInvoke.Rectangle(m, new Rectangle(50, 50, 100, 100), new MCvScalar(255), -1);

            CvInvoke.Circle(m, new Point(300, 300), 100, new MCvScalar(255), -1);

            Mat m1 = new Mat();

            m1 = m.Clone();

            Point p1 = new Point(240, 100);

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            VectorOfRect hierarchy = new VectorOfRect();

            CvInvoke.FindContours(m1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

            List<Double> dis = new List<Double>();

            for (int i = 0; i < contours.Size; i++)

            {

                Double dis1 = CvInvoke.PointPolygonTest(contours[i], p1, true);

                dis.Add(dis1);

                //只看在轮廓的内外

                //点在轮廓上,返回0,不计算距离返回0

                //点在轮廓内,返回正数,不计算距离返回1

                //点在轮廓外,返回负数,不计算距离返回-1

                //Double dis2 = CvInvoke.PointPolygonTest(contours[i], p1, false);

                //Console.WriteLine(dis2);

            }

            CvInvoke.Circle(m1, p1, 2, new MCvScalar(255), -1);

            ImageBox1.Image = m1;

            //使用获得的距离绘制圆形

            Mat m3 = new Mat(400, 400, DepthType.Cv8U, 3);

            m3.SetTo(new MCvScalar(0));

            CvInvoke.Rectangle(m3, new Rectangle(50, 50, 100, 100), new MCvScalar(255, 255, 255), -1);

            CvInvoke.Circle(m3, new Point(300, 300), 100, new MCvScalar(255, 255, 255), -1);

            CvInvoke.Circle(m3, p1, 2, new MCvScalar(0, 0, 255), -1);

            for (int i = 0; i < dis.Count; i++)

                CvInvoke.Circle(m3, p1, (int)Math.Abs(dis[i]), new MCvScalar(0, 255, 0), 2);

            ImageBox2.Image = m3;

        }

运行后如下图所示:

 

图6-14 点到轮廓的外接圆

上述代码只能获得最小距离,如果要得到轮廓外一点到轮廓最小距离的轮廓上一点的坐标,可以采用以下方法:

1、图像M1上绘制图形A

2、获得图形A的轮廓A(M1上只有一个轮廓)

3、获得点A到图形A的最小距离d

4、图像M2上使用点A为圆心,最小距离d为半径画圆A

5、M2和M1做异或,得到圆A

6、获得圆A的轮廓B(M2上只有一个圆形的轮廓)

7、获得轮廓B上的每个点到轮廓A的距离,判断是否符合条件:理论上等于0就表示该点在轮廓A上,但是通常不会直接判断=0而是给定一个范围。

那么符合条件的点即为需要的坐标点。

实现代码如下:

【代码位置:frmChapter6】Button14_Click

        //获得点到轮廓的最短距离

        //以点为圆心,最短距离为半径画圆

        //获得圆的轮廓上的点,这里可能会出现误差

        //求出每个点到轮廓的最短距离

        //如果为0,那么这个点在轮廓上,

        //但是通常而言,会有偏差

        //感觉此方法误差比较大

        private void Button14_Click(object sender, EventArgs e)

        {

            Mat m = new Mat(400, 400, DepthType.Cv8U, 1);

            m.SetTo(new MCvScalar(0));

            CvInvoke.Rectangle(m, new Rectangle(50, 50, 100, 100), new MCvScalar(255), -1);

            ImageBox1.Image = m;

            Point p1 = new Point(240, 100);

            Mat m1 = new Mat();

            m1 = m.Clone();

            //求出点到形状的距离

            VectorOfVectorOfPoint contours1 = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(m1, contours1, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

            //这里只有一个形状轮廓,所以直接使用contours[0]

            Double dis1 = CvInvoke.PointPolygonTest(contours1[0], p1, true);

            //获得最短距离后画圆

            CvInvoke.Circle(m1, p1, (int)Math.Abs(dis1), new MCvScalar(255), 1);

            ImageBox2.Image = m1;

            //mm1异或,这里获得到刚才生成的圆形

            Mat m2 = new Mat();

            CvInvoke.BitwiseXor(m, m1, m2);

            VectorOfVectorOfPoint contours2 = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(m2, contours2, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

            //这里只有一个形状轮廓

            VectorOfPoint cirpoints = contours2[0];

            //保存形状上符合距离条件的点

            List<Point> shapes = new List<Point>();

            for(int i = 0;i< cirpoints.Size;i++)

            {

                Point cirp = new Point(cirpoints[i].X, cirpoints[i].Y);

                //不用计算距离,只需要获得是否在轮廓上

                Double dis = CvInvoke.PointPolygonTest(contours1[0], cirp, true);

                //小于2视为符合条件

                if (Math.Abs(dis) <= 1)

                    shapes.Add(cirp);

            }

            Mat m3 = new Mat();

            m3 = m.Clone();

            CvInvoke.CvtColor(m3, m3, ColorConversion.Gray2Bgr);

            //绘制点

            CvInvoke.Circle(m3, p1, 2, new MCvScalar(0, 0, 255), -1);

            //以点为圆心绘制圆,半径为最短距离

            CvInvoke.Circle(m3, p1, (int)Math.Abs(dis1), new MCvScalar(0, 255, 0), 1);

            //画出线段

            foreach (Point p in shapes)

                CvInvoke.Line(m3, p1, p, new MCvScalar(255, 0, 0), 1);

            ImageBox3.Image = m3;

        }

运行后如下图所示:

 

图6-15 轮廓与轮廓外一点最小距离的坐标点

通过运行结果,可以看出此方法获得的坐标点太多,误差比较大,为此在下面的代码中进行改进,采用平均值来获得坐标点。

【代码位置:frmChapter6】Button15_Click

        //获得点到轮廓的最短距离

        //对上面代码上的改进,增加了平均值

        private void Button15_Click(object sender, EventArgs e)

        {

            Mat m = new Mat(400, 400, DepthType.Cv8U, 1);

            m.SetTo(new MCvScalar(0));

            //CvInvoke.Circle(m, new Point(300, 300), 100, new MCvScalar(255), -1);

            CvInvoke.Rectangle(m, new Rectangle(50, 50, 100, 100), new MCvScalar(255), -1);

            ImageBox1.Image = m;

            Point p1 = new Point(240, 100);

            Mat m1 = new Mat();

            m1 = m.Clone();

            //求出点到形状的距离

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(m1, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

            //这里只有一个形状轮廓

            Double dis1 = CvInvoke.PointPolygonTest(contours[0], p1, true);

            CvInvoke.Circle(m1, p1, (int)Math.Abs(dis1), new MCvScalar(255), 1);

            ImageBox2.Image = m1;

            Mat m2 = new Mat();

            CvInvoke.BitwiseXor(m, m1, m2);

            //ImageBox3.Image = m2;

            VectorOfVectorOfPoint contours1 = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(m2, contours1, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

            //这里只有一个形状轮廓

            VectorOfPoint cirpoints = contours1[0];

            List<Point> shapes = new List<Point>();

            for (int i = 0; i < cirpoints.Size; i++)

            {

                Point cirp = new Point(cirpoints[i].X, cirpoints[i].Y);

                //不用计算距离,只需要获得是否在轮廓上

                Double dis = CvInvoke.PointPolygonTest(contours[0], cirp, true);

                //距离是否在设置范围,这里是3,多少都没所谓,后面要计算平均值

                if (Math.Abs(dis) <= 3)

                    shapes.Add(cirp);

            }

            Mat m3 = new Mat();

            m3 = m.Clone();

            CvInvoke.CvtColor(m3, m3, ColorConversion.Gray2Bgr);

            CvInvoke.Circle(m3, p1, (int)Math.Abs(dis1), new MCvScalar(0, 255, 0), 1);

            CvInvoke.Circle(m3, p1, 2, new MCvScalar(0, 0, 255), -1);

            Double totalx = 0;

            Double totaly = 0;

            Double avgx;

            Double avgy;

            //平均值计算点坐标

            for (int i = 0; i < shapes.Count; i++)

            {

                totalx += shapes[i].X;

                totaly += shapes[i].Y;

            }

            avgx = totalx / shapes.Count;

            avgy = totaly / shapes.Count;

            CvInvoke.Line(m3, p1, new Point((int)(avgx), (int)(avgy)), new MCvScalar(255, 0, 0), 1);

            ImageBox3.Image = m3;

        }

运行后如下图所示:

 

图6-16 轮廓与轮廓外一点最小距离的坐标点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2065666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ JAVA源码 HMAC计算 openssl 消息认证码计算 https消息防篡改 通信安全

签名和验签 把所有消息按顺序合并成一条信息&#xff0c;对这个信息用密钥进行签名。 签名信息通过 HTTP 头 Sign 传递&#xff0c;没有携带签名或者签名验证不通过的请求&#xff0c;将会被认为异常请求&#xff0c;并返回相应 code 码。 校验方法&#xff1a;根据 http请求…

【嵌入式裸机开发】智能家居入门7:最新ONENET,MQTT协议接入,最全最新(微信小程序、MQTT协议、ONENET云平台、STM32)

智能家居入门7 前言一、ONENET云平台创建产品与设备二、STM32端连接服务器前的准备三、STM32端实现四、微信小程序端连接服务器前的准备五、微信小程序端实现六、最终测试 前言 本篇文章介绍最新ONENET云平台的MQTT协议接入方法&#xff0c;在STM32上实现数据上云与服务器下发…

影像组学与病理组学在鼻咽癌领域的最新研究进展|文献速递·24-08-23

小罗碎碎念 今天这期推文收纳了人工智能在鼻咽癌领域的最新研究进展&#xff0c;既涉及影像组学也涉及病理组学。 在写这期推文的时候&#xff0c;刚好看到了国自然基金放榜的消息&#xff0c;在这里也祝各位关注小罗的老师能如愿上榜&#xff01;&#xff01; 正在积极备战…

LangChain框架深度解析:对Chains组件的全方位探索与实战案例

文章目录 前言一、Chains二、LLMChain⭐1.LLMChain介绍2.LLMChain案例 三、SimpleSequentialChain⭐1.SimpleSequentialChain介绍2.SimpleSequentialChain案例 四、SequentialChain⭐1.SequentialChain介绍2.SequentialChain案例 五、RouterChain⭐1.RouterChain介绍2.RouterCh…

ArcGIS空间自相关 (Global Moran‘s I)——探究人口空间格局的20年变迁

先了解什么是莫兰指数&#xff1f; 莫兰指数&#xff08;Morans I&#xff09;是一种用于衡量空间自相关性的统计量&#xff0c;即它可以帮助我们了解一个地理区域内的观测值是否彼此相关以及这种相关性的强度和方向。 白话版&#xff1a;一句话就是判断数据在空间上有没有自…

ChatGPT3.5/新手使用手册——在线使用详细操作步骤

成长路上不孤单&#x1f60a;【14后小学生一枚&#xff0c;C爱好者&#xff0c;持续分享所学&#xff0c;今日分享主题【ChatGPT新手使用手册】&#xff0c;需要欢迎收藏转发&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&…

学习笔记七:基于Jenkins+k8s+Git+DockerHub等技术链构建企业级DevOps容器云平台

基于Jenkinsk8sGitDockerHub等技术链构建企业级DevOps容器云平台 安装Jenkins在kubernetes中部署jenkins创建名称空间创建pv,上传pv.yaml创建pvc创建一个sa账号通过deployment部署jenkins更新资源清单文件把jenkins前端加上service&#xff0c;提供外部网络访问 配置Jenkins获取…

MQ的优缺点及适用场景

MQ的优缺点及适用场景 1、MQ的优点2、MQ的缺点 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 消息队列&#xff08;MQ&#xff09;在软件开发中扮演重要角色&#xff0c;带来解耦、异步、削峰等好处。然而&#xff0c;MQ的引入也伴随着一些…

【Hot100】LeetCode—101. 对称二叉树

目录 1- 思路借助队列 2- 实现⭐101. 对称二叉树——题解思路 3- ACM 实现 原题连接&#xff1a;101. 对称二叉树 1- 思路 借助队列 1- 创建队列&#xff1a;Queue<TreeNode> queue&#xff0c;初始化加入 root.left 和 root.right2- 判断逻辑&#xff1a;while(!queu…

为什么要进行微隔离

在当今数字化时代&#xff0c;随着云计算、大数据、物联网等技术的飞速发展&#xff0c;企业网络环境日益复杂&#xff0c;传统的网络边界防护策略面临着前所未有的挑战。传统的防火墙、入侵检测系统等安全设备虽然在一定程度上能够抵御外部威胁&#xff0c;但在内部网络的安全…

回归分析系列16— 多层次模型

119 多层次模型 19.1 简介 多层次模型&#xff08;也称为层次线性模型或混合效应模型&#xff09;在处理具有嵌套结构的数据时非常有用。例如&#xff0c;在教育数据中&#xff0c;学生嵌套在班级中&#xff0c;班级嵌套在学校中。多层次模型允许我们同时建模这些不同层次的影…

政安晨【零基础玩转各类开源AI项目】基于本地Linux Ubuntu系统部署及应用强大的开源AI音乐生成工具:AudioCraft

目录 简介 部署 下载项目 创建虚拟环境 激活虚拟环境 安装依赖 启动 成功 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 简介 A…

c++每日练习记录4-(递归思想)

题解1迭代&#xff1a; 利用利用两个新的指针&#xff0c;一个用于保存输出的初始节点&#xff0c;另外一个用于地址的迭代指向。 ListNode *mergeTwoLists(ListNode *list1, ListNode *list2){ListNode *list_node new ListNode(0);ListNode *list_node1 list_node;while (l…

看图学sql之sql 中的UNION 和union all

UNION 用于合并两个或者多个 SELECT 语句的结果集 语法&#xff1a; SELECT column1, column2 ... FROM table1, table2 [WHERE condition1]UNION / UNION ALLSELECT column1, column2 ... FROM table1, table2 [WHERE condition2] 数据分析社区直达 免费数据分析资料下载。…

C#使用 ModeBusTCP读取汇川Easy521PLC

Modbus TCP是一种基于以太网TCP/IP的Modbus协议变种&#xff0c;它允许Modbus协议在以太网网络上运行&#xff0c;使得设备之间可以通过IP网络交换数据。Modbus由MODICON公司于1979年开发&#xff0c;是一种工业现场总线协议标准&#xff0c;广泛应用于工业自动化领域。 #regio…

【嵌入式】总结指南——Linux下的裸机驱动开发

板型:正点原子 I.MX6UL MINI 屏幕&#xff1a;7寸 1024*600 立意&#xff1a;既是这一段学习的总结&#xff0c;也可作为入门指南的参考&#xff0c;不过并不能作为教程来看&#xff0c;实际学习还是要找相应的视频或文章教程。 一、历程 应该和使用这块板子的大部分人一样&a…

理解List AbstractList ArrayList

ArrayList 实现了 List 接口&#xff0c;继承了 AbstractList 抽象类。 Q: 为什么要ArrayList继承AbstractList&#xff0c;让AbstractList实现List&#xff1f;而不是让ArrayList直接实现List&#xff1f; A: 接口中全都是抽象的方法&#xff0c;而抽象类中可以有抽象方法&am…

【达梦数据库】shell脚本获取集群内确认监视器地址

目录 1、需求2、想法3、实现代码4、检验效果4.1、集群内任意节点使用非dmdba用户执行4.2、集群内任意节点使用dmdba用户执行4.2.1、数据库主备节点执行4.2.1、数据库确认监视器节点执行 4.3、非集群内节点执行 1、需求 有确认监视器的集群&#xff0c;在集群的任何一个集群上执…

Android13 app后台无法启动Abort background activity starts from

总纲 android13 rom 开发总纲说明 目录 1.前言 2.log分析 3.代码查找分析 4.修改方法 5.编译测试 6彩蛋 1.前言 Android13 用户app后台无法启动,提示Abort background activity starts from 10111 2.log分析 08-07 21:37:36.703: W/ActivityTaskManager(440): Back…

Llama3.1大模型

背景 Llama 3.1是一款由Meta&#xff08;前Facebook&#xff09;推出的先进大型语言模型。它在自然语言处理领域具有显著优势&#xff0c;为用户提供高质量的文本生成、理解和推理能力。 Transformer架构 Transformer是一种神经网络架构&#xff0c;可以处理文本、音频、视频和…