# from capture.CalibrationDataCaptureDialog import CalibrationDataCaptureDialog
from PySide import QtGui, QtCore
import os
from calibration.FlatWallLensCalib import flatWallLensCalibration
from calibration.CommonPhaseOffsetRawDataSimpleAverage import commonPhaseOffset
from calibration.PerPixelOffset import perPixelOffset
from models.DataEngine import DataEngine
from models.DepthCameraStreamController import DepthCameraStreamController
from views.DataViewContainer import DataViewContainer
from CalibrationPage import CalibrationPage
import Voxel
[docs]class CalibrationDataCapturePage(CalibrationPage):
"""This code is used for live capture
This code captures data and calibrates, saving files into the profile path. Profile path = /path/to/.Voxel/profiles. """
STATE_START = 0
STATE_NEAR_CAPTURED = 1
STATE_FAR_CAPTURED = 2
STATE_COMMON_PHASE_CAPTURED = 3
STATE_PER_PIXEL_CAPTURED = 4
STRATEGY = 'FlatWall'
BUTTON_TEXTS = {'lens':["Capture Far View", "Capture Near View","Capture Common Phase OFfset Data", "Capture Per Pixel Data", "Calibrate"],
'commonPhase': ["Capture Phase Data", "Capture Phase Data for Second Modulation Frequency","Capture Per Pixel Offset Data", "Calibrate"],
'perPixel': ["Capture Pixel Data", "Calibrate"]}
MESSAGE_TEXTS = {'lens':[
"Point the depth camera flat to a wall. Make sure you only see the flat wall in the camera view below and nothing else. This will be for far view capture. Later you'll need to capture near view. Now, for far view click on the capture button.",
"Maintain the depth camera orientation to the flat wall but move it closer. Make sure you only see the flat wall in the camera view below and nothing else. Now, click on the capture button to the right.",
"Capture Data for Common Phase and Per Pixel Offset Calculation. ",
"Capture Data for Per Pixel Offset Calculation",
"Great! You've got all views captured. Now, click on the calibrate button to compute the calibration coefficents."],
'commonPhase': ["Point the depth camera flat to a wall. Make sure you only see the flat wall in the camera view below and nothing else.",
"dealias_en is turned on. Please click on capture to record data with the second modulation frequency.",
"Capture Data for Per Pixel Offset Calculation",
"All views captured. Click on calibrate to calibrate"],
'perPixel': ['Point the camera to a flat wall and capture data for calculating per pixel offsets.',
"Great! you have all the data captured. CLick on calibrate. "]}
def __init__(self, calibrationWizard):
super (CalibrationDataCapturePage, self).__init__()
self.calibrationWizard = calibrationWizard
self.setTitle("Capture Data and Calibrate Using Depth Camera")
self.setSubTitle("Please Follow the instructions to calibrate the camera")
self.layout = QtGui.QVBoxLayout(self)
self.captureGroupBox = QtGui.QGroupBox("Data Capture")
self.layout.addWidget(self.captureGroupBox)
self.dataView = None
self.progressBar = None
self.progressText = None
self.hlayout = None
self.dataEngine = None
self.depthCameraController = None
self.lensCaptured = False
self.farCaptured = False
self.nearCaptured = False
self.commonPhaseCaptured = False
self.perPixelCaptured = False
self.nearFileName = None
self.farFileName = None
self.commonPhaseFileName = None
self.perPixelFileName = None
self.complete = False
self.state = CalibrationDataCapturePage.STATE_START
#layouts for groupboxes
captureLayout = QtGui.QVBoxLayout()
self.captureGroupBox.setLayout(captureLayout)
hlayout = QtGui.QHBoxLayout()
hlayout.setAlignment(QtCore.Qt.AlignTop)
self.message = QtGui.QLabel()
self.message.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.message.setWordWrap(True)
self.message.setAlignment(QtCore.Qt.AlignTop)
hlayout.addWidget(self.message)
captureLayout.addLayout(hlayout)
self.captureButton = QtGui.QPushButton()
captureLayout.addWidget(self.captureButton)
self.captureButton.clicked.connect(self.captureDataAndCalibrate)
self.paramsGroupBox = None
self.paramsText = ''
[docs] def initializePage(self, *args, **kwargs):
self.depthCamera = self.calibrationWizard.depthCamera
self.calibrations = []
for calibration in self.calibrationWizard.calibs:
if self.calibrationWizard.calibs[calibration] == CalibrationDataCapturePage.STRATEGY:
self.calibrations.append(calibration)
if 'lens' in self.calibrations:
self.calibrationToDo = 'lens'
self.buttonTexts = CalibrationDataCapturePage.BUTTON_TEXTS['lens']
self.messageTexts = CalibrationDataCapturePage.MESSAGE_TEXTS['lens']
elif 'commonPhase' in self.calibrations:
self.calibrationToDo = 'commonPhase'
self.buttonTexts = CalibrationDataCapturePage.BUTTON_TEXTS['commonPhase']
self.messageTexts = CalibrationDataCapturePage.MESSAGE_TEXTS['commonPhase']
elif 'perPixel' in self.calibrations:
self.calibrationToDo = 'perPixel'
self.buttonTexts = CalibrationDataCapturePage.BUTTON_TEXTS['perPixel']
self.messageTexts = CalibrationDataCapturePage.MESSAGE_TEXTS['perPixel']
self.captureButton.setText(self.buttonTexts[0])
self.message.setText(self.messageTexts[0])
if not self.hlayout:
self.hlayout = QtGui.QHBoxLayout()
self.numberOfFrames = 100
self.hlayout.addWidget(QtGui.QLabel('Number of frames to capture: '))
self.frameCount = QtGui.QSpinBox()
self.frameCount.setRange(50, 1000)
self.frameCount.setValue(self.numberOfFrames)
self.frameCount.valueChanged.connect(self.setNumberOfFrames)
self.hlayout.addWidget(self.frameCount)
self.hlayout.addStretch()
self.hlayout.addWidget(QtGui.QLabel(' Distance from flat wall: '))
self.distance = QtGui.QDoubleSpinBox()
self.distance.setRange(0.1, 5000)
self.distance.setSingleStep(0.1)
self.distance.setValue(25.0)
self.distanceValue = self.distance.value()
self.distance.setDecimals(1)
self.distance.valueChanged.connect(self.setDistance)
self.hlayout.addWidget(self.distance)
self.hlayout.addWidget(QtGui.QLabel('cm'))
self.layout.addLayout(self.hlayout)
if not self.dataEngine:
self.depthCameraController = DepthCameraStreamController(self.calibrationWizard.cameraSystem, self.calibrationWizard.depthCamera)
self.dataEngine = DataEngine(self.depthCameraController)
self.dataEngine.disableStatistics()
self.captureRunning = False
self.dataEngine.connectData("phase", self.captureData, QtCore.Qt.QueuedConnection)
if not self.dataView:
self.dataView = DataViewContainer(self.dataEngine, 'phase', shouldLinkViewBox = False, showFormatMenu = True)
self.layout.addWidget(self.dataView)
if not self.progressBar:
self.progressBar = QtGui.QProgressBar()
self.currentProgressValue = 0
self.progressBar.setValue(0)
self.layout.addWidget(self.progressBar)
if not self.progressText:
self.progressText = QtGui.QLabel()
self.layout.addWidget(self.progressText)
if not self.paramsGroupBox:
self.paramsGroupBox = QtGui.QGroupBox("Calibration Parameters")
vlayout = QtGui.QVBoxLayout()
self.paramsGroupBox.setLayout(vlayout)
self.paramsLabel = QtGui.QLabel()
vlayout.addWidget(self.paramsLabel)
self.paramsGroupBox.hide()
self.layout.addWidget(self.paramsGroupBox)
self.depthCameraController.start()
[docs] def captureData(self, value):
if not self.captureRunning:
return
self.profilePath = self.calibrationWizard.profilePath\
+ os.sep + self.calibrationWizard.depthCamera.name() + os.sep + self.calibrationWizard.depthCamera.id().split(":")[-1].split(')')[0]
fileNames = {'lens':["far.vxl", "near.vxl", "commonPhase.vxl", "perPixel.vxl"],
'commonPhase': ["commonPhase.vxl" ,"commonPhase2.vxl"],
'perPixel': ["perPixel.vxl"]}
files = fileNames[self.calibrationToDo]
self.files = [self.profilePath + os.sep + f for f in files]
if self.currentFrameCount > self.numberOfFrames:
self.depthCamera.closeFrameStream()
self.stopCapture()
else:
if self.depthCamera.isSavingFrameStream():
self.currentFrameCount +=1
self.progressBar.setValue(self.currentFrameCount*100/self.numberOfFrames)
else:
ret, self.modFreq1 = self.depthCamera.getf("mod_freq1")
ret, self.modFreq2 = self.depthCamera.getf("mod_freq2")
self.fileName = self.files[value]
print self.files[value]
if not self.depthCamera.saveFrameStream(self.files[value]):
QtGui.QMessageBox.critical(self, "Can't save stream", "Cannot save the current stream")
[docs] def startCapture(self):
self.captureButton.setDisabled(True)
self.frameCount.setDisabled(True)
self.average = None
self.captureRunning = True
self.currentFrameCount = 0
[docs] def captureDataAndCalibrate(self):
r, dealiasEnabled = self.depthCamera.getb("dealias_en")
if not r:
QtGui.QMessageBox.critical(self, "Can't get parameter", "Cannot get the dealias_en parameter")
if dealiasEnabled:
r = self.depthCamera.setb('ind_freq_data_en', True)
r1 = self.depthCamera.setb('ind_freq_data_sel', False)
if self.calibrationToDo == 'lens':
if self.farCaptured == False:
self.startCapture()
self.captureData(0)
self.farFileName = self.fileName
self.farDistance = self.distanceValue
self.farCaptured = True
self.message.setText(self.messageTexts[1])
self.captureButton.setText(self.buttonTexts[1])
elif self.nearCaptured == False:
self.startCapture()
self.captureData(1)
self.nearFileName = self.fileName
self.nearDistance = self.distanceValue
if 'commonPhase' in self.calibrations:
self.commonPhaseDistance = self.distanceValue
self.commonPhaseFileName = self.fileName
self.commonPhaseFileName1 = None
if not dealiasEnabled:
self.commonPhaseCaptured = True
self.nearCaptured = True
if 'perPixel' in self.calibrations:
self.perPixelFileName = self.nearFileName
self.perPixelCaptured = True
self.message.setText(self.messageTexts[4])
self.captureButton.setText(self.buttonTexts[4])
if 'commonPhase' in self.calibrations and dealiasEnabled is True and self.commonPhaseCaptured ==False:
self.message.setText(self.messageTexts[2])
self.captureButton.setText(self.buttonTexts[2])
self.nearCaptured = True
else:
self.message.setText(self.messageTexts[4])
self.captureButton.setText(self.buttonTexts[4])
elif self.commonPhaseCaptured is False and 'commonPhase' in self.calibrations:
r1 = self.depthCamera.setb('ind_freq_data_sel', True)
self.startCapture()
self.captureData(2)
self.commonPhaseFileName1 = self.fileName
self.commonPhaseCaptured = True
self.message.setText(self.messageTexts[4])
self.captureButton.setText(self.buttonTexts[4])
elif self.perPixelCaptured is False and 'perPixel' in self.calibrations:
self.startCapture()
self.captureData(3)
self.perPixelFileName = self.fileName
self.message.setText(self.messageTexts[4])
self.captureButton.setText(self.buttonTexts[4])
else:
self.calibrate()
elif self.calibrationToDo == "commonPhase":
if self.commonPhaseCaptured == False:
self.startCapture()
if not self.commonPhaseFileName:
self.captureData(0)
self.commonPhaseFileName = self.fileName
self.commonPhaseFileName1 = None
if not dealiasEnabled:
self.commonPhaseCaptured = True
self.message.setText(self.messageTexts[3])
self.captureButton.setText(self.buttonTexts[3])
else:
self.message.setText(self.messageTexts[1])
self.captureButton.setText(self.buttonTexts[1])
r1 = self.depthCamera.setb('ind_freq_data_sel', True)
elif dealiasEnabled:
self.captureData(1)
self.commonPhaseFileName1 = self.fileName
self.message.setText(self.messageTexts[3])
self.captureButton.setText(self.buttonTexts[3])
self.commonPhaseCaptured = True
self.commonPhaseDistance = self.distanceValue
if 'perPixel' in self.calibrations:
self.perPixelFileName = self.fileName
self.perPixelCaptured = True
elif self.perPixelCaptured is False and 'perPixel' in self.calibrations:
self.startCapture()
self.captureData(1)
self.perPixelFileName = self.fileName
self.perPixelCaptured = True
self.message.setText(self.messageTexts[2])
self.captureButton.setText(self.buttonTexts[2])
else:
self.message.setText(self.messageTexts[3])
self.captureButton.setText(self.buttonTexts[3])
self.calibrate()
elif self.calibrationToDo == 'perPixel':
if self.perPixelCaptured == False:
self.startCapture()
self.captureData(0)
self.perPixelCaptured = True
self.perPixelFileName = self.fileName
self.message.setText(self.messageTexts[1])
self.captureButton.setText(self.buttonTexts[1])
else:
self.calibrate()
[docs] def calibrate(self):
if self.nearCaptured and self.farCaptured:
try:
ret, mtx, dist = flatWallLensCalibration(self.nearFileName, self.nearDistance/100, self.farFileName, self.farDistance/100)
except Exception, e:
ret = False
if ret:
self.paramsText += "cx = %f\n cy = %f/n fx = fy = %f/n k1 = %f\n k2 = %f/n k3 = %f\n"\
%(mtx[0,2], mtx[1,2], mtx[0,0], dist[0], dist[1], dist[2])
self.message.setText("Calibration Done. Click on next to proceed")
self.calibrationWizard.calibParams['cx'] = mtx[0,2]
self.calibrationWizard.calibParams['cy'] = mtx[1,2]
self.calibrationWizard.calibParams['fx'] = mtx[0,0]
self.calibrationWizard.calibParams['fy'] = mtx[0,0]
self.calibrationWizard.calibParams['k1'] = dist[0]
self.calibrationWizard.calibParams['k2'] = dist[1]
self.calibrationWizard.calibParams['k3'] = dist[2]
self.calibrationWizard.calibParams['p1'] = 0
self.calibrationWizard.calibParams['p1'] = 0
self.completed = True
self.completeChanged.emit()
else:
QtGui.QMessageBox.critical(self, "Check Data", "Can't get the coefficients")
if self.commonPhaseCaptured:
try:
if 'cx' in self.calibrationWizard.calibParams:\
cx = self.calibrationWizard.calibParams['cx']
else:
cx = 0
if 'cy' in self.calibrationWizard.calibParams:
cy = self.calibrationWizard.calibParams['cy']
else:
cy = 0
ret, phaseCorr1, phaseCorr2, _, _ = commonPhaseOffset(self.commonPhaseFileName, self.commonPhaseDistance/100, self.modFreq1, cx, cy, self.commonPhaseFileName1, self.modFreq2, chipset = self.depthCamera.chipset())
except Exception, e:
print(e)
ret = False
if ret:
self.paramsText += "phase_corr_1 = %d\n phase_corr_2 = %d\n"%(phaseCorr1, phaseCorr2)
self.calibrationWizard.calibParams['phase_corr1'] = phaseCorr1
self.calibrationWizard.calibParams['phase_corr2'] = phaseCorr2
else:
QtGui.QMessageBox.critical(self, "Check Data", "Can't get the coefficients")
if self.perPixelCaptured:
try:
c = Voxel.Configuration()
r, path = c.getLocalConfPath()
ret, phaseOffsetFileName, _, _ = perPixelOffset(self.perPixelFileName, pathToSave=path, profileName = self.calibrationWizard.profileName)
except Exception, e:
ret = False
print e
if ret:
self.paramsText += "phaseOffsetFileName: %s"%(phaseOffsetFileName)
self.calibrationWizard.calibParams['phasecorrection'] = 'file:'+os.path.basename(phaseOffsetFileName)
else:
QtGui.QMessageBox.critical(self, "Check Data", "Can't get the coefficients")
self.paramsLabel.setText(self.paramsText)
self.paramsGroupBox.show()
if self.paramsText:
self.complete = True
self.completeChanged.emit()
[docs] def isComplete(self, *args, **kwargs):
return self.complete
[docs] def setNumberOfFrames(self, value):
self.numberOfFrames = value
[docs] def stopCapture(self):
self.captureRunning = False
self.captureButton.setEnabled(True)
if self.captureButton.text()!='Calibrate':
self.frameCount.setEnabled(True)
self.progressBar.setValue(0)
[docs] def cleanupPage(self, *args, **kwargs):
self.depthCameraController.stop()
self.nearCaptured =False
self.farCaptured = False
self.commonPhaseCaptured = False
self.perPixelCaptured = False
[docs] def closeEvent(self, *args, **kwargs):
self.depthCameraController.stop()
[docs] def setDistance(self, value):
self.distanceValue = value