public static void RunOld(string[] args) { var intrinsicfile = args.FirstOrDefault() ?? Calibration.KinectDefaultFileName; var camIntrinsic = Utils.DeSerializeObject<CalibrationResult>(intrinsicfile); var projFile = args.Skip(1).FirstOrDefault() ?? Calibration.ProjectorDefaultFileName; var projIntrinsic = Utils.DeSerializeObject<CalibrationResult>(projFile); KinectSensor sensor = KinectSensor.KinectSensors.First(); Camera cam = new Camera(sensor, ColorImageFormat.RgbResolution1280x960Fps12); Projector proj = new Projector(); var keyl = new KeyboardListener(proj.window.Keyboard); double offsetx = 0, offsety = 0, scale = 0.5; bool proceed = false, quit = false; keyl.AddBinaryAction(0.02, -0.02, OpenTK.Input.Key.Up, OpenTK.Input.Key.Down, new OpenTK.Input.Key[0], (f) => offsety += f); keyl.AddBinaryAction(0.02, -0.02, OpenTK.Input.Key.Left, OpenTK.Input.Key.Right, new OpenTK.Input.Key[0], (f) => offsetx -= f); keyl.AddBinaryAction(0.02, -0.02, OpenTK.Input.Key.Up, OpenTK.Input.Key.Down, new OpenTK.Input.Key[] { Key.ShiftLeft }, (f) => scale += f); keyl.AddAction(() => proceed = true, Key.Space); keyl.AddAction(() => quit = proceed = true, Key.Q); PointF[] corners; proj.DrawBackground(Color.Black); while (true) { Console.WriteLine("Make sure the kinect can see the board"); Console.ReadLine(); corners = StereoCalibration.GetCameraCorners(cam.TakePicture(3), new Size(7, 4), false); if (corners.All(c => c != null)) { break; } else Console.WriteLine("Could not find corners"); } PointF[] projCorners; var projectedCorners = proj.DrawCheckerboard(new Size(8, 5), 0, 0, 0, scale, offsetx, offsety); while (true) { Console.WriteLine("Make sure the kinect can see the projection"); while (!proceed) { projectedCorners = proj.DrawCheckerboard(new Size(8, 5), 0, 0, 0, scale, offsetx, offsety); proj.window.ProcessEvents(); } projCorners = StereoCalibration.GetCameraCorners(cam.TakePicture(3), new Size(7, 4), false); if (corners.All(c => c != null)) { break; } else Console.WriteLine("Could not find any corners, make sure the checkerboard is visible to all Kinects."); } var camResult = StereoCalibration.CalibrateCamera(corners, new Size(7, 4), 0.05f, camIntrinsic); var transform = StereoCalibration.FindHomography(projCorners, projectedCorners); var projResult = StereoCalibration.CalibrateCamera(transform(corners), new Size(7, 4), 0.05f, projIntrinsic); Utils.SerializeObject(camResult, intrinsicfile); Utils.SerializeObject(projResult, projFile); proj.Close(); }
static CalibrationResult CalibrateProjector(KinectSensor sensor, Camera camera, Projector projector, CalibrationResult cameraCalib, PointF[][] cacalibdata, bool reload = false, bool save = true) { CalibrationResult result; string datafile = "projectorcalibration.xml"; if (!reload && File.Exists(datafile)) result = Utils.DeSerializeObject<CalibrationResult>(datafile); else { VoiceCommander commander = new VoiceCommander(sensor); commander.LoadChoices("Shoot", "Ready", "Next", "Continue", "Carry on", "Smaller", "Bigger", "Go", "Stop"); List<PointF[]> cam = new List<PointF[]>(), proj = new List<PointF[]>(); Size pattern = new Size(8, 7); PointF[] cc; PointF[] pc; double size = 0.5; pc = projector.DrawCheckerboard(pattern, 0, 0, 0, size); while (true) { var word = commander.Recognize("Ready?"); if (word == "Bigger") { size += 0.1; pc = projector.DrawCheckerboard(pattern, 0, 0, 0, size); continue; } else if (word == "Smaller") { size -= 0.1; pc = projector.DrawCheckerboard(pattern, 0, 0, 0, size); continue; } if (word == "Stop") break; cc = StereoCalibration.FindDualPlaneCorners(camera, pattern); if (cc != null && pc != null) { cam.Add(cc); proj.Add(pc); } } projector.DrawBackground(Color.Black); result = StereoCalibration.CalibrateProjector(projector, cacalibdata, cam.ToArray(), proj.ToArray(), new Size(7, 4), 0.05f); //result = StereoCalibration.CalibrateProjector(projector, camera, new Size(8, 7), cameraCalib, cacalibdata, new Size(7, 4), 0.05f); if (save) Utils.SerializeObject(result, datafile); } return result; }
public static CalibrationResult CalibrateProjector(Projector projector, Camera camera, Size pattern, CalibrationResult cameraCalib, PointF[][] cacalibdata, Size cameraPattern, float checkerboardSize) { List<PointF[]> cameraCorners = new List<PointF[]>(); List<PointF[]> projectorCorners = new List<PointF[]>(); var cpattern = new Size(pattern.Width - 1, pattern.Height - 1); int steps = 15; double rotx = 0, roty = 0, rotz = 0; for (int i = 0; i < steps; i++) { var di = (double)i / (double)steps; rotx = 0; roty = Math.Sin(di * Math.PI / 2) * 0.8; rotz = Math.Sin(di * Math.PI / 2) * 0.6; var pcs = projector.DrawCheckerboard(pattern, rotx, roty, rotz, 0.5); var img = camera.TakePicture(3); var ccs = GetCameraCorners(img, cpattern, false); if (ccs != null) { projectorCorners.Add(pcs); cameraCorners.Add(ccs); var withCorners = camera.TakePicture(0); if (DebugWindow != null) { QuickDraw.Start(withCorners) .Color(Color.White) .DrawPoint(ccs, 5) .Finish(); DebugWindow.DrawBitmap(withCorners); } } } //for (int i = 0; i < steps; i++) //{ // var di = (double)i / (double)steps; // rotx += 0.04; // roty *= 0.90; // var pcs = projector.DrawCheckerboard(pattern, // rotx, // roty, // rotz, 0.7); // var ccs = GetCameraCorners(camera, cpattern, false); // if (ccs != null) // { // projectorCorners.Add(pcs); // cameraCorners.Add(ccs); // var withCorners = camera.TakePicture(0); // if (DebugWindow != null) // { // QuickDraw.Start(withCorners) // .Color(Color.White) // .DrawPoint(ccs, 5) // .Finish(); // DebugWindow.DrawBitmap(withCorners); // } // } //} var hm = CreateHomography(cameraCorners.ToArray(), projectorCorners.ToArray()); var globals = GenerateCheckerBoard(cameraPattern, checkerboardSize, 0); var globalCorners = cacalibdata.Select(row => globals).ToArray(); var proj = cacalibdata.Select(cs => cs.Select(c => new PointF(c.X, c.Y)).ToArray()).ToArray(); foreach (var p in proj) hm.ProjectPoints(p); IntrinsicCameraParameters projIntrin = new IntrinsicCameraParameters(); ExtrinsicCameraParameters[] projExtrins; Emgu.CV.CameraCalibration.CalibrateCamera(globalCorners, proj, projector.Size, projIntrin, Emgu.CV.CvEnum.CALIB_TYPE.CV_CALIB_RATIONAL_MODEL, out projExtrins); return new CalibrationResult() { Intrinsic = projIntrin, Extrinsic = projExtrins.First() }; }