/// <summary>
        /// Calculates mean color of a blob in an image.
        /// </summary>
        /// <param name="blob">The blob.</param>
        /// <param name="originalImage">The original image</param>
        /// <returns>Average color</returns>
        public Bgr MeanColor(CvBlob blob, Image <Bgr, Byte> originalImage)
        {
            Bgr color = new Bgr();

            color.MCvScalar = cvbCvBlobMeanColor(blob, _ptr, originalImage);
            return(color);
        }
Esempio n. 2
0
 /// <summary>
 /// Calculates mean color of a blob in an image.
 /// </summary>
 /// <param name="blob">The blob.</param>
 /// <param name="originalImage">The original image</param>
 /// <returns>Average color</returns>
 public Bgr MeanColor(CvBlob blob, Image<Bgr, Byte> originalImage)
 {
     Bgr color = new Bgr();
      color.MCvScalar = CvInvoke.cvbCvBlobMeanColor(blob, _ptr, originalImage);
      return color;
 }
        /// <summary>
        /// 图漾获取产品特征及位置
        /// </summary>
        /// <param name="myblob"></param>
        /// <param name="point_3d"></param>
        /// <returns></returns>
        public static bool getProduceInfo(Emgu.CV.Cvb.CvBlob myblob, float[] point_3d)
        {
            //#########################################【1】,获取最小外接矩形中心点下标#################################################
            Point[]     ctr  = myblob.GetContour();                          //获取轮廓
            RotatedRect rect = CvInvoke.MinAreaRect(new VectorOfPoint(ctr)); //最小矩形

            PointF[] pt = CvInvoke.BoxPoints(rect);                          //最小外接矩形四个角点
            PointF   po = rect.Center;                                       //最小外接矩形中心
            int      xc = (int)po.X;                                         //最小外接矩形中心X坐标
            int      yc = (int)po.Y;                                         //最小外接矩形中心Y坐标

            //#########################################【2】,绘制外接最小矩形(紧贴连通域):#################################################
            for (int i = 0; i < 4; ++i)
            {
                Point p1 = new Point((int)pt[i].X, (int)pt[i].Y);
                //GLB.obj.jd.Add(p1);//角点存下备画轨迹用
                Point p2 = new Point((int)pt[(i + 1) % 4].X, (int)pt[(i + 1) % 4].Y);
                CvInvoke.Line(GLB.MyFrame, p1, p2, new MCvScalar(0, 0, 255), 2);
            }

            //#########################################【3】真实角点):#################################################
            List <Point3> pointReal = new List <Point3>();

            for (int i = 0; i < 4; ++i)
            {
                Point3 Ang_temp = new Point3(0, 0, 0);//0.8视场角点坐标
                Ang_temp.X = xc + 0.8 * (pt[i].X - xc);
                Ang_temp.Y = yc + 0.8 * (pt[i].Y - yc);

                if (Ang_temp.Y < 0 || Ang_temp.Y > 960 - 2 || Ang_temp.X < 0 || Ang_temp.X > 1280 - 2)
                {
                    return(false);                      ///////无效角点
                }
                Point3 Ang_point = new Point3(0, 0, 0); //0.8角点坐标
                Ang_point.X = point_3d[((int)Ang_temp.Y * GLB.BUFW + (int)Ang_temp.X) * 3 + 0];
                Ang_point.Y = point_3d[((int)Ang_temp.Y * GLB.BUFW + (int)Ang_temp.X) * 3 + 1];
                Ang_point.Z = point_3d[((int)Ang_temp.Y * GLB.BUFW + (int)Ang_temp.X) * 3 + 2];
                if (double.IsNaN(Ang_point.Z))
                {
                    return(false);                          ///////////////////////////////////////////////////////////无效角点
                }
                pointReal.Add(Ang_point);
                RotatedRect myrect = new RotatedRect(new PointF((float)Ang_temp.X, (float)Ang_temp.Y), new Size(8, 8), 0);
                CvInvoke.Ellipse(GLB.MyFrame, myrect, new MCvScalar(255, 0, 0), 2);//在角上一个小圆
            }
            //GLB.obj.Depth = (int)pointReal.Average(o => o.Z);//中心点的深度//Z
            //GLB.obj.yCenter = (int)pointReal.Average(o => o.Y);//Y
            //GLB.obj.xCenter = (int)pointReal.Average(o => o.X); ;//X
            ////#########################################队列求均值--获取中心坐标#################################################
            GLB.avgCameraPoint3.Enqueue(new Point3(pointReal.Average(o => o.X), pointReal.Average(o => o.Y), (int)pointReal.Average(o => o.Z)));
            if (GLB.avgCameraPoint3.Count > 5)
            {
                GLB.avgCameraPoint3.Dequeue();
            }
            else
            {
                return(false);
            }
            GLB.obj.Depth   = (int)GLB.avgCameraPoint3.Average(o => o.Z); //中心点的深度//Z
            GLB.obj.yCenter = (int)GLB.avgCameraPoint3.Average(o => o.Y); //Y
            GLB.obj.xCenter = (int)GLB.avgCameraPoint3.Average(o => o.X); //X
            //#########################################获取质心#################################################
            //PointF gravity = myblob.Centroid;
            //int gravity_x = (int)gravity.X;
            //int gravity_y = (int)gravity.Y;
            //if (double.IsNaN(point_3d[(gravity_y * GLB.BUFW + gravity_x) * 3 + 2])) return false;/////////////////////空值不执行
            //GLB.obj.Depth = (int)point_3d[(gravity_y * GLB.BUFW + gravity_x) * 3 + 2];//Z
            //GLB.obj.yCenter = (int)point_3d[(gravity_y * GLB.BUFW + gravity_x) * 3 + 1];//Y
            //GLB.obj.xCenter = (int)point_3d[(gravity_y * GLB.BUFW + gravity_x) * 3 + 0];//X

            //######################################### 显示本区块中心[画圆]:#################################################
            RotatedRect boxCenter = new RotatedRect(new PointF(xc, yc), new Size(8, 8), 0);

            CvInvoke.Ellipse(GLB.MyFrame, boxCenter, new MCvScalar(255, 0, 0), 4);                                                                                                                                                                                         //在中心画一个小圆
            CvInvoke.PutText(GLB.MyFrame, "x:" + xc + "y:" + yc + "XC=" + GLB.obj.xCenter + "YC=" + GLB.obj.yCenter + "Depth=" + GLB.obj.Depth, new System.Drawing.Point(xc - 176, yc + 25), Emgu.CV.CvEnum.FontFace.HersheyDuplex, .75, new MCvScalar(255, 255, 255), 2); //深度显示

            //#########################################【4】真实的长轴,短轴,倾角计算:#################################################
            double axisLong  = 1.25 * Math.Sqrt(Math.Pow(pointReal[1].X - pointReal[0].X, 2) + Math.Pow(pointReal[1].Y - pointReal[0].Y, 2) + Math.Pow(pointReal[1].Z - pointReal[0].Z, 2));
            double axisShort = 1.25 * Math.Sqrt(Math.Pow(pointReal[2].X - pointReal[1].X, 2) + Math.Pow(pointReal[2].Y - pointReal[1].Y, 2) + Math.Pow(pointReal[2].Z - pointReal[1].Z, 2));

            if (axisShort > axisLong)
            {
                double temp = axisLong;
                axisLong  = axisShort;
                axisShort = temp;
            }
            double Angl = rect.Angle;//矩形框角度

            // Angl *= 180d / Math.PI; //换算成角度制
            if (Math.Abs(Angl) > 45)
            {
                Angl = Angl + 90;
            }


            if (Angl >= 90)//控制旋转范围
            {
                Angl -= 180;
            }
            if (Angl <= -90)
            {
                Angl += 180;
            }
            //GLB.obj.Angle = Angl;//旋转角
            ////队列求均值
            GLB.avgAngle.Enqueue((float)Angl);
            if (GLB.avgAngle.Count > 5)
            {
                GLB.avgAngle.Dequeue();
            }
            else
            {
                return(false);
            }
            GLB.obj.Angle = GLB.avgAngle.Average();//旋转角


            GLB.obj.axisLong  = axisLong;             //长轴
            GLB.obj.axisShort = axisShort;            //短轴
            GLB.obj.L2S       = axisLong / axisShort; //长短轴之比;
            GLB.obj.realArea  = axisLong * axisShort; //估算的物件尺寸

            //像尺寸显示:
            CvInvoke.PutText(GLB.MyFrame, "Lr=" + (int)axisLong + ",Sr=" + (int)axisShort, new System.Drawing.Point((int)pt[2].X, (int)pt[2].Y), Emgu.CV.CvEnum.FontFace.HersheyDuplex, .75, new MCvScalar(0, 0, 255), 2);
            CvInvoke.PutText(GLB.MyFrame, "Angl=" + Angl, new System.Drawing.Point((int)pt[3].X, (int)pt[3].Y), Emgu.CV.CvEnum.FontFace.HersheyDuplex, .75, new MCvScalar(0, 0, 255), 2);
            return(true);
        }
        public static double CalculateBlobAngle(CvBlob blob)
        {
            //.5*atan2(2.*blob->u11,(blob->u20-blob->u02));

               double dy = 2.0*blob.BlobMoments.U11;
               double dx = blob.BlobMoments.U20 - blob.BlobMoments.U02;

               double result = 0.5*Math.Atan2(dy, dx);

               return result;
        }