void Hu(Image <Gray, byte> img, ref Double[] MomentHu, ref Double[] MomentR) { double r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0, r10 = 0; Image <Gray, byte> imgA = new Image <Gray, byte>(img.Size); imgA = img.ThresholdBinary(new Gray(60), new Gray(255)); Contour <Point> contourA = imgA.FindContours(); MCvMoments momentsA = contourA.GetMoments(); MCvHuMoments HuMomentsA = momentsA.GetHuMoment(); MomentHu[0] = HuMomentsA.hu1; MomentHu[1] = HuMomentsA.hu2; MomentHu[2] = HuMomentsA.hu3; MomentHu[3] = HuMomentsA.hu4; MomentHu[4] = HuMomentsA.hu5; MomentHu[5] = HuMomentsA.hu6; Rmoment(HuMomentsA.hu1, HuMomentsA.hu2, HuMomentsA.hu3, HuMomentsA.hu4, HuMomentsA.hu5, HuMomentsA.hu6, ref r1, ref r2, ref r3, ref r4, ref r5, ref r6, ref r7, ref r8, ref r9, ref r10); MomentR[0] = r1; MomentR[1] = r2; MomentR[2] = r3; MomentR[3] = r4; MomentR[4] = r5; MomentR[5] = r6; MomentR[6] = r7; MomentR[7] = r8; MomentR[8] = r9; MomentR[9] = r10; }
/// <summary> /// 选择轮廓并计算轮廓特征 /// </summary> private void NumListContours_ValueChanged(object sender, EventArgs e) { //先绘制此条轮廓 mArgs.FeatureType = ContourFeatureType.Contour; mArgs.ContourIndex = (int)NumListContours.Value; Params_Changed(); //再计算此条轮廓的特征 VectorOfPoint cnt = mContours[mArgs.ContourIndex]; TxtContourArea.Text = CvInvoke.ContourArea(cnt).ToString(); TxtArcLength.Text = CvInvoke.ArcLength(cnt, true).ToString(); MCvMoments moments = CvInvoke.Moments(cnt); TxtMoments.Text = string.Format("M00: {0}\r\nM01: {1}\r\nM02: {02}\r\nM03: {3}\r\nM10: {4}\r\nM11: {5}\r\nM12: {6}\r\nM20: {7}\r\nM21: {8}\r\nM30: {9}\r\n" + "Mu02: {10}\r\nMu03: {11}\r\nMu11: {12}\r\nMu12: {13}\r\nMu20: {14}\r\nMu21: {15}\r\nMu30: {16}", moments.M00, moments.M01, moments.M02, moments.M03, moments.M10, moments.M11, moments.M12, moments.M20, moments.M21, moments.M30, moments.Mu02, moments.Mu03, moments.Mu11, moments.Mu12, moments.Mu20, moments.Mu21, moments.Mu30); TxtContourCenter.Text = string.Format("({0},{1})", moments.M10 / moments.M00, moments.M01 / moments.M00); double[] huMoments = moments.GetHuMoment(); for (int i = 0; i < huMoments.Length; i++) { TxtHuMoments.Text += huMoments[i] + "\r\n"; } }
void Hu(Image <Gray, byte> img, ref Double[] MomentHu) { Image <Gray, byte> imgA = new Image <Gray, byte>(img.Size); imgA = img.ThresholdBinary(new Gray(60), new Gray(255)); Contour <Point> contourA = imgA.FindContours(); MCvMoments momentsA = contourA.GetMoments(); MCvHuMoments HuMomentsA = momentsA.GetHuMoment(); MomentHu[0] = HuMomentsA.hu1; MomentHu[1] = HuMomentsA.hu2; MomentHu[2] = HuMomentsA.hu3; MomentHu[3] = HuMomentsA.hu4; MomentHu[4] = HuMomentsA.hu5; MomentHu[5] = HuMomentsA.hu6; }
private Rectangle LocateROI() { int prediction = -1; VectorOfPoint contourOfInterest = new VectorOfPoint(); int index = 0; index = ImgProc.LargestContourIndex(_contour); contourOfInterest = _contour[index]; MCvMoments moment = CvInvoke.Moments(contourOfInterest); double[] huMoment = moment.GetHuMoment(); prediction = _svm.Compute(huMoment); //foreach (VectorOfPoint vp in _listOfContours.GetRange(0, 5)) //{ // MCvMoments moment = CvInvoke.Moments(vp); // double[] huMoment = moment.GetHuMoment(); // prediction = _svm.Compute(huMoment); // if (prediction == CLASSIFICATION_ARM || prediction == CLASSIFICATION_HAND) // { // contourOfInterest = vp; // break; // } //} if (prediction == CLASSIFICATION_REJECT) { return(Rectangle.Empty); } else if (prediction == CLASSIFICATION_HAND) { //Rectangle rectRotRect = rectRot.MinAreaRect(); //Rectangle init = CvInvoke.MinAreaRect(contoursEval1[largestContourIndexEval1]).MinAreaRect(); //Point final = new Point(rectRotRect.X + init.X, rectRotRect.Y + init.Y); //return new Rectangle(final, init.Size); return(CvInvoke.MinAreaRect(contourOfInterest).MinAreaRect()); } else if (prediction == CLASSIFICATION_ARM) { Mat convexityDefect = new Mat(); VectorOfInt hull = new VectorOfInt(); CvInvoke.ConvexHull(contourOfInterest, hull, false, false); CvInvoke.ConvexityDefects(contourOfInterest, hull, convexityDefect); RotatedRect rectRot = CvInvoke.MinAreaRect(contourOfInterest); ModifiedRotatedRect rotRectMod = new ModifiedRotatedRect(rectRot); int yDel = 0; double ptLftToRight = Geometry.Distance(rotRectMod.Pul, rotRectMod.Pur); double ptUpToDown = Geometry.Distance(rotRectMod.Pul, rotRectMod.Pll); if (!convexityDefect.IsEmpty) { Matrix <int> convex = new Matrix <int>(convexityDefect.Rows, convexityDefect.Cols, convexityDefect.NumberOfChannels); convexityDefect.CopyTo(convex); List <Point> contourTmp = new List <Point>(); for (int i = 0; i < contourOfInterest.Size; i++) { contourTmp.Add(contourOfInterest[i]); } List <ConvexDefects> convexDefectList = new List <ConvexDefects>(); for (int i = 0; i < convex.Rows; i++) { // do not touch int startIdx = convex.Data[i, 0]; int endIdx = convex.Data[i, 1]; int pointIdx = convex.Data[i, 2]; Point startPt = contourOfInterest[startIdx]; Point endPt = contourOfInterest[endIdx]; Point defectPt = contourOfInterest[pointIdx]; // do not touch convexDefectList.Add(new ConvexDefects(startPt, endPt, defectPt)); } if (ptLftToRight <= ptUpToDown) { Point pc1Tmp = convexDefectList[0].DefectPt; Point pc2Tmp = convexDefectList[1].DefectPt; Point pc = pc1Tmp.Y > pc2Tmp.Y ? pc1Tmp : pc2Tmp; Point ptUpLeft = rotRectMod.Pul; Point ptUpRight = rotRectMod.Pur; Point ptLowLeft = rotRectMod.Pll; Point ptLowRight = rotRectMod.Plr; ModifiedRotatedRect rotRectEval1 = ModifiedRotatedRect.Cut(ptUpLeft, ptUpRight, ptLowLeft, ptLowRight, pc); ModifiedRotatedRect rotRectEval2 = ModifiedRotatedRect.Cut(ptUpLeft, ptUpRight, ptLowLeft, ptLowRight, pc, true); Size sizeFrame = ImageInput.Size; Rectangle rectROIEval1 = rotRectEval1.ToRect(sizeFrame); Rectangle rectROIEval2 = rotRectEval2.ToRect(sizeFrame); Mat cloneMat1 = ImageInput.Clone().Mat; Mat matToBeEval1 = new Mat(cloneMat1, rectROIEval1); VectorOfVectorOfPoint contoursEval1 = new VectorOfVectorOfPoint(); Mat matHierachyEval1 = new Mat(); CvInvoke.FindContours(matToBeEval1, contoursEval1, matHierachyEval1, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxTc89L1); int largestContourIndexEval1 = ImgProc.LargestContourIndex(contoursEval1); MCvMoments momentEval1 = CvInvoke.Moments(contoursEval1[largestContourIndexEval1]); double[] huMomentsEval1 = momentEval1.GetHuMoment(); double[] featureVectorSearch = ScaleValues(huMomentsEval1, 5000.0); int predictionEval1 = _svm.Compute(featureVectorSearch, MulticlassComputeMethod.Elimination); //double[] featureVectorHand = ScaleValues(huMomentsEval1. // .GetRange(0, _svmMachineHand.Inputs).ToArray(), 1000.0); if (predictionEval1 == CLASSIFICATION_HAND) { Rectangle rectRotRect = rectRot.MinAreaRect(); Rectangle init = CvInvoke.MinAreaRect(contoursEval1[largestContourIndexEval1]).MinAreaRect(); Point final = new Point(rectRotRect.X + init.X, rectRotRect.Y + init.Y); return(new Rectangle(final, init.Size)); } else { return(Rectangle.Empty); } } else { return(Rectangle.Empty); } } else { return(Rectangle.Empty); } } else { return(Rectangle.Empty); } }
public void ComputeFeatures(Segment s) { //Add the relative size NamedFeature f = new NamedFeature("RelativeSize"); f.values.Add(s.points.Count() / (double)(imageWidth * imageHeight)); s.features.Add(f); // Relative centroid PointF c = NormalizedCentroid(s); s.features.Add(new NamedFeature("RelativeCentroid", new List <double> { c.X, c.Y })); // One interior point PointF np = RandomNormalizedInteriorPoint(s); s.features.Add(new NamedFeature("OneInteriorPoint", new List <double> { np.X, np.Y })); //Radial distance s.features.Add(new NamedFeature("RadialDistance", new List <double> { Math.Sqrt(c.X * c.X + c.Y * c.Y) })); //Normalized Discrete Compactness http://www.m-hikari.com/imf-password2009/25-28-2009/bribiescaIMF25-28-2009.pdf //Find the segment id Point sp = s.points.First(); int sidx = assignments[sp.X, sp.Y]; //count number of perimeter edges int perimeter = 0; foreach (Point p in s.points) { for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (Math.Abs(i) == Math.Abs(j)) { continue; } if (Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight) && assignments[p.X + i, p.Y + j] != sidx) { perimeter++; } else if (!Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight)) //edge pixels should be considered perimeter too { perimeter++; } } } } int n = s.points.Count(); double CD = (4.0 * n - perimeter) / 2; double CDmin = n - 1; double CDmax = (4 * n - 4 * Math.Sqrt(n)) / 2; double CDN = (CD - CDmin) / Math.Max(1, (CDmax - CDmin)); s.features.Add(new NamedFeature("NormalizedDiscreteCompactness", new List <double> { CDN })); //Add elongation (width/length normalized between 0-square to 1-long http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf PointF[] points = s.points.Select <Point, PointF>(p => new PointF(p.X, p.Y)).ToArray <PointF>(); Emgu.CV.Structure.MCvBox2D box = Emgu.CV.PointCollection.MinAreaRect(points); PointF[] vertices = box.GetVertices(); double elongation = 1 - Math.Min(box.size.Width + 1, box.size.Height + 1) / Math.Max(box.size.Width + 1, box.size.Height + 1); s.features.Add(new NamedFeature("Elongation", new List <double> { elongation })); //Add Hu shape moments, invariant to translation, scale, and rotation (not sure what each measure refers to intuitively though, or if there is an intuitive analog) //They may also do badly on noisy data however. See: http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf (called Invariant Moments) Bitmap regionBitmap = new Bitmap(imageWidth, imageHeight); Graphics g = Graphics.FromImage(regionBitmap); g.FillRectangle(new SolidBrush(Color.Black), 0, 0, imageWidth, imageHeight); foreach (Point p in s.points) { regionBitmap.SetPixel(p.X, p.Y, Color.White); } Emgu.CV.Image <Gray, byte> region = new Emgu.CV.Image <Gray, byte>(regionBitmap); MCvMoments moment = region.GetMoments(true); MCvHuMoments hu = moment.GetHuMoment(); s.features.Add(new NamedFeature("HuMoments", new List <double> { hu.hu1, hu.hu2, hu.hu3, hu.hu4, hu.hu5, hu.hu6, hu.hu7 })); region.Dispose(); regionBitmap.Dispose(); }