예제 #1
0
        public ProgramTask()
        {
            Monitor.ClientSize = new Size(640, 480);
            ColoredChessboard = new ColoredChessboard(Chessboard, Color.CornflowerBlue.Alpha(0.9f), Color.Orange.Alpha(0.3f));

            var maybeSecondaryScreen = Screen.AllScreens.Where(s => s != Screen.PrimaryScreen).FirstOrDefault() ?? Screen.PrimaryScreen;

            // Projector = new RealProjector("Optoma EW1610", "1018", maybeSecondaryScreen.Bounds.Size, maybeSecondaryScreen);
            var virtualProjectorOrbit = new OrbitCamera("Virtual Projector Orbit", "N/A", new Size(1280, 800), new PointF(640, 850), 100, 2, 134);
            Projector = new VirtualProjector(Monitor, virtualProjectorOrbit);

            WorldCamera = new OrbitCamera("World Orbit", "1018", Monitor.Size, Monitor.Size.CenterF(), Monitor.Size.Width, 0.1f, 100)
            {
                Center = Chessboard.VertexCenter,
                Distance = 56,
                YawPitch = new Vector2(0.2f, -0.2f),
            };

            WorldScene = new Scene(WorldCamera)
            {
                // MakeColoredAxisOfLength(Vector3.UnitX, Color.Red, length: 20.0f),
                // MakeColoredAxisOfLength(Vector3.UnitY, Color.Green, length: 20.0f),
                // MakeColoredAxisOfLength(Vector3.UnitZ, Color.Blue, length: 20.0f),
                
                // ColoredChessboard,

                // new Grid(Matrix.CreateRotationX(MathHelper.PiOver2),  Color.Red.Lerp(Color.White, 0.9f).Alpha(0.3f), Color.Red.Alpha(0.5f)),
                // new Grid(Matrix.CreateRotationY(-MathHelper.PiOver2), Color.Green.Lerp(Color.White, 0.9f).Alpha(0.1f), Color.Green.Alpha(0.3f)),
                // new Grid(Matrix.Identity,                             Color.Blue.Lerp(Color.White, 0.9f).Alpha(0.1f), Color.Blue.Alpha(0.4f)),

                new MeshModel("ManStanding", Matrix.CreateScale(0.1f) * Matrix.CreateRotationY(-MathHelper.PiOver2) * Matrix.CreateTranslation(4, 0, 2)) { ProjectorViewProject = Projector },
                new MeshModel("MutantStanding", Matrix.CreateScale(0.4f) * Matrix.CreateRotationY(0) * Matrix.CreateTranslation(8, 0, 1)) { ProjectorViewProject = Projector },
                new MeshModel("HeadFemale", Matrix.CreateScale(0.2f) * Matrix.CreateRotationX(-MathHelper.PiOver2) * Matrix.CreateTranslation(-3, 6, 0)) { ProjectorViewProject = Projector },
            };

            CaptureCameras = CreateCaptureCameras().ToList();
            if (CaptureCameras.IsEmpty())
                AddVirtualCaptureCamera("VirCam 1", "1018", Color.Red);

            CaptureCameraSelectionPictureGray = new Picture2D(CaptureCameraSelected.Intrinsics.ImageSize.LimitProportional(290, 290).AnchorWithin(Monitor.ClientRectangle, AnchorPoints.BottomLeft), CaptureCameraSelected.Capture.GrayTexture2D);
            CaptureCameraSelectionPictureRgba = new Picture2D(CaptureCameraSelected.Intrinsics.ImageSize.LimitProportional(290, 290).ToRect(CaptureCameraSelectionPictureGray.Rectangle.Left, CaptureCameraSelectionPictureGray.Rectangle.Top, AnchorPoints.BottomLeft), CaptureCameraSelected.Capture.RgbaTexture2D);
            CaptureCameraSelected.Highlight = true;

            WorldScene.Add(CaptureCameras);
            WorldScene.Add(Projector);

            Monitor.Scene = new Scene(new ScreenCamera(Monitor))
            {
                new Clear(Color.LightGray),
                WorldScene,
                CaptureCameraSelectionPictureGray,
                CaptureCameraSelectionPictureRgba,
            };

            LocateTrigger = new Trigger(() => new LocateTask(Monitor, CaptureCameraSelected, Chessboard).Run(), Keys.L);
            CalibrateTrigger = new Trigger(() => new CalibrateTask(Monitor, CaptureCameraSelected, Chessboard).Run(CaptureCameraSelected), Keys.C);
            ChessboardShapeTrigger = new Trigger(() => new ChessboardShapeTask(Monitor, Projector, Chessboard).Run(), Keys.S);
            CalibrateIndirectlyTrigger = new Trigger(() => { WorldScene.Remove(ColoredChessboard); return new CalibrateIndirectlyTask(Monitor, CaptureCameras, Projector, Chessboard).Run(WorldScene); }, Keys.I);
            GrayScanTrigger = new Trigger(() => new GrayScanTask(Monitor, CaptureCameras.First(), Projector).Run(WorldScene), Keys.G);

            AttachInputToCamera(Program.WhenInput.Where(input => !input.KeyPressed(Keys.LeftAlt)), Monitor, WorldCamera);
            AttachInputToCamera(Program.WhenInput.Where(input => input.KeyPressed(Keys.LeftAlt)), Monitor, virtualProjectorOrbit);

            AttachPerformanceBar();

            Program.WhenInput.Where(input => input.KeyDown(Keys.Tab)).Subscribe(input =>
                {
                    CaptureCameraSelected.Highlight = false;
                    CaptureCameraSelectionIdx = (CaptureCameraSelectionIdx + 1) % CaptureCameras.Count;
                    CaptureCameraSelected.Highlight = true;
                    CaptureCameraSelectionPictureGray.Texture2D = CaptureCameraSelected.Capture.GrayTexture2D;
                    CaptureCameraSelectionPictureRgba.Texture2D = CaptureCameraSelected.Capture.RgbaTexture2D;

                });
        }
