public void Run() { try { // Set running to true so main GUI knows that plugin has not finished this.Running = true; this.testThread = Thread.CurrentThread; // Repeatedly move and snap image for (int i = 0; i < this.repetitions; i++) { this.camera.Snap(this.path + "\\repeatability-" + i + ".bmp"); // Move actuator out and back this.motor.MoveRel(this.distance); this.motor.WaitForEndOfMove(); Thread.Sleep(200); this.motor.MoveRel(-this.distance); this.motor.WaitForEndOfMove(); Thread.Sleep(200); } this.camera.Snap(this.path + "\\repeatability-" + this.repetitions + ".bmp"); var imgProccessing = new MatlabDFTRegistration.DFTRegistration(); MWArray[] argsOut = imgProccessing.get_offsets(2, this.path); double[,] dx = (double[, ])argsOut[0].ToArray(); double[,] dy = (double[, ])argsOut[1].ToArray(); double stdX = this.CalculateStdev(dx); double stdY = this.CalculateStdev(dy); MessageBox.Show(string.Format("Standard deviation x: {0:0.00}, y: {1:0.00}", stdX, stdY)); using (StreamWriter file = new StreamWriter(this.path + "\\results.csv")) { for (int r = 0; r < dx.GetLength(0); r++) { double dxi = this.camera.Scale * dx[r, 0]; double dyi = this.camera.Scale * dy[r, 0]; file.WriteLine(dxi.ToString() + "," + dyi.ToString()); } } } catch (ThreadInterruptedException e) { return; } }
/// <summary> /// Moves actuators and captures images for calibration /// </summary> public void Run() { try { // Create image processing Matlab object var imgProccessing = new MatlabDFTRegistration.DFTRegistration(); // Set running to true so main GUI knows that plugin has not finished this.Running = true; this.testThread = Thread.CurrentThread; int moves = 10; double moveDist = (this.camera.Width / 2) / moves; double[] Positions = new double[moves + 1]; // Snap reference image (stage centered) this.camera.Snap(this.path + "\\scaling-0.bmp"); // Move stage to left end of motion this.xMotor.MoveRel(-moves / 2 * moveDist); this.xMotor.WaitForEndOfMove(); // Repeatedly move right and snap image for (int i = 0; i < moves; i++) { this.camera.Snap(path + "\\scaling-x-" + i + ".bmp"); Positions[i] = moveDist * (-moves / 2 + i); // Move actuator out and back this.xMotor.MoveRel(moveDist); this.xMotor.WaitForEndOfMove(); Thread.Sleep(200); } Positions[moves] = moveDist * moves / 2; this.camera.Snap(path + "\\scaling-x-" + moves + ".bmp"); // Move stage to top end of motion this.xMotor.MoveRel(-moves / 2 * moveDist); this.xMotor.WaitForEndOfMove(); this.yMotor.MoveRel(-moves / 2 * moveDist); this.yMotor.WaitForEndOfMove(); // Repeatedly move down and snap image for (int i = 0; i < moves; i++) { this.camera.Snap(path + "\\scaling-y-" + i + ".bmp"); // Move actuator out and back this.yMotor.MoveRel(moveDist); this.yMotor.WaitForEndOfMove(); Thread.Sleep(200); } this.camera.Snap(path + "\\scaling-y-" + moves + ".bmp"); // Call image processing routine to get pixel offsets of each image MWArray[] argsOut = imgProccessing.get_offsets(2, this.path); double[,] dx = (double[, ])argsOut[0].ToArray(); double[,] dy = (double[, ])argsOut[1].ToArray(); double[,] PixelXX = new double[moves + 1, 1]; double[,] PixelXY = new double[moves + 1, 1]; double[,] PixelYY = new double[moves + 1, 1]; double[,] PixelYX = new double[moves + 1, 1]; Array.Copy(dx, 1, PixelXX, 0, moves + 1); Array.Copy(dy, 1, PixelXX, 0, moves + 1); Array.Copy(dy, 2 + moves, PixelXX, 0, moves + 1); Array.Copy(dx, 2 + moves, PixelXX, 0, moves + 1); double scaleXX, scaleXY, scaleYY, scaleYX; double offsetXX, offsetXY, offsetYY, offsetYX; double rsqXX = CameraCalibration.FindLinearLeastSquaresFit(Positions, PixelXX, out scaleXX, out offsetXX); double rsqXY = CameraCalibration.FindLinearLeastSquaresFit(Positions, PixelXY, out scaleXY, out offsetXY); double rsqYY = CameraCalibration.FindLinearLeastSquaresFit(Positions, PixelYY, out scaleYY, out offsetYY); double rsqYX = CameraCalibration.FindLinearLeastSquaresFit(Positions, PixelYX, out scaleYX, out offsetYX); // Write results to file using (StreamWriter file = new StreamWriter(this.path + "\\results.csv")) { file.WriteLine("\"X Position\",\"Y Position\",\"Pixel X\",\"Pixel Y\""); for (int r = 0; r < moves + 1; r++) { double dxi = dx[r + 1, 0]; double dyi = dy[r + 1, 0]; file.WriteLine(Positions[r] + ",0," + dxi.ToString() + "," + dyi.ToString()); } for (int r = 0; r < moves + 1; r++) { double dxi = dx[r + moves + 2, 0]; double dyi = dy[r + moves + 2, 0]; file.WriteLine("0," + Positions[r] + "," + dxi.ToString() + "," + dyi.ToString()); } } // Display results and ask user to accept calibration double scale = (scaleXX + scaleYY) / 2; string resultMsg = string.Format("Scale X:{0:0.00}\tCrosstalk X:{1:0.00}\n" + "X Scale R^2:{2:0.0000}\tCrosstalk R^2:{3:0.0000}\n" + "Scale Y:{4:0.00}, Crosstalk Y:{5:0.00}\n" + "Y Scale R^2:{6:0.0000}\tCrosstalk R^2:{7:0.0000}", scaleXX, scaleXY, rsqXX, rsqXY, scaleYY, scaleYX, rsqYY, rsqYX); DialogResult result = MessageBox.Show(resultMsg, "Results", MessageBoxButtons.YesNo); if (result == DialogResult.OK) { this.camera.SetScale(this.rccm, scale); } } catch (ThreadInterruptedException e) { return; } }