Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LMS
FishUI
Commits
6f1d2d7f
Commit
6f1d2d7f
authored
Jul 13, 2020
by
Andy Regensky
Browse files
Implement fisheye image overlay including arrow key navigation
parent
b17fd617
Changes
9
Hide whitespace changes
Inline
Side-by-side
fishui/MainViewModel.py
View file @
6f1d2d7f
...
...
@@ -56,6 +56,10 @@ class MainViewModel(QObject):
self
.
uwc_sign
=
None
self
.
updateProjections
()
# Fisheye background image
self
.
_fisheye_images
=
[]
self
.
_current_fisheye_idx
=
0
@
property
def
sensor_dimensions_valid
(
self
):
return
np
.
isclose
(
self
.
sensor_size_px
[
0
]
/
self
.
sensor_size_mm
[
0
],
...
...
@@ -252,3 +256,22 @@ class MainViewModel(QObject):
self
.
block_ctr_pym
=
block_ctr_pym
self
.
block_ctr_pxm
=
block_ctr_pxm
self
.
didChange
.
emit
()
def
setFisheyeImages
(
self
,
images
):
self
.
_fisheye_images
=
images
self
.
_current_fisheye_idx
=
0
self
.
didChange
.
emit
()
def
nextFisheyeImage
(
self
):
self
.
_current_fisheye_idx
+=
1
self
.
didChange
.
emit
()
def
previousFisheyeImage
(
self
):
self
.
_current_fisheye_idx
-=
1
self
.
didChange
.
emit
()
@
property
def
currentFisheyeImage
(
self
):
if
len
(
self
.
_fisheye_images
)
==
0
:
return
None
return
self
.
_fisheye_images
[
self
.
_current_fisheye_idx
%
len
(
self
.
_fisheye_images
)]
fishui/MainWindow.py
View file @
6f1d2d7f
from
PySide2.QtWidgets
import
*
from
PySide2.QtCore
import
Qt
import
fishui.widgets
as
widgets
from
fishui.MainViewModel
import
MainViewModel
...
...
@@ -13,15 +14,19 @@ class MainWindow(QMainWindow):
self
.
distortionWidget
=
widgets
.
DistortionVisualizationWidget
(
self
,
self
.
viewModel
)
# layout
splitter
=
QSplitter
()
splitter
=
QSplitter
(
self
)
splitter
.
addWidget
(
self
.
propertiesWidget
)
splitter
.
addWidget
(
self
.
distortionWidget
)
splitter
.
setHandleWidth
(
2
)
splitter
.
setChildrenCollapsible
(
False
)
splitter
.
setStyleSheet
(
"QSplitter:handle { background-color: gray; }"
)
# widget = QWidget()
# widget.setLayout(layout)
self
.
setCentralWidget
(
splitter
)
self
.
setFocus
()
self
.
show
()
def
keyPressEvent
(
self
,
event
):
if
event
.
key
()
==
Qt
.
Key_Right
:
self
.
viewModel
.
nextFisheyeImage
()
elif
event
.
key
()
==
Qt
.
Key_Left
:
self
.
viewModel
.
previousFisheyeImage
()
fishui/widgets/DistortionVisualizationWidget.py
View file @
6f1d2d7f
...
...
@@ -2,7 +2,7 @@ from PySide2.QtWidgets import QWidget, QGridLayout, QLabel, QGraphicsBlurEffect,
from
PySide2.QtCore
import
Qt
,
Slot
from
fishui.MainViewModel
import
MainViewModel
from
fishui.widgets.AspectRatioWidget
import
AspectRatioWidget
from
fishui.widgets.Fisheye
Block
Widget
import
Fisheye
Block
Widget
from
fishui.widgets.FisheyeWidget
import
FisheyeWidget
from
fishui.widgets.PerspectiveBlockWidget
import
PerspectiveBlockWidget
...
...
@@ -20,7 +20,7 @@ class DistortionVisualizationWidget(QWidget):
self
.
fisheyeLabel
.
setStyleSheet
(
"font-weight: bold; font-size: 16px"
)
self
.
fisheyeLabel
.
setAlignment
(
Qt
.
AlignCenter
)
self
.
fisheyeLabel
.
setSizePolicy
(
QSizePolicy
.
Preferred
,
QSizePolicy
.
Fixed
)
self
.
fisheye
Block
Widget
=
AspectRatioWidget
(
Fisheye
Block
Widget
(
self
,
viewModel
),
self
)
self
.
fisheyeWidget
=
AspectRatioWidget
(
FisheyeWidget
(
self
,
viewModel
),
self
)
# Perspective visualization
self
.
perspectiveLabel
=
QLabel
(
self
)
...
...
@@ -35,11 +35,12 @@ class DistortionVisualizationWidget(QWidget):
perspective_label_width
=
self
.
perspectiveLabel
.
sizeHint
().
width
()
min_width_constraint
=
max
(
fisheye_label_width
,
perspective_label_width
)
self
.
fisheyeLabel
.
setMinimumWidth
(
min_width_constraint
)
self
.
perspectiveLabel
.
setMinimumWidth
(
min_width_constraint
)
# Layout
layout
=
QGridLayout
(
self
)
layout
.
addWidget
(
self
.
fisheyeLabel
,
0
,
0
)
layout
.
addWidget
(
self
.
fisheye
Block
Widget
,
1
,
0
)
layout
.
addWidget
(
self
.
fisheyeWidget
,
1
,
0
)
layout
.
addWidget
(
self
.
perspectiveLabel
,
0
,
1
)
layout
.
addWidget
(
self
.
perspectiveBlockWidget
,
1
,
1
)
...
...
@@ -68,15 +69,15 @@ class DistortionVisualizationWidget(QWidget):
if
self
.
viewModel
.
sensor_dimensions_valid
:
self
.
overlay
.
setVisible
(
False
)
self
.
fisheyeLabel
.
setGraphicsEffect
(
None
)
self
.
fisheye
Block
Widget
.
setGraphicsEffect
(
None
)
self
.
fisheyeWidget
.
setGraphicsEffect
(
None
)
self
.
perspectiveLabel
.
setGraphicsEffect
(
None
)
self
.
perspectiveBlockWidget
.
setGraphicsEffect
(
None
)
aspect_ratio
=
self
.
viewModel
.
sensor_size_px
[
0
]
/
self
.
viewModel
.
sensor_size_px
[
1
]
self
.
fisheye
Block
Widget
.
setAspectRatio
(
aspect_ratio
)
self
.
fisheyeWidget
.
setAspectRatio
(
aspect_ratio
)
self
.
perspectiveBlockWidget
.
setAspectRatio
(
aspect_ratio
)
else
:
self
.
overlay
.
setVisible
(
True
)
self
.
fisheyeLabel
.
setGraphicsEffect
(
QGraphicsBlurEffect
(
self
))
self
.
fisheye
Block
Widget
.
setGraphicsEffect
(
QGraphicsBlurEffect
(
self
))
self
.
fisheyeWidget
.
setGraphicsEffect
(
QGraphicsBlurEffect
(
self
))
self
.
perspectiveLabel
.
setGraphicsEffect
(
QGraphicsBlurEffect
(
self
))
self
.
perspectiveBlockWidget
.
setGraphicsEffect
(
QGraphicsBlurEffect
(
self
))
fishui/widgets/FisheyeBackgroundWidget.py
0 → 100644
View file @
6f1d2d7f
import
sys
from
PySide2.QtGui
import
QPainter
,
QColor
,
QPainterPath
,
QPen
,
QPalette
,
QPolygonF
,
QImage
from
PySide2.QtWidgets
import
QWidget
,
QApplication
,
QMenu
,
QAction
,
QFileDialog
from
PySide2.QtCore
import
QSize
,
Qt
,
QPointF
,
QRect
,
QRectF
,
Slot
from
fishui.MainViewModel
import
MainViewModel
class
FisheyeBackgroundWidget
(
QWidget
):
def
__init__
(
self
,
parent
,
viewModel
:
MainViewModel
):
super
().
__init__
(
parent
)
self
.
viewModel
=
viewModel
self
.
viewModel
.
didChange
.
connect
(
self
.
repaint
)
self
.
show
()
def
sizeHint
(
self
):
return
QSize
(
400
,
400
)
def
paintEvent
(
self
,
event
):
painter
=
QPainter
()
painter
.
begin
(
self
)
painter
.
setWindow
(
QRect
(
0
,
0
,
self
.
viewModel
.
sensor_size_px
[
0
],
self
.
viewModel
.
sensor_size_px
[
1
]))
painter
.
setRenderHint
(
QPainter
.
Antialiasing
)
painter
.
fillRect
(
painter
.
window
(),
QColor
(
255
,
255
,
255
))
self
.
drawImage
(
painter
)
self
.
drawFisheyeBoundary
(
painter
)
painter
.
end
()
def
drawImage
(
self
,
painter
):
image_file
=
self
.
viewModel
.
currentFisheyeImage
if
image_file
is
None
:
return
image
=
QImage
(
image_file
)
rect
=
QRectF
(
0
,
0
,
self
.
viewModel
.
sensor_size_px
[
0
],
self
.
viewModel
.
sensor_size_px
[
1
])
painter
.
drawImage
(
rect
,
image
,
rect
)
def
drawFisheyeBoundary
(
self
,
painter
):
pen
=
QPen
()
pen
.
setColor
(
QColor
(
0
,
0
,
0
))
pen
.
setWidth
(
painter
.
window
().
width
()
/
200
)
painter
.
setPen
(
pen
)
painter
.
drawEllipse
(
QRect
(
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
)
)
def
contextMenuEvent
(
self
,
event
):
menu
=
QMenu
(
self
)
openAct
=
QAction
(
"Open"
,
self
)
openAct
.
setStatusTip
(
"Open a background image"
)
openAct
.
triggered
.
connect
(
self
.
openImage
)
menu
.
addAction
(
openAct
)
menu
.
exec_
(
event
.
globalPos
())
@
Slot
()
def
openImage
(
self
):
image_files
=
QFileDialog
.
getOpenFileNames
(
self
,
"Open images"
,
"."
,
"Images (*.png *.jpg)"
)[
0
]
self
.
viewModel
.
setFisheyeImages
(
image_files
)
fishui/widgets/FisheyeBlockWidget.py
View file @
6f1d2d7f
...
...
@@ -19,7 +19,6 @@ class FisheyeBlockWidget(QWidget):
self
.
initialOrigin
=
None
self
.
initialMouse
=
None
# self.setMinimumSize(QSize(300, 300))
self
.
show
()
@
Slot
()
...
...
@@ -45,25 +44,9 @@ class FisheyeBlockWidget(QWidget):
self
.
viewModel
.
sensor_size_px
[
0
],
self
.
viewModel
.
sensor_size_px
[
1
]))
painter
.
setRenderHint
(
QPainter
.
Antialiasing
)
painter
.
fillRect
(
painter
.
window
(),
QColor
(
255
,
255
,
255
))
self
.
drawFisheyeBoundary
(
event
,
painter
)
self
.
drawPolygons
(
event
,
painter
)
painter
.
end
()
def
drawFisheyeBoundary
(
self
,
event
,
painter
):
pen
=
QPen
()
pen
.
setColor
(
QColor
(
0
,
0
,
0
))
pen
.
setWidth
(
painter
.
window
().
width
()
/
200
)
painter
.
setPen
(
pen
)
painter
.
drawEllipse
(
QRect
(
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
)
)
def
drawPolygons
(
self
,
event
,
painter
):
orange
=
QColor
(
255
,
127
,
14
)
blue
=
QColor
(
31
,
119
,
180
)
...
...
@@ -79,8 +62,9 @@ class FisheyeBlockWidget(QWidget):
painter
.
drawPolygon
(
self
.
fisheyePolygon
)
def
mousePressEvent
(
self
,
event
):
self
.
initialOrigin
=
self
.
viewModel
.
origin
self
.
initialMouse
=
event
.
pos
()
if
event
.
button
()
==
Qt
.
LeftButton
:
self
.
initialOrigin
=
self
.
viewModel
.
origin
self
.
initialMouse
=
event
.
pos
()
def
mouseMoveEvent
(
self
,
event
):
if
self
.
initialMouse
is
not
None
:
...
...
@@ -91,5 +75,6 @@ class FisheyeBlockWidget(QWidget):
self
.
viewModel
.
setOrigin
(
origin
)
def
mouseReleaseEvent
(
self
,
event
):
self
.
initialOrigin
=
None
self
.
initialMouse
=
None
if
event
.
button
()
==
Qt
.
LeftButton
:
self
.
initialOrigin
=
None
self
.
initialMouse
=
None
fishui/widgets/FisheyeWidget.py
0 → 100644
View file @
6f1d2d7f
from
PySide2.QtWidgets
import
QWidget
,
QGridLayout
,
QLabel
,
QGraphicsBlurEffect
,
QSizePolicy
from
PySide2.QtCore
import
Qt
,
Slot
,
QSize
from
fishui.MainViewModel
import
MainViewModel
from
fishui.widgets.FisheyeBackgroundWidget
import
FisheyeBackgroundWidget
from
fishui.widgets.FisheyeBlockWidget
import
FisheyeBlockWidget
# TODO: Overlaying widgets using QWidget leads to repainting all widgets if child widget is updated. Use QGraphics...?
class
FisheyeWidget
(
QWidget
):
def
__init__
(
self
,
parent
,
viewModel
:
MainViewModel
):
super
().
__init__
(
parent
)
self
.
fisheyeBackgroundWidget
=
FisheyeBackgroundWidget
(
self
,
viewModel
)
self
.
fisheyeBlockWidget
=
FisheyeBlockWidget
(
self
,
viewModel
)
self
.
show
()
def
sizeHint
(
self
):
return
QSize
(
400
,
400
)
def
resizeEvent
(
self
,
event
):
w
=
event
.
size
().
width
()
h
=
event
.
size
().
height
()
self
.
fisheyeBackgroundWidget
.
setGeometry
(
0
,
0
,
w
,
h
)
self
.
fisheyeBlockWidget
.
setGeometry
(
0
,
0
,
w
,
h
)
def
contextMenuEvent
(
self
,
event
):
self
.
fisheyeBackgroundWidget
.
contextMenuEvent
(
event
)
fishui/widgets/PerspectiveBlockWidget.py
View file @
6f1d2d7f
...
...
@@ -96,9 +96,10 @@ class PerspectiveBlockWidget(QWidget):
painter
.
drawPolygon
(
self
.
controlPointMovedPolygon
)
def
mousePressEvent
(
self
,
event
):
self
.
initialMV0
=
self
.
viewModel
.
motion_vector_cp0
self
.
initialMV1
=
self
.
viewModel
.
motion_vector_cp1
self
.
initialMouse
=
event
.
pos
()
if
event
.
button
()
==
Qt
.
LeftButton
:
self
.
initialMV0
=
self
.
viewModel
.
motion_vector_cp0
self
.
initialMV1
=
self
.
viewModel
.
motion_vector_cp1
self
.
initialMouse
=
event
.
pos
()
def
mouseMoveEvent
(
self
,
event
):
if
self
.
initialMouse
is
not
None
:
...
...
@@ -115,6 +116,7 @@ class PerspectiveBlockWidget(QWidget):
self
.
viewModel
.
setMotionVectorCP0
(
motion_vector
)
def
mouseReleaseEvent
(
self
,
event
):
self
.
initialMV0
=
None
self
.
initialMV1
=
None
self
.
initialMouse
=
None
if
event
.
button
()
==
Qt
.
LeftButton
:
self
.
initialMV0
=
None
self
.
initialMV1
=
None
self
.
initialMouse
=
None
fishui/widgets/PropertiesWidget.py
View file @
6f1d2d7f
...
...
@@ -221,7 +221,6 @@ class PropertiesWidget(QWidget):
"Open calibration data (.txt)"
,
"."
,
"Text files (""*.json)"
)[
0
]
try
:
self
.
viewModel
.
setProjection
(
projection
,
calib_file
)
except
(
ValueError
,
FileNotFoundError
):
# Errors if calib_file is invalid
...
...
fishui/widgets/__init__.py
View file @
6f1d2d7f
from
.AspectRatioWidget
import
AspectRatioWidget
from
.FisheyeBackgroundWidget
import
FisheyeBackgroundWidget
from
.FisheyeBlockWidget
import
FisheyeBlockWidget
from
.FisheyeWidget
import
FisheyeWidget
from
.PerspectiveBlockWidget
import
PerspectiveBlockWidget
from
.DistortionVisualizationWidget
import
DistortionVisualizationWidget
from
.PropertiesWidget
import
PropertiesWidget
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment