public void RotateAboutImage(double angle, Image <Bgr, byte> input) { for (int i = 0; i < _points.Count; i++) { ColorfulPoint p = _points[i]; p.X -= input.Width / 2; p.Y -= input.Height / 2; int _px, _py; _px = (int)(p.X * Math.Cos(angle / (180 / Math.PI)) - p.Y * Math.Sin(angle / (180 / Math.PI)));//rotate by theta _py = (int)(p.X * Math.Sin(angle / (180 / Math.PI)) + p.Y * Math.Cos(angle / (180 / Math.PI))); p.X = _px + input.Width / 2; p.Y = _py + input.Height / 2; _points[i] = p; } for (int i = 0; i < _polyPoints.Count; i++) { ColorfulPoint p = _polyPoints[i]; p.X -= input.Width / 2; p.Y -= input.Height / 2; int _px, _py; _px = (int)(p.X * Math.Cos(angle / (180 / Math.PI)) - p.Y * Math.Sin(angle / (180 / Math.PI)));//rotate by theta _py = (int)(p.X * Math.Sin(angle / (180 / Math.PI)) + p.Y * Math.Cos(angle / (180 / Math.PI))); p.X = _px + input.Width / 2; p.Y = _py + input.Height / 2; _polyPoints[i] = p; } }
// rotate, angle is in degree public void Rotate(double angle) { for (int i = 0; i < _points.Count; i++) { ColorfulPoint p = _points[i]; p.X -= Center.X; p.Y -= Center.Y; int _px, _py; _px = (int)(p.X * Math.Cos(angle / (180 / Math.PI)) - p.Y * Math.Sin(angle / (180 / Math.PI)));//rotate by theta _py = (int)(p.X * Math.Sin(angle / (180 / Math.PI)) + p.Y * Math.Cos(angle / (180 / Math.PI))); p.X = _px + Center.X; p.Y = _py + Center.Y; _points[i] = p; } for (int i = 0; i < _polyPoints.Count; i++) { ColorfulPoint p = _polyPoints[i]; p.X -= Center.X; p.Y -= Center.Y; int _px, _py; _px = (int)(p.X * Math.Cos(angle / (180 / Math.PI)) - p.Y * Math.Sin(angle / (180 / Math.PI)));//rotate by theta _py = (int)(p.X * Math.Sin(angle / (180 / Math.PI)) + p.Y * Math.Cos(angle / (180 / Math.PI))); p.X = _px + Center.X; p.Y = _py + Center.Y; _polyPoints[i] = p; } }
private int IndexOfPolyPoint(ColorfulPoint p) { for (int i = 0; i < _points.Count; i++) { if (p.X == _points[i].X && p.Y == _points[i].Y) { return(i); } } return(-1); }
// translate public void Translate(int x, int y) { for (int i = 0; i < _points.Count; i++) { ColorfulPoint p = _points[i]; p.X += x; p.Y += y; _points[i] = p; } for (int i = 0; i < _polyPoints.Count; i++) { ColorfulPoint p = _polyPoints[i]; p.X += x; p.Y += y; _polyPoints[i] = p; } }
// scale, although this will compromise the accuracy of the contour map public void Scale(double x, double y = -1) { if (y < 0) { y = x; } for (int i = 0; i < _points.Count; i++) { ColorfulPoint p = _points[i]; p.X = (int)(p.X * x); p.Y = (int)(p.Y * y); _points[i] = p; } for (int i = 0; i < _polyPoints.Count; i++) { ColorfulPoint p = _polyPoints[i]; p.X = (int)(p.X * x); p.Y = (int)(p.Y * y); _polyPoints[i] = p; } }
private int IndexOfPolyPoint(ColorfulPoint p) { for (int i = 0; i < _points.Count; i++) { if (p.X == _points[i].X && p.Y == _points[i].Y) { return i; } } return -1; }
// get all of the valid contour maps, valid means circumfence > 200 px // this was not in their code, I added this feature, but I used their logic public static List<ColorfulContourMap> getAllContourMap(Mat input, int index, int mode = 0) { // use for all members List<ColorfulContourMap> result = new List<ColorfulContourMap>(); MatImage m1 = new MatImage(input); m1.Convert(); Mat gray = m1.Out(); // use for black background if (mode == 0) { MatImage m2 = new MatImage(gray); m2.SmoothGaussian(3); m2.ThresholdBinaryInv(245, 255); gray = m2.Out(); } // use for white background else { MatImage m2 = new MatImage(gray); m2.SmoothGaussian(3); m2.ThresholdBinaryInv(100, 255); gray = m2.Out(); } // one time use List<Point> pointList = new List<Point>(); List<Point> polyPointList = new List<Point>(); List<ColorfulPoint> cps = new List<ColorfulPoint>(); List<ColorfulPoint> pcps = new List<ColorfulPoint>(); // fetch all the contours using Emgu CV // fetch all the polys using Emgu CV // extract the points and colors Mat temp = gray.Clone(); VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); CvInvoke.FindContours(gray, contours, new Mat(), RetrType.List, ChainApproxMethod.ChainApproxNone); double area = Math.Abs(CvInvoke.ContourArea(contours[0])); VectorOfPoint maxArea = contours[0]; // maxArea is used as the current contour //contour = contour.HNext; // use this to loop for (int i = 0; i < contours.Size; i++) { double nextArea = Math.Abs(CvInvoke.ContourArea(contours[i], false)); // Find the area of contour area = nextArea; if (area >= Constants.MIN_AREA) { maxArea = contours[i]; VectorOfPoint poly = new VectorOfPoint(); CvInvoke.ApproxPolyDP(maxArea, poly, 1.0, true); pointList = maxArea.ToArray().ToList(); polyPointList = poly.ToArray().ToList(); foreach (Point p in pointList) { ColorfulPoint cp = new ColorfulPoint { X = p.X, Y = p.Y, color = extractPointColor(p, input) }; cps.Add(cp); } foreach (Point p in polyPointList) { ColorfulPoint cp = new ColorfulPoint { X = p.X, Y = p.Y, color = extractPointColor(p, input) }; pcps.Add(cp); } result.Add(new ColorfulContourMap(cps, pcps, index)); // clear temporal lists pointList = new List<Point>(); polyPointList = new List<Point>(); cps = new List<ColorfulPoint>(); pcps = new List<ColorfulPoint>(); } } return result; }
// get all of the valid contour maps, valid means circumfence > 200 px // this was not in their code, I added this feature, but I used their logic public static List <ColorfulContourMap> getAllContourMap(Mat input, int index, int mode = 0) { // use for all members List <ColorfulContourMap> result = new List <ColorfulContourMap>(); MatImage m1 = new MatImage(input); m1.Convert(); Mat gray = m1.Out(); // use for black background if (mode == 0) { MatImage m2 = new MatImage(gray); m2.SmoothGaussian(3); m2.ThresholdBinaryInv(245, 255); gray = m2.Out(); } // use for white background else { MatImage m2 = new MatImage(gray); m2.SmoothGaussian(3); m2.ThresholdBinaryInv(100, 255); gray = m2.Out(); } // one time use List <Point> pointList = new List <Point>(); List <Point> polyPointList = new List <Point>(); List <ColorfulPoint> cps = new List <ColorfulPoint>(); List <ColorfulPoint> pcps = new List <ColorfulPoint>(); // fetch all the contours using Emgu CV // fetch all the polys using Emgu CV // extract the points and colors Mat temp = gray.Clone(); VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); CvInvoke.FindContours(gray, contours, new Mat(), RetrType.List, ChainApproxMethod.ChainApproxNone); double area = Math.Abs(CvInvoke.ContourArea(contours[0])); VectorOfPoint maxArea = contours[0]; // maxArea is used as the current contour //contour = contour.HNext; // use this to loop for (int i = 0; i < contours.Size; i++) { double nextArea = Math.Abs(CvInvoke.ContourArea(contours[i], false)); // Find the area of contour area = nextArea; if (area >= Constants.MIN_AREA) { maxArea = contours[i]; VectorOfPoint poly = new VectorOfPoint(); CvInvoke.ApproxPolyDP(maxArea, poly, 1.0, true); pointList = maxArea.ToArray().ToList(); polyPointList = poly.ToArray().ToList(); foreach (Point p in pointList) { ColorfulPoint cp = new ColorfulPoint { X = p.X, Y = p.Y, color = extractPointColor(p, input) }; cps.Add(cp); } foreach (Point p in polyPointList) { ColorfulPoint cp = new ColorfulPoint { X = p.X, Y = p.Y, color = extractPointColor(p, input) }; pcps.Add(cp); } result.Add(new ColorfulContourMap(cps, pcps, index)); // clear temporal lists pointList = new List <Point>(); polyPointList = new List <Point>(); cps = new List <ColorfulPoint>(); pcps = new List <ColorfulPoint>(); } } return(result); }