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