public void ProcessImage(Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> image) { Emgu.CV.Image<Gray, byte> gray = image.Convert<Gray, byte>(); Emgu.CV.Image<Gray, byte> binary = new Image<Gray,byte>(image.Size); CvInvoke.cvThreshold(gray, binary, 40, 255, THRESH.CV_THRESH_BINARY | THRESH.CV_THRESH_OTSU); binary._Not(); Emgu.CV.Contour<System.Drawing.Point> contour_points = binary.FindContours(); MemStorage storage = new MemStorage(); Matrix<double> warp = new Matrix<double>(3, 3); while (contour_points != null) { Contour<Point> c = contour_points.ApproxPoly(contour_points.Perimeter * 0.05, storage); double p = c.Perimeter; if (c.Total == 4 && p > 300) { PointF[] src = new PointF[] { new PointF(c[0].X, c[0].Y), new PointF(c[1].X, c[1].Y), new PointF(c[2].X, c[2].Y), new PointF(c[3].X, c[3].Y)}; CvInvoke.cvGetPerspectiveTransform(src, _dest, warp); int flags = (int)INTER.CV_INTER_LINEAR + (int)WARP.CV_WARP_FILL_OUTLIERS; CvInvoke.cvWarpPerspective(gray, _roi, warp, flags, new MCvScalar(0)); double min_error; Orientation orient; FindBestOrientation(out min_error, out orient); if (min_error < 0.4) { image.DrawPolyline(c.ToArray(), true, new Bgr(Color.Green), 2); System.Console.WriteLine(min_error + " " + orient); switch (orient) { case Orientation.Degrees0: image.Draw(new LineSegment2D(c[0], c[3]), new Bgr(System.Drawing.Color.Red), 2); break; case Orientation.Degrees90: image.Draw(new LineSegment2D(c[1], c[0]), new Bgr(System.Drawing.Color.Red), 2); break; case Orientation.Degrees180: image.Draw(new LineSegment2D(c[2], c[1]), new Bgr(System.Drawing.Color.Red), 2); break; case Orientation.Degrees270: image.Draw(new LineSegment2D(c[3], c[2]), new Bgr(System.Drawing.Color.Red), 2); break; } } // 0 degrees } contour_points = contour_points.HNext; } }