Ejemplo n.º 1
0
        private static void Run()
        {
            /*
            PointF[] imageCorners = new PointF[]
            {
                new PointF(10, 10),
                new PointF(20, 20),
                new PointF(30, 30),
                new PointF(40, 40),
                new PointF(10, 40),
                new PointF(40, 10),
            };

            MCvPoint3D32f[] worldCorners = new MCvPoint3D32f[]
            {
                new MCvPoint3D32f(10, 10, 0),
                new MCvPoint3D32f(20, 20, 0),
                new MCvPoint3D32f(30, 30, 0),
                new MCvPoint3D32f(40, 40, 0),
                new MCvPoint3D32f(10, 40, 0),
                new MCvPoint3D32f(40, 10, 0),
            };

            var kamera = new Kamera("Casio Ex S5", "0", 3648, 2736);
            kamera.CalibrateExtrinsics(imageCorners, worldCorners);
            */

            var sqw = 100;
            var m = 7;
            var n = 10;
            var checkers = new Checkers(m, n, new Point((800 - m * sqw) / 2 + 0, (1280 - n * sqw) / 2 - 0), new Size(sqw, sqw))
            {
                BlackColor = Color.Black,
                WhiteColor = Color.White,
                OtherColor = Color.White,
            };

            // ConsoleHelper.Create();

            if (Global.No)
                Offline.Run(checkers);
            else
            {
                var program = new OldProgram();
                if (Global.No)
                    program.CalibrateCamera();
                else
                    program.Run(checkers);
            }

            // ConsoleHelper.Destroy();
        }
Ejemplo n.º 2
0
        public static void Run(Checkers checkers)
        {
            Emgu.CV.Util.OptimizeCV(true);

            PointF[] imageCornersCamera = new PointF[]
            {
                new PointF(3141, 2144),
                new PointF(2035, 2599),
                new PointF(1594, 1503),
                new PointF(2683, 1019),
                new PointF(2363, 1824),
                new PointF(2137, 1258),
                new PointF(1783,  400),
                new PointF( 599, 1948),
            };

            MCvPoint3D32f[] worldCornersCamera = new MCvPoint3D32f[]
            {
                new MCvPoint3D32f(0, 0, 0),
                new MCvPoint3D32f(0, 0.5f, 0),
                new MCvPoint3D32f(0.5f, 0.5f, 0),
                new MCvPoint3D32f(0.5f, 0, 0),
                new MCvPoint3D32f(0.25f, 0.25f, 0),
                new MCvPoint3D32f(0.5f, 0.25f, 0),
                new MCvPoint3D32f(0.9f, 0.25f, 0),
                new MCvPoint3D32f(0.5f, 1.0f, 0),            
            };

            var dstDir = Path.Combine(Global.TmpDir);
            var srcDir = Path.Combine(Global.DatDir, @"Offline\Optoma EW1610\Raw");
            var proPath = Path.Combine(Global.DatDir, @"Offline\Optoma EW1610\intrinsics.txt");
            var camPath = Path.Combine(Global.DatDir, @"Offline\Casio Ex S5\intrinsics.txt");

            var camera = new Camera(camPath, 3648, 2736, imageCornersCamera, worldCornersCamera);

            var proSize = new Size(800, 1280);

            var zPlane = new Plane(Vector3.UnitZ, 0);

            var invertedBlackAndWhite = false;

            var srcFiles = Directory.EnumerateFiles(srcDir, "*.jpg").ToArray();
            PointF[][] imageCorners = new PointF[srcFiles.Length][];
            imageCorners = checkers.GetImagePointsCopy(srcFiles.Length);
            var worldCorners = Projector.GetObjectPointsCopy(srcFiles.Length, checkers.Saddles.Width, checkers.Saddles.Height, (float)checkers.Square.Width, (float)checkers.Square.Height);

            var sw = Stopwatch.StartNew();
            Console.WriteLine("Finding corners in {0} images.", srcFiles.Length);

            Parallel.ForEach(srcFiles, new ParallelOptions() { MaxDegreeOfParallelism = 1, }, (srcFile, loopState, lon) =>
            {
                Console.WriteLine("    Finding corners in image: {0}/{2}, {1}.", lon, srcFile, srcFiles.Length);
                var sw2 = Stopwatch.StartNew();

                using (var img = new Image<Bgr, byte>(srcFile))
                using (var gray = img.Convert<Gray, byte>())
                {
                    if (invertedBlackAndWhite)
                        gray._Not();

                    ImageViewer.Show(gray);

                    var und = camera.Intrinsics.Undistort(img);
                    und.Save(@"C:\Users\Jaap\Temp\und.png");

                    var patternSize = checkers.Saddles;
                    PointF[] corners;
                    var ccbt = CALIB_CB_TYPE.FILTER_QUADS | CALIB_CB_TYPE.ADAPTIVE_THRESH;
                    var found = CameraCalibration.FindChessboardCorners(gray, patternSize, ccbt, out corners);

                    CvInvoke.cvDrawChessboardCorners(img.Ptr, patternSize, corners, corners.Length, patternWasFound: found ? 1 : 0);

                    if (found)
                    {
                        var window = new Size(32, 32);
                        var zeroZone = new Size(-1, -1);
                        var criteria = new MCvTermCriteria(21, 0.0001);
                        Console.WriteLine("    Image {0}/{1} has corners, subpixing begins at {2}.", lon, srcFiles.Length, sw2.Elapsed);
                        gray.FindCornerSubPix(new PointF[][] { corners }, window, zeroZone, criteria);
                        
                        for (int i = 0; i < corners.Length; ++i)
                        {
                            img.Draw(new Cross2DF(corners[i], 20, 20), new Bgr(255, 0, 255), 1);

                            var ray = camera.BoundingFrustum.ThroughPixel(camera.World.Translation, corners[i].X, corners[i].Y, camera.Width, camera.Height);
                            var intersect = ray.Intersects(zPlane);
                            if (intersect.HasValue)
                            {
                                var rayCastWorldCorner = ray.Position + intersect.Value * ray.Direction;
                                worldCorners[lon][i] = new MCvPoint3D32f(rayCastWorldCorner.X, rayCastWorldCorner.Y, rayCastWorldCorner.Z);
                            }                            
                        }

                        corners = CameraCalibration.ProjectPoints(worldCorners[lon], camera.Extrinsics, camera.Intrinsics);
                        for (int i = 0; i < corners.Length; ++i)
                            img.Draw(new Cross2DF(corners[i], 10, 10), new Bgr(255, 255, 0), 1);                        
                    }
                    else
                    {
                        worldCorners[lon] = null;
                    }

                    img.Save(@"C:\Users\Jaap\Temp\img.png");
                    
                    imageCorners[lon] = found ? corners : null;
                    var prefix = found ? "ok." : "failed.";
                    var dstFile = Path.Combine(dstDir, prefix + Path.GetFileNameWithoutExtension(srcFile) + ".png");
                    if (File.Exists(dstFile))
                        File.Delete(dstFile);

                    img.Save(dstFile);

                    if (lon == 0)
                        ImageViewer.Show(img);

                    Console.WriteLine("    Image {0}/{1} is done {2}, found: {3}, time: {4}.", lon, srcFiles.Length, dstFile, found, sw2.Elapsed);
                }
            });

            if (Global.Yes)
                return;

            worldCorners = worldCorners.Where(c => c != null).Select(c => c).ToArray();
            imageCorners = checkers.GetImagePointsCopy(worldCorners.Length);

            var intrinsics = new IntrinsicCameraParameters();

            Console.WriteLine("Found corners in {0}/{1} images, time: {2}.", worldCorners.Length, srcFiles.Length, sw.Elapsed);
            Console.WriteLine("Now calibrating...");
            sw.Restart();

            ExtrinsicCameraParameters[] extrinsics;

            var ct = CALIB_TYPE.CV_CALIB_FIX_K3 | CALIB_TYPE.CV_CALIB_FIX_PRINCIPAL_POINT | CALIB_TYPE.CV_CALIB_ZERO_TANGENT_DIST;
                ct = CALIB_TYPE.CV_CALIB_FIX_K3 | CALIB_TYPE.CV_CALIB_ZERO_TANGENT_DIST;

            var reprojErr = CameraCalibration.CalibrateCamera(worldCorners,
            imageCorners, proSize, intrinsics, ct, out extrinsics);
            var reprojErrPerCornerSquared = reprojErr / (imageCorners.Length * checkers.Saddles.Area());
            var reprojErrPerCorner = Math.Sqrt(reprojErrPerCornerSquared);

            Console.WriteLine("Calibration done in: {0}, reprojection error = {1}, {2}, {3}", sw.Elapsed, reprojErr, reprojErrPerCornerSquared, reprojErrPerCorner);

            Markers.Chessboard.Save(proPath, intrinsics, proSize.Width, proSize.Height);

            Matrix<float> mdx, mdy;
            intrinsics.InitUndistortMap(proSize.Width, proSize.Height, out mdx, out mdy);

            Console.WriteLine("Now undistorting and saving...");
            sw.Restart();

            if (Global.No)
                Parallel.ForEach(srcFiles, new ParallelOptions() { MaxDegreeOfParallelism = 2, }, (srcFile, loopState, lon) =>
                {
                    var dstFile = Path.Combine(dstDir, Path.GetFileNameWithoutExtension(srcFile) + ".undistorted.png");
                    if (File.Exists(dstFile))
                        File.Delete(dstFile);

                    using (var img = new Image<Bgr, byte>(srcFile))
                    using (var jmg = img.Copy())
                    {
                        CvInvoke.cvRemap(jmg.Ptr, img.Ptr, mdx, mdy, (int)INTER.CV_INTER_LINEAR | (int)Emgu.CV.CvEnum.WARP.CV_WARP_FILL_OUTLIERS, new MCvScalar(255.0f, 0.0f, 255.0f, 255.0f));
                        img.Save(dstFile);
                    }

                    Console.WriteLine("    Undistorted {0}/{2}, {1}", lon, dstFile, srcFiles.Length);
                });

            Console.WriteLine("Undistortion done in {0}, press a key to continue.", sw.Elapsed);
            Console.ReadKey();
            Console.WriteLine("One more key please...");
        }
Ejemplo n.º 3
0
        private async void Run(Checkers checkers)
        {
            /*
            m.MouseEvents.Subscribe(mea => 
                {
                    Input.Global.Update(m.Hwnd);
                    r.Render<Circle2d>(new Circle2d.Context() { 
                        Position = new Vector2(mea.X, mea.Y),
                        InnerRadius = 16,
                        OuterRadius = 20,
                        Color = Color.HotPink
                    });

                    r.Render<Circle2d>(new Circle2d.Context() { 
                        Position = Input.Global.MousePosition,
                        InnerRadius = 8,
                        OuterRadius = 12,
                        Color = Color.Beige
                    });
                    
                    r.Render<Circle2d>(new Circle2d.Context()
                    {
                        Position = Input.Global.MousePosition,
                        InnerRadius = 0,
                        OuterRadius = 4,
                        Color = Color.Yellow
                    });                    
                    r.Present(m, m);
                });
            */
            var numPhotosNeeded = 1;
            for (int i = 0; i < numPhotosNeeded; ++i)
            {
                // r.Present(null, p);
                await KeyPress(p, m, "Photo {0}/{1}", i, numPhotosNeeded);
            }

            r.Render<Clear>(Color.Black);
            await KeyPress(p, m, "Black");

            r.Render<Clear>(Color.Gray);
            await KeyPress(p, m, "Gray");

            r.Render<Clear>(Color.White);
            await KeyPress(p, m, "White");

            var sgc = new SafeGrayCode(p.Size.Width);
            for (int i = 0; i < sgc.NumBits; ++i)
            {
                r.Render<GrayCodeSweep>(new GrayCodeSweep.Context()
                    {
                        Bit = i, Sgc = sgc,
                        Sweep = p.Size.Height,
                        Dir = GrayCodeSweep.Dir.Horizontal,
                    });
                await KeyPress(p, m, "Horizontal Gray Code {0}/{1}", i + 1, sgc.NumBits);
            }

            sgc = new SafeGrayCode((int)p.Size.Width);
            for (int i = 0; i < sgc.NumBits; ++i)
            {
                r.Render<GrayCodeSweep>(new GrayCodeSweep.Context()
                {
                    Bit = i,
                    Sgc = sgc,
                    Sweep = (int)p.Size.Height,
                    Dir = GrayCodeSweep.Dir.Vertical,
                });
                await KeyPress(p, m, "Horizontal Gray Code {0}/{1}", i + 1, sgc.NumBits);
            }

            r.Render<Clear>(Color.HotPink);
            await KeyPress(p, m, "Done");
        }
Ejemplo n.º 4
0
        private async void CalibrateCamera()
        {
            var sqw = 50;
            var M = 8;
            var N = 7;
            var W = m.Size.Width;
            var H = m.Size.Height;
            var checkers = new Checkers(M, N, new Point((W - M * sqw) / 2 + 0, (H - N * sqw) / 2 - 0), new Size(sqw, sqw));
            
            var cap = CLEyeCapture.AllDevices.FirstOrDefault();
            if (cap == null)
                return;

            var kam = new Kamera(cap.Name, cap.Uuid, cap.Width, cap.Height);
            if (kam.HasCalibratedIntrinsics)
            {
                Try(kam);
                return;
            }
            else
            {
                List<PointF[]> imageCorners = new List<PointF[]>();
                List<MCvPoint3D32f[]> worldCorners = new List<MCvPoint3D32f[]>();

                for (; ; )
                {
                    // r.Present(null, m);
                    r.Render<Chessboard2d>(checkers);

                    var key = await KeyPress(m, p, "{0} Photos", imageCorners.Count);
                    if (key == Keys.F1)
                        break;

                    using (var pic = cap.TryDequeue())
                        if (pic != null)
                            using (var gray = pic.Bgra.Convert<Gray, byte>())
                            using (var bgr = pic.Bgra.Convert<Bgr, byte>())
                            {
                                PointF[] foundCorners;
                                var calibChessboardType = CALIB_CB_TYPE.FILTER_QUADS | CALIB_CB_TYPE.ADAPTIVE_THRESH;
                                var found = CameraCalibration.FindChessboardCorners(gray, checkers.Saddles, calibChessboardType, out foundCorners);
                                if (found)
                                {
                                    var window = new Size(sqw * 100 / 10, sqw * 100 / 10);
                                    var zeroZone = new Size(-1, -1);
                                    var criteria = new MCvTermCriteria(21, 0.0001);
                                    gray.FindCornerSubPix(new PointF[][] { foundCorners }, window, zeroZone, criteria);
                                }

                                CvInvoke.cvDrawChessboardCorners(bgr.Ptr, checkers.Saddles, foundCorners, foundCorners.Length, patternWasFound: (found ? 1 : 0));
                                bgr.Save(Path.Combine(Global.TmpDir, cap.Name + imageCorners.Count.ToString() + ".png"));

                                if (found)
                                {
                                    imageCorners.Add(foundCorners);
                                    worldCorners.Add(checkers.GetWorldPointsCopy());
                                }
                            }
                }

                kam.CalibrateIntrinsics(imageCorners.ToArray(), worldCorners.ToArray());
            }
        }