예제 #2
0
        public async Task<PinHole> Run(Services services, IEnumerable<Intrinsics> intrinsics)
        {
            var monitor = services.Monitor;
            var projector = services.Projectors.First();

            monitor.FullScreen = false;
            projector.FullScreen = true;

            monitor.Show();
            projector.Show();
            
            Vector3[] projectorCorners;
            var chessboard = SculptChessboardTask.Load(out projectorCorners, projector.ClientSize);                    

            var confirmTrigger = from key in projector.KeyDown
                                 where key.KeyCode == Keys.Space
                                 select default(Unit);

            var closeTrigger = from close in monitor.FormClosingObservable
                               select close;

            bool done = false;
            var doneTrigger = Observable.Amb(confirmTrigger, closeTrigger);

            var pinHoles = services.Captures.Select((capture, idx) => new PinHole(capture, intrinsics.ToArray()[idx], services.Renderer)).ToArray();

            var capture1 = services.Captures.First();
            var texture2D = services.Renderer.LeaseFor(capture1);
            
            PointF[] corners = new PointF[chessboard.SaddleCount.Area()];                
            
            using (doneTrigger.Subscribe(_ => done = true))
            using (capture1.Subscribe(picture => {
                using (picture)
                {
                    CvInvoke.cvDrawChessboardCorners(picture.Bgra.Ptr, chessboard.SaddleCount, corners, corners.Length, 1);
                    texture2D.SetData(picture.Bytes);
                }
            }))
            {
                var homography = chessboard.GetVertexHomographyTo(projectorCorners);
                var camera = new ScreenCamera2D(homography,
                        Matrix.CreateOrthographicOffCenter(0, projector.ClientSize.Width, projector.ClientSize.Height, 0, 0, 1));

                var orbitCamera = monitor.CreateOrbitCamera(50, monitor.Size.Ratio(), null);
                var picture2D = new Picture2D(services.Captures.First().Size.Scale(0.5f).AnchorWithin(monitor.ClientRectangle, AnchorPoints.BottomRight), texture2D) { Color = Color.White.Scale(0.9f), };
                
                foreach (var pinHole in pinHoles)
                    pinHole.LocateUsing(chessboard, corners);

                while (!done)
                {
                    var pf = projector.Begin(services.Renderer);
                    pf.Add(Color.White);
                    pf.Add(camera);
                    pf.Add(chessboard);
                    await pf.PresentAsync();

                    var mf = monitor.Begin(services.Renderer);
                    mf.Add(Color.DarkGray);
                    mf.Add(chessboard);
                    
                    foreach (var pinHole in pinHoles)
                    {
                        var crns = pinHole.BoundingFrustum.GetCorners().Skip(4).Take(4).ToArray();
                        mf.Add(new Quad(crns[2], crns[3], crns[1], crns[0], picture2D.Texture2D, Color.White.Scale(0.8f)));
                        mf.Add(pinHole.BoundingFrustum);

                        if (corners != null)
                        {
                            var position = pinHole.World.Translation;
                            mf.Add(new LineSegment(position, Vector3.Zero, 0.03f) { Color = Color.Fuchsia, });
                                
                            for (int i = 0; i < corners.Length; ++i)                                
                            {
                                var corner = corners[i];
                                var ray = pinHole.BoundingFrustum.ThroughPixel(position, corner.X, corner.Y, pinHole.ImageWidth, pinHole.ImageHeight);
                                var lineSegment = new LineSegment(ray.Position, ray.Position + 5.4f * ray.Direction, 0.005f) { Color = Palette.Get(i), };
                                mf.Add(lineSegment);
                            }
                        }
                    }

                    await mf.PresentAsync();
                }
            }

            return null;
        }