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); }
// static factory methods // getting the contour with the max area in a picture // the extraction algorithm is from the C++ code Line 440-534 public static ColorfulContourMap getMaxContourMap(Image <Bgr, byte> input, int index) { ColorfulContourMap result = new ColorfulContourMap(); Image <Gray, byte> gray = input.Convert <Gray, byte>(); gray = gray.SmoothGaussian(3).ThresholdBinaryInv(new Gray(245), new Gray(255)).MorphologyEx(null, CV_MORPH_OP.CV_MOP_CLOSE, 2); List <Point> pointList = new List <Point>(); List <Point> polyPointList = new List <Point>(); List <ColorfulPoint> cps = new List <ColorfulPoint>(); List <ColorfulPoint> pcps = new List <ColorfulPoint>(); using (MemStorage storage1 = new MemStorage()) { Image <Gray, Byte> temp = gray.Clone(); Contour <Point> contour = temp.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, RETR_TYPE.CV_RETR_EXTERNAL); double area = Math.Abs(contour.Area); Contour <Point> maxArea = contour; contour = contour.HNext; for (; contour != null; contour = contour.HNext) { double nextArea = Math.Abs(contour.Area); if (area < nextArea) { area = nextArea; maxArea = contour; } } Contour <Point> poly = maxArea.ApproxPoly(1.0, storage1); pointList = maxArea.ToList(); polyPointList = poly.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 = new ColorfulContourMap(cps, pcps, index); result.matched = false; } return(result); }
// 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; } }
// 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(Image <Bgr, byte> input, int index, int mode = 0) { // use for all members List <ColorfulContourMap> result = new List <ColorfulContourMap>(); Image <Gray, byte> gray = input.Convert <Gray, byte>(); // use for black background if (mode == 0) { gray = gray.SmoothGaussian(3).ThresholdBinaryInv(new Gray(245), new Gray(255)).MorphologyEx(null, CV_MORPH_OP.CV_MOP_CLOSE, 2); } // use for white background else { gray = gray.SmoothGaussian(3).ThresholdBinary(new Gray(100), new Gray(255)).MorphologyEx(null, CV_MORPH_OP.CV_MOP_CLOSE, 2); } // 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 using (MemStorage storage1 = new MemStorage()) { Image <Gray, Byte> temp = gray.Clone(); Contour <Point> contour = temp.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, RETR_TYPE.CV_RETR_EXTERNAL); double area = Math.Abs(contour.Area); Contour <Point> maxArea = contour; // maxArea is used as the current contour //contour = contour.HNext; // use this to loop for (; contour != null; contour = contour.HNext) { double nextArea = Math.Abs(contour.Area); area = nextArea; if (area >= Constants.MIN_AREA) { maxArea = contour; Contour <Point> poly = maxArea.ApproxPoly(1.0, storage1); pointList = maxArea.ToList(); polyPointList = poly.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); }