/// <summary> /// Создаёт контур из внешних точек при помощи афинной гистограммы /// </summary> /// <param name="centerMode">Выбор центра внешнего контура</param> /// <param name="histogramScale">Число баров гистограммы 3*histogramScale* (длина стороны матрицы)</param> /// <param name="radiusScale">Скалированный радиус от центра</param> /// <returns></returns> public CvContourInfo ToAraundContour(CenterDrawMode centerMode = CenterDrawMode.BoundingRectCenter, int histogramScale = 1, double radiusScale = 1, MovingPredictType movingType = MovingPredictType.None, int movingRange = 1) { CvContourInfo araundContour = new CvContourInfo(); Point center = this.BoundingCenter; switch (centerMode) { case CenterDrawMode.PixelWeightCenter: center = this.WeightCenter; break; case CenterDrawMode.HistogramCenter: UpdateXYHistogram(); center = this.HistogramCenter; break; } araundContour.m_points = AraundPoints(center, m_points, histogramScale, radiusScale, movingType, movingRange); araundContour.Id = this.Id; araundContour.ParentId = this.ParentId; araundContour.MainColor = new MCvScalar(this.MainColor.V0, this.MainColor.V1, this.MainColor.V2); araundContour.PerimeterColor = new MCvScalar(this.PerimeterColor.V0, this.PerimeterColor.V1, this.PerimeterColor.V2); araundContour.Area = this.Area; araundContour.Perimeter = this.Perimeter; araundContour.BoundingRect = new Rectangle(this.BoundingRect.X, this.BoundingRect.Y, this.BoundingRect.Width, this.BoundingRect.Height); araundContour.BoundingCenter = new Point(this.BoundingCenter.X, this.BoundingCenter.Y); araundContour.WeightCenter = new Point(this.WeightCenter.X, this.WeightCenter.Y); araundContour.HistogramCenter = new Point(this.HistogramCenter.X, this.HistogramCenter.Y); return(araundContour); }
public void Update(Mat img, ChainApproxMethod method = ChainApproxMethod.ChainApproxNone) { m_contours.Clear(); Mat grayImg = img; if (img.NumberOfChannels > 1) { grayImg = new Mat(); CvInvoke.CvtColor(img, grayImg, ColorConversion.Bgr2Gray); } // hierachy[0][i] 0я иерархии для i-ого контура // hierachy[0][i][0] - индекс следующего контура на том же уровне // hierachy[0][i][1] - индекс предыдущий контура на том же уровне // hierachy[0][i][2] - Индекс потомка // hierachy[0][i][3] - Индекс родителя using (Mat hierachy = new Mat()) using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(grayImg, contours, hierachy, RetrType.Tree, method); if (contours.Size == 0) { return; } int sz = contours.Size * 4; int[] hierachyArray = new int[sz]; Marshal.Copy(hierachy.DataPointer, hierachyArray, 0, sz); for (int i = 0; i < contours.Size; i++) { if (contours[i].Size > 2) { int parentID = hierachyArray[i * 4 + 3]; CvContourInfo info = new CvContourInfo(i, parentID, contours[i]); // пока не понял логику m_contours.Add(info); } } } }
public CvContourInfo Clone() { CvContourInfo info = new CvContourInfo(); info.m_points = new Point[this.m_points.Length]; for (int i = 0; i < this.m_points.Length; i++) { info.m_points[i] = new Point(this.m_points[i].X, this.m_points[i].Y); } info.Id = this.Id; info.ParentId = this.ParentId; info.MainColor = new MCvScalar(this.MainColor.V0, this.MainColor.V1, this.MainColor.V2); info.PerimeterColor = new MCvScalar(this.PerimeterColor.V0, this.PerimeterColor.V1, this.PerimeterColor.V2); info.Area = this.Area; info.Perimeter = this.Perimeter; info.BoundingRect = new Rectangle(this.BoundingRect.X, this.BoundingRect.Y, this.BoundingRect.Width, this.BoundingRect.Height); info.BoundingCenter = new Point(this.BoundingCenter.X, this.BoundingCenter.Y); info.WeightCenter = new Point(this.WeightCenter.X, this.WeightCenter.Y); info.HistogramCenter = new Point(this.HistogramCenter.X, this.HistogramCenter.Y); return(info); }
// По идее ещё нужен алгоритм кластеризации //public CvContours[] GetClasters() /// <summary> /// Сливает все конутра коллекции во внешний контур с единым центром /// </summary> /// <param name="centerMode"></param> /// <param name="histogramScale"></param> /// <param name="radiusScale"></param> /// <returns></returns> public CvContours GetConcatenateAroundContour(CenterDrawMode centerMode = CenterDrawMode.BoundingRectCenter, int histogramScale = 1, double radiusScale = 1) { CvContours resultContour = new CvContours(); if (m_contours.Count == 0) { return(resultContour); } int totalPoints = 0; foreach (var contour in m_contours) { totalPoints += contour.PointsCnt; } if (totalPoints == 0) { return(resultContour); } double xx = 0; double yy = 0; int shift = 0; Point[] points = new Point[totalPoints]; foreach (var contour in m_contours) { contour.CopyPointsTo(points, shift); shift += contour.PointsCnt; switch (centerMode) { case CenterDrawMode.BoundingRectCenter: xx += contour.BoundingCenter.X; yy += contour.BoundingCenter.Y; break; case CenterDrawMode.PixelWeightCenter: xx += contour.WeightCenter.X; yy += contour.WeightCenter.Y; break; case CenterDrawMode.HistogramCenter: contour.UpdateXYHistogram(); xx += contour.HistogramCenter.X; yy += contour.HistogramCenter.Y; break; } } Point commonCenterPoint = new Point((int)(xx / m_contours.Count), (int)(yy / m_contours.Count)); var aroundPoints = CvContourInfo.AraundPoints(commonCenterPoint, points, histogramScale, radiusScale); CvContourInfo contourInfo = new CvContourInfo(0, -1, aroundPoints); resultContour.m_contours.Add(contourInfo); return(resultContour); }