Voxel Calibration Wizard

Source code for wizard.CalibrationNonLinearityPage

import csv 
import os
from PySide import QtGui, QtCore
from PySide.QtGui import QComboBox
from calibration.NonLinearityCalibration import NonLinearityCalibration
from CalibrationPage import CalibrationPage
from wizard.Calibrations import CALIB_SHOW, CHIPSETS
[docs]class CalibrationNonLinearityTableDelegate(QtGui.QItemDelegate): def __init__(self, parent = None): super(CalibrationNonLinearityTableDelegate, self).__init__(parent)
[docs]class CalibrationNonLinearityPage (CalibrationPage): """Wizard page for non linearity calibration Takes CSV file as input and gives non linearity coefficients as output """ CSV_FILE_NAME = 'non-linearity.csv' def __init__(self, calibrationWizard): super (CalibrationNonLinearityPage, self).__init__() self.calibrationWizard = calibrationWizard self.setTitle('Non-linearity Calibration') self.setSubTitle('Computation of non-linearity of phase vs distance. Please measure the phase value at cx, cy') self.mainLayout = QtGui.QVBoxLayout(self)
[docs] def initializePage(self): self.layout = QtGui.QVBoxLayout() hlayout = QtGui.QHBoxLayout() self.phasePeriod = QtGui.QComboBox() hlayout.addWidget(self.phasePeriod) hlayout.addStretch() if self.calibrationWizard.depthCamera: self.chipset = CHIPSETS[self.calibrationWizard.depthCamera.chipset()] else: self.chipset = self.calibrationWizard.camera self.setChipsetParams() self.calibrateButton = QtGui.QPushButton('&Calibrate') self.calibrateButton.pressed.connect(self.calibrate) self.calibrateButton.setShortcut('Alt+C') hlayout.addWidget(self.calibrateButton) self.layout.addLayout(hlayout) self.calibrateButton.setDisabled(True) hlayout = QtGui.QHBoxLayout() modFreqLabel = QtGui.QLabel("Mod Frequency 1") self.modFreq = QtGui.QDoubleSpinBox() self.modFreq.setRange(0, 75) self.modFrequency = 48 self.modFreq.setValue(48) self.modFreq.setSingleStep(0.05) hlayout.addWidget(modFreqLabel) hlayout.addWidget(self.modFreq) hlayout.addStretch() self.modFreq.valueChanged.connect(self.setModFrequency) modFreq2Label = QtGui.QLabel("Mod Frequency 2") self.modFreq2 = QtGui.QDoubleSpinBox() self.modFrequency2 = 60 self.modFreq2.setSingleStep(0.05) self.modFreq2.setRange(0, 75) self.modFreq2.setValue(60) hlayout.addWidget(modFreq2Label) hlayout.addWidget(self.modFreq2) self.modFreq2.valueChanged.connect(self.setModFrequency2) self.layout.addLayout(hlayout) groupbox = QtGui.QGroupBox() groupbox.setTitle('Phase vs Distance Measurements') self.layout.addWidget(groupbox) vglayout = QtGui.QVBoxLayout() groupbox.setLayout(vglayout) self.phaseDistanceMeasurements = QtGui.QTableWidget() self.rowLength = 2 self.phaseDistanceMeasurements.setColumnCount(self.rowLength) self.phaseDistanceMeasurements.setHorizontalHeaderLabels(['Actual Distance', 'Phase 1']) self.phaseDistanceMeasurements.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.phaseDistanceMeasurements.setToolTip('Please ensure that entries are in increasing order of distance') self.phaseDistanceMeasurements.setItemDelegate(CalibrationNonLinearityTableDelegate()) vglayout.addWidget(self.phaseDistanceMeasurements) insertRowAction = QtGui.QAction('Insert Row', self.phaseDistanceMeasurements) insertRowAction.setShortcut('Insert') insertRowAction.triggered.connect(self.insertRow) self.phaseDistanceMeasurements.addAction(insertRowAction) removeRowAction = QtGui.QAction('Remove Row', self.phaseDistanceMeasurements) removeRowAction.setShortcut('Del') removeRowAction.triggered.connect(self.removeRow) self.phaseDistanceMeasurements.addAction(removeRowAction) removeAllRowsAction = QtGui.QAction('Remove All Rows', self.phaseDistanceMeasurements) removeAllRowsAction.setShortcut('Shift+Del') removeAllRowsAction.triggered.connect(self.removeAllRows) self.phaseDistanceMeasurements.addAction(removeAllRowsAction) self.importCSVButton = QtGui.QPushButton('&Import From CSV') self.importCSVButton.setShortcut('Alt+I') self.importCSVButton.pressed.connect(self.importCSV) vglayout.addWidget(self.importCSVButton) self.paramsGroupbox = QtGui.QGroupBox() self.paramsGroupbox.setTitle('Non-linearity Parameters') self.layout.addWidget(self.paramsGroupbox) self.paramsText = QtGui.QTextEdit() self.paramsText.setReadOnly(True) self.paramsText.setMinimumHeight(100) vglayout = QtGui.QVBoxLayout() vglayout.addWidget(self.paramsText) self.paramsGroupbox.setLayout(vglayout) self.paramsGroupbox.hide() self.mainLayout.addLayout(self.layout) self.calibrated = False
[docs] def cleanupPage(self, *args, **kwargs): self.clearLayout(self.layout)
[docs] def setChipsetParams(self): if self.chipset == CHIPSETS["calculus.ti"]: self.phasePeriod.clear() self.phasePeriod.addItems(['90 degrees', '180 degrees']) self.phasePeriod.setCurrentIndex(1) self.modFreq2.setDisabled(True) self.modFrequency2 = 0 else: self.phasePeriod.clear() self.phasePeriod.addItems(['90 degrees', '180 degrees', '360 degrees']) self.phasePeriod.setCurrentIndex(2)
[docs] def setModFrequency(self, value): self.modFrequency = value
[docs] def setModFrequency2(self, value): self.modFrequency2 = value
[docs] def insertRow(self): i = self.phaseDistanceMeasurements.currentRow() if i >= 0 and i < self.phaseDistanceMeasurements.rowCount(): self.phaseDistanceMeasurements.insertRow(i + 1) elif self.phaseDistanceMeasurements.rowCount() == 0: self.phaseDistanceMeasurements.insertRow(0) self.calibrateButton.setEnabled(True)
[docs] def removeRow(self): i = self.phaseDistanceMeasurements.currentRow() if i >= 0 and i < self.phaseDistanceMeasurements.rowCount(): r = QtGui.QMessageBox.question(self, 'Remove Row', 'Are you sure you want to remove the current row?', \ buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if r == QtGui.QMessageBox.Yes: self.phaseDistanceMeasurements.removeRow(i) if self.phaseDistanceMeasurements.rowCount() == 0: self.calibrateButton.setDisabled(True)
[docs] def removeAllRows(self): r = QtGui.QMessageBox.question(self, 'Remove All Rows', 'Are you sure you want to remove all rows?', \ buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if r == QtGui.QMessageBox.Yes: for i in range(0, self.phaseDistanceMeasurements.rowCount()): self.phaseDistanceMeasurements.removeRow(0) self.calibrateButton.setDisabled(True)
[docs] def writeCSV(self, data, csvFile): with open(csvFile, 'w') as f: for r in data: f.write(','.join(format(c, ".3f") for c in r) + '\n')
[docs] def importCSV(self, csvFile = None): if csvFile is None: name, filter = QtGui.QFileDialog.getOpenFileName(self, 'Select CSV File', filter = 'CSV Files (*.csv)') if name: for i in range(0, self.phaseDistanceMeasurements.rowCount()): self.phaseDistanceMeasurements.removeRow(0) csvFile = str(name) self.calibrated = False self.paramsGroupbox.hide() else: return if not os.path.exists(csvFile): return with open(csvFile, 'rb') as f: reader = csv.reader(f) c = 0 for row in reader: r = self.phaseDistanceMeasurements.rowCount() self.phaseDistanceMeasurements.insertRow(self.phaseDistanceMeasurements.rowCount()) if self.phaseDistanceMeasurements.rowCount()>0: self.calibrateButton.setEnabled(True) for i in range(0, len(row)): self.phaseDistanceMeasurements.setItem(r, i, QtGui.QTableWidgetItem(row[i])) c += 1
[docs] def getData(self): d = [] for r in range(0, self.phaseDistanceMeasurements.rowCount()): x = [] for c in range(0, self.rowLength): t = self.phaseDistanceMeasurements.item(r, c).text() if len(t) == 0: QtGui.QMessageBox.critical(self, 'Data Missing', 'Data at row = %d, column = %d is empty'%(r, c)) return [] x.append(float(t)) d.append(x) return d
[docs] def calibrate (self): d1 = self.getData() csvFile = self.calibrationWizard.profilePath + "/%s %s"%(self.calibrationWizard.profileName, CalibrationNonLinearityPage.CSV_FILE_NAME) self.writeCSV(d1, csvFile) try: ret = NonLinearityCalibration(csvFile, self.modFrequency, self.modFrequency2) boo, y,y2 = ret except Exception, e: ret = False print e if ret: self.calibrationWizard.calibParams["phase_lin_corr_period"] = self.phasePeriod.currentIndex() self.calibrationWizard.calibParams["phase_lin_corr_en"] = True data = '' for c in y: data += str(int(c)) + ' ' self.calibrationWizard.calibParams["phase_lin_coeff0"] = data data = 'phase_lin_coeff0 ' + data data2 = '' if y2: for c in y2: data2 += str(int(c)) + ' ' self.calibrationWizard.calibParams["phase_lin_coeff1"] = data2 if data2: data2 = '\nphase_lin_coeff1' + data2 self.paramsText.setText(data+data2) self.paramsGroupbox.show() else: QtGui.QMessageBox.critical(self, "Cannot compute coefficients", "Check Data") self.calibrated = True self.completeChanged.emit()
[docs] def isComplete(self): return self.calibrated