Commit 480495a3 authored by Andy Regensky's avatar Andy Regensky
Browse files

Allow changing sensor dimensions and add overlay for non-square shaped sensor pixels

parent 4790de88
...@@ -20,8 +20,8 @@ class MainViewModel(QObject): ...@@ -20,8 +20,8 @@ class MainViewModel(QObject):
'calibrated': projections.CalibratedProjection 'calibrated': projections.CalibratedProjection
} }
self.sensor_size_mm = (5.2, 5.2) self.sensor_size_mm = (5.2, 10.4)
self.sensor_size_px = (1088, 1088) self.sensor_size_px = (1088, 2176)
self.focal_length_mm = 1.8 self.focal_length_mm = 1.8
self.projection_key = 'equisolid' self.projection_key = 'equisolid'
self.calibration_coeffs = None self.calibration_coeffs = None
...@@ -56,6 +56,11 @@ class MainViewModel(QObject): ...@@ -56,6 +56,11 @@ class MainViewModel(QObject):
self.uwc_sign = None self.uwc_sign = None
self.updateProjections() self.updateProjections()
@property
def sensor_dimensions_valid(self):
return np.isclose(self.sensor_size_px[0]/self.sensor_size_mm[0],
self.sensor_size_px[1]/self.sensor_size_mm[1])
def setSensorSize(self, sensor_size): def setSensorSize(self, sensor_size):
self.sensor_size_mm = sensor_size self.sensor_size_mm = sensor_size
self.updateProjections() self.updateProjections()
...@@ -114,6 +119,10 @@ class MainViewModel(QObject): ...@@ -114,6 +119,10 @@ class MainViewModel(QObject):
return focal_length, calib_coeffs return focal_length, calib_coeffs
def updateProjections(self): def updateProjections(self):
# Do not update the projections, if the sensor itself is not valid.
if not self.sensor_dimensions_valid:
self.didChange.emit()
return
focal_length_px = projections.Projection.to_focal_length_px(self.focal_length_mm, self.sensor_size_mm, self.sensor_size_px) focal_length_px = projections.Projection.to_focal_length_px(self.focal_length_mm, self.sensor_size_mm, self.sensor_size_px)
if self.projection_key == 'calibrated': if self.projection_key == 'calibrated':
px_per_mm = self.sensor_size_px[0]/self.sensor_size_mm[0] px_per_mm = self.sensor_size_px[0]/self.sensor_size_mm[0]
...@@ -155,8 +164,8 @@ class MainViewModel(QObject): ...@@ -155,8 +164,8 @@ class MainViewModel(QObject):
self.samples_per_edge) self.samples_per_edge)
# Filter within FOV 180 # Filter within FOV 180
r, _ = coordinate_conversion.cartesian_to_polar(block_y - self.center[0], r, _ = coordinate_conversion.cartesian_to_polar(block_y - self.center[1],
block_x - self.center[1]) block_x - self.center[0])
block_x = block_x[r <= self.fov_180_radius] block_x = block_x[r <= self.fov_180_radius]
block_y = block_y[r <= self.fov_180_radius] block_y = block_y[r <= self.fov_180_radius]
...@@ -165,8 +174,8 @@ class MainViewModel(QObject): ...@@ -165,8 +174,8 @@ class MainViewModel(QObject):
self.didChange.emit() self.didChange.emit()
def updatePerspectiveBlockpoints(self): def updatePerspectiveBlockpoints(self):
block_yfc = self.block_yf - self.center[0] block_yfc = self.block_yf - self.center[1]
block_xfc = self.block_xf - self.center[1] block_xfc = self.block_xf - self.center[0]
r_f, phi = coordinate_conversion.cartesian_to_polar(block_yfc, block_xfc) r_f, phi = coordinate_conversion.cartesian_to_polar(block_yfc, block_xfc)
r_p = self.projection.transform_to(self.perspective, r_f) r_p = self.projection.transform_to(self.perspective, r_f)
...@@ -192,15 +201,14 @@ class MainViewModel(QObject): ...@@ -192,15 +201,14 @@ class MainViewModel(QObject):
r_fm = self.perspective.transform_to(self.projection, r_pm) r_fm = self.perspective.transform_to(self.projection, r_pm)
r_fm = r_fm + (self.uwc_sign < 0) * 2 * (self.projection.radius(np.deg2rad(90)) - r_fm) r_fm = r_fm + (self.uwc_sign < 0) * 2 * (self.projection.radius(np.deg2rad(90)) - r_fm)
block_yfm, block_xfm = coordinate_conversion.polar_to_cartesian(r_fm, phi_m) block_yfm, block_xfm = coordinate_conversion.polar_to_cartesian(r_fm, phi_m)
center = np.asarray(self.sensor_size_px) / 2 self.block_yfm = block_yfm + self.center[1]
self.block_yfm = block_yfm + center[0] self.block_xfm = block_xfm + self.center[0]
self.block_xfm = block_xfm + center[1]
self.didChange.emit() self.didChange.emit()
def updateControlBlockpoints(self): def updateControlBlockpoints(self):
block_center = np.asarray(self.origin) + (np.asarray(self.blocksize) - 1) / 2 block_center = np.asarray(self.origin) + (np.asarray(self.blocksize) - 1) / 2
r_f, phi = coordinate_conversion.cartesian_to_polar(block_center[1] - self.center[0], r_f, phi = coordinate_conversion.cartesian_to_polar(block_center[1] - self.center[1],
block_center[0] - self.center[1]) block_center[0] - self.center[0])
r_p = self.projection.transform_to(self.perspective, r_f) r_p = self.projection.transform_to(self.perspective, r_f)
cp0_y, cp0_x = coordinate_conversion.polar_to_cartesian(r_p, phi) cp0_y, cp0_x = coordinate_conversion.polar_to_cartesian(r_p, phi)
cp0_y = cp0_y - self.blocksize[1] / 2 cp0_y = cp0_y - self.blocksize[1] / 2
......
from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel, QGraphicsBlurEffect
from PySide2.QtCore import Qt from PySide2.QtCore import Qt, Slot
from fishui.MainViewModel import MainViewModel from fishui.MainViewModel import MainViewModel
from fishui.widgets.AspectRatioWidget import AspectRatioWidget from fishui.widgets.AspectRatioWidget import AspectRatioWidget
from fishui.widgets.FisheyeBlockWidget import FisheyeBlockWidget from fishui.widgets.FisheyeBlockWidget import FisheyeBlockWidget
...@@ -11,6 +11,9 @@ class DistortionVisualizationWidget(QWidget): ...@@ -11,6 +11,9 @@ class DistortionVisualizationWidget(QWidget):
def __init__(self, parent, viewModel: MainViewModel): def __init__(self, parent, viewModel: MainViewModel):
super().__init__(parent) super().__init__(parent)
self.viewModel = viewModel
self.viewModel.didChange.connect(self.viewModelChanged)
# Fisheye visualization # Fisheye visualization
self.fisheyeLabel = QLabel(self) self.fisheyeLabel = QLabel(self)
self.fisheyeLabel.setText("Fisheye domain") self.fisheyeLabel.setText("Fisheye domain")
...@@ -39,4 +42,35 @@ class DistortionVisualizationWidget(QWidget): ...@@ -39,4 +42,35 @@ class DistortionVisualizationWidget(QWidget):
layout.addLayout(perspectiveLayout) layout.addLayout(perspectiveLayout)
self.setLayout(layout) self.setLayout(layout)
# Invalid sensor dimensions overlay
self.overlay = QLabel(self)
self.overlay.setText("Sensor dimensions do not result in square-sized pixels.")
self.overlay.setStyleSheet("background-color: rgba(100, 100, 100, 0.5);"
"color: white;"
"font-weight: bold;"
"font-size: 16px;")
self.overlay.setAlignment(Qt.AlignCenter)
self.overlay.setVisible(False)
self.show() self.show()
def resizeEvent(self, e):
w = e.size().width()
h = e.size().height()
self.overlay.setGeometry(0, 0, w, h)
@Slot()
def viewModelChanged(self):
if self.viewModel.sensor_dimensions_valid:
self.overlay.setVisible(False)
self.fisheyeLabel.setGraphicsEffect(None)
self.fisheyeBlockWidget.setGraphicsEffect(None)
self.perspectiveLabel.setGraphicsEffect(None)
self.perspectiveBlockWidget.setGraphicsEffect(None)
else:
self.overlay.setVisible(True)
self.fisheyeLabel.setGraphicsEffect(QGraphicsBlurEffect(self))
self.fisheyeBlockWidget.setGraphicsEffect(QGraphicsBlurEffect(self))
self.perspectiveLabel.setGraphicsEffect(QGraphicsBlurEffect(self))
self.perspectiveBlockWidget.setGraphicsEffect(QGraphicsBlurEffect(self))
...@@ -40,7 +40,10 @@ class FisheyeBlockWidget(QWidget): ...@@ -40,7 +40,10 @@ class FisheyeBlockWidget(QWidget):
def paintEvent(self, event): def paintEvent(self, event):
painter = QPainter() painter = QPainter()
painter.begin(self) painter.begin(self)
painter.setWindow(QRect(0, 0, self.viewModel.sensor_size_px[1], self.viewModel.sensor_size_px[0])) painter.setWindow(QRect(0,
0,
self.viewModel.sensor_size_px[0],
self.viewModel.sensor_size_px[1]))
painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(painter.window(), QColor(255, 255, 255)) painter.fillRect(painter.window(), QColor(255, 255, 255))
self.drawFisheyeBoundary(event, painter) self.drawFisheyeBoundary(event, painter)
...@@ -54,8 +57,8 @@ class FisheyeBlockWidget(QWidget): ...@@ -54,8 +57,8 @@ class FisheyeBlockWidget(QWidget):
painter.setPen(pen) painter.setPen(pen)
painter.drawEllipse( painter.drawEllipse(
QRect( QRect(
self.viewModel.center[1] - self.viewModel.fov_180_radius,
self.viewModel.center[0] - self.viewModel.fov_180_radius, self.viewModel.center[0] - self.viewModel.fov_180_radius,
self.viewModel.center[1] - self.viewModel.fov_180_radius,
2 * self.viewModel.fov_180_radius, 2 * self.viewModel.fov_180_radius,
2 * self.viewModel.fov_180_radius 2 * self.viewModel.fov_180_radius
) )
...@@ -82,8 +85,8 @@ class FisheyeBlockWidget(QWidget): ...@@ -82,8 +85,8 @@ class FisheyeBlockWidget(QWidget):
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
if self.initialMouse is not None: if self.initialMouse is not None:
relativeMotion = event.pos() - self.initialMouse relativeMotion = event.pos() - self.initialMouse
relativeMotion.setX(relativeMotion.x() * (self.viewModel.sensor_size_px[1]/self.width())) relativeMotion.setX(relativeMotion.x() * (self.viewModel.sensor_size_px[0]/self.width()))
relativeMotion.setY(relativeMotion.y() * (self.viewModel.sensor_size_px[0] / self.height())) relativeMotion.setY(relativeMotion.y() * (self.viewModel.sensor_size_px[1] / self.height()))
origin = (self.initialOrigin[0] + relativeMotion.x(), self.initialOrigin[1] + relativeMotion.y()) origin = (self.initialOrigin[0] + relativeMotion.x(), self.initialOrigin[1] + relativeMotion.y())
self.viewModel.setOrigin(origin) self.viewModel.setOrigin(origin)
......
...@@ -33,8 +33,8 @@ class PerspectiveBlockWidget(QWidget): ...@@ -33,8 +33,8 @@ class PerspectiveBlockWidget(QWidget):
perspectiveMovedPolygon = QPolygonF() perspectiveMovedPolygon = QPolygonF()
controlPointPolygon = QPolygonF() controlPointPolygon = QPolygonF()
controlPointMovedPolygon = QPolygonF() controlPointMovedPolygon = QPolygonF()
sensor_offset_x = (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[1]) / 2 sensor_offset_x = (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[0]) / 2
sensor_offset_y = (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[0]) / 2 sensor_offset_y = (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[1]) / 2
block_xp = self.viewModel.block_xp + sensor_offset_x block_xp = self.viewModel.block_xp + sensor_offset_x
block_yp = self.viewModel.block_yp + sensor_offset_y block_yp = self.viewModel.block_yp + sensor_offset_y
block_xpm = self.viewModel.block_xpm + sensor_offset_x block_xpm = self.viewModel.block_xpm + sensor_offset_x
...@@ -63,8 +63,8 @@ class PerspectiveBlockWidget(QWidget): ...@@ -63,8 +63,8 @@ class PerspectiveBlockWidget(QWidget):
def paintEvent(self, event): def paintEvent(self, event):
painter = QPainter() painter = QPainter()
painter.begin(self) painter.begin(self)
painter.setWindow(QRect(0, 0, self.viewModel.perspective_scale * self.viewModel.sensor_size_px[1], painter.setWindow(QRect(0, 0, self.viewModel.perspective_scale * self.viewModel.sensor_size_px[0],
self.viewModel.perspective_scale * self.viewModel.sensor_size_px[0])) self.viewModel.perspective_scale * self.viewModel.sensor_size_px[1]))
painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(painter.window(), QColor(255, 255, 255)) painter.fillRect(painter.window(), QColor(255, 255, 255))
self.drawPolygon(event, painter) self.drawPolygon(event, painter)
...@@ -103,8 +103,8 @@ class PerspectiveBlockWidget(QWidget): ...@@ -103,8 +103,8 @@ class PerspectiveBlockWidget(QWidget):
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
if self.initialMouse is not None: if self.initialMouse is not None:
relativeMotion = event.pos() - self.initialMouse relativeMotion = event.pos() - self.initialMouse
relativeMotion.setX(relativeMotion.x() * (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[1] / self.width())) relativeMotion.setX(relativeMotion.x() * (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[0] / self.width()))
relativeMotion.setY(relativeMotion.y() * (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[0] / self.height())) relativeMotion.setY(relativeMotion.y() * (self.viewModel.perspective_scale * self.viewModel.sensor_size_px[1] / self.height()))
if self.viewModel.affineModel: if self.viewModel.affineModel:
motion_vector_cp0 = (self.initialMV0[0] + relativeMotion.x(), self.initialMV0[1] + relativeMotion.y()) motion_vector_cp0 = (self.initialMV0[0] + relativeMotion.x(), self.initialMV0[1] + relativeMotion.y())
motion_vector_cp1 = (self.initialMV1[0] + relativeMotion.x(), self.initialMV1[1] + relativeMotion.y()) motion_vector_cp1 = (self.initialMV1[0] + relativeMotion.x(), self.initialMV1[1] + relativeMotion.y())
......
...@@ -13,8 +13,8 @@ class PropertiesWidget(QWidget): ...@@ -13,8 +13,8 @@ class PropertiesWidget(QWidget):
self.viewModel = viewModel self.viewModel = viewModel
self.viewModel.didChange.connect(self.updateValues) self.viewModel.didChange.connect(self.updateValues)
negIntValidator = QIntValidator(-1088, 1088, self) negIntValidator = QIntValidator(-999999, 999999, self)
intValidator = QIntValidator(0, 1088, self) intValidator = QIntValidator(0, 999999, self)
doubleValidator = QDoubleValidator(0, float("inf"), 2, self) doubleValidator = QDoubleValidator(0, float("inf"), 2, self)
# Setup widgets # Setup widgets
...@@ -28,12 +28,10 @@ class PropertiesWidget(QWidget): ...@@ -28,12 +28,10 @@ class PropertiesWidget(QWidget):
self.sensorSizeWidthEdit = QLineEdit(self) self.sensorSizeWidthEdit = QLineEdit(self)
self.sensorSizeWidthEdit.setValidator(doubleValidator) self.sensorSizeWidthEdit.setValidator(doubleValidator)
self.sensorSizeWidthEdit.editingFinished.connect(self.sensorSizeWidthEditingFinished) self.sensorSizeWidthEdit.editingFinished.connect(self.sensorSizeWidthEditingFinished)
self.sensorSizeWidthEdit.setEnabled(False)
self.sensorSizeHeightEdit = QLineEdit(self) self.sensorSizeHeightEdit = QLineEdit(self)
self.sensorSizeHeightEdit.setValidator(doubleValidator) self.sensorSizeHeightEdit.setValidator(doubleValidator)
self.sensorSizeHeightEdit.editingFinished.connect(self.sensorSizeHeightEditingFinished) self.sensorSizeHeightEdit.editingFinished.connect(self.sensorSizeHeightEditingFinished)
self.sensorSizeHeightEdit.setEnabled(False)
self.resolutionLabel = QLabel(self) self.resolutionLabel = QLabel(self)
self.resolutionLabel.setText("Sensor resolution:") self.resolutionLabel.setText("Sensor resolution:")
...@@ -41,12 +39,10 @@ class PropertiesWidget(QWidget): ...@@ -41,12 +39,10 @@ class PropertiesWidget(QWidget):
self.resolutionWidthEdit = QLineEdit(self) self.resolutionWidthEdit = QLineEdit(self)
self.resolutionWidthEdit.setValidator(intValidator) self.resolutionWidthEdit.setValidator(intValidator)
self.resolutionWidthEdit.editingFinished.connect(self.resolutionWidthEditingFinished) self.resolutionWidthEdit.editingFinished.connect(self.resolutionWidthEditingFinished)
self.resolutionWidthEdit.setEnabled(False)
self.resolutionHeightEdit = QLineEdit(self) self.resolutionHeightEdit = QLineEdit(self)
self.resolutionHeightEdit.setValidator(intValidator) self.resolutionHeightEdit.setValidator(intValidator)
self.resolutionHeightEdit.editingFinished.connect(self.resolutionHeightEditingFinished) self.resolutionHeightEdit.editingFinished.connect(self.resolutionHeightEditingFinished)
self.resolutionHeightEdit.setEnabled(False)
self.focalLengthLabel = QLabel(self) self.focalLengthLabel = QLabel(self)
self.focalLengthLabel.setText("Focal length:") self.focalLengthLabel.setText("Focal length:")
...@@ -191,25 +187,26 @@ class PropertiesWidget(QWidget): ...@@ -191,25 +187,26 @@ class PropertiesWidget(QWidget):
@Slot() @Slot()
def sensorSizeWidthEditingFinished(self): def sensorSizeWidthEditingFinished(self):
sensor_size = self.viewModel.sensor_size_mm sensor_size = self.viewModel.sensor_size_mm
sensor_size = (sensor_size[0], float(self.sensorSizeWidthEdit.text())) sensor_size = (float(self.sensorSizeWidthEdit.text()), sensor_size[1])
print(sensor_size)
self.viewModel.setSensorSize(sensor_size) self.viewModel.setSensorSize(sensor_size)
@Slot() @Slot()
def sensorSizeHeightEditingFinished(self): def sensorSizeHeightEditingFinished(self):
sensor_size = self.viewModel.sensor_size_mm sensor_size = self.viewModel.sensor_size_mm
sensor_size = (float(self.sensorSizeWidthEdit.text()), sensor_size[1]) sensor_size = (sensor_size[0], float(self.sensorSizeHeightEdit.text()))
self.viewModel.setSensorSize(sensor_size) self.viewModel.setSensorSize(sensor_size)
@Slot() @Slot()
def resolutionWidthEditingFinished(self): def resolutionWidthEditingFinished(self):
resolution = self.viewModel.sensor_size_px resolution = self.viewModel.sensor_size_px
resolution = (resolution[0], int(self.resolutionHeightEdit.text())) resolution = (int(self.resolutionWidthEdit.text()), resolution[1])
self.viewModel.setSensorResolution(resolution) self.viewModel.setSensorResolution(resolution)
@Slot() @Slot()
def resolutionHeightEditingFinished(self): def resolutionHeightEditingFinished(self):
resolution = self.viewModel.sensor_size_px resolution = self.viewModel.sensor_size_px
resolution = (int(self.resolutionWidthEdit.text()), resolution[1]) resolution = (resolution[0], int(self.resolutionHeightEdit.text()))
self.viewModel.setSensorResolution(resolution) self.viewModel.setSensorResolution(resolution)
@Slot() @Slot()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment