Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error when visualising 2D image #439

Merged
merged 17 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Enhancements:
- Adds methods to CILviewer and CILviewer2D #425

Bugfix:
- Fix error when visualising 2D images #439
- Differentiate 3D and 2D images in the converter `numpy2vtkImage` #437
- Edit slider min value #420
- Fix extent error when user clicks in the viewer to create a box by clicking outside of the image #425
Expand Down
6 changes: 3 additions & 3 deletions Wrappers/Python/ccpi/viewer/iviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class SingleViewerCenterWidget(QtWidgets.QMainWindow):
def __init__(self, parent=None, viewer=viewer2D):
QtWidgets.QMainWindow.__init__(self, parent)

self.frame = QCILViewerWidget(viewer=viewer, shape=(600, 600))
self.frame = QCILViewerWidget(parent, viewer=viewer, shape=(600, 600))

if viewer == viewer3D:
self.frame.viewer.setVolumeRenderOpacityMethod('scalar')
Expand All @@ -41,8 +41,8 @@ def __init__(self, parent=None, viewer1='2D', viewer2='2D'):
elif viewer == '3D':
styles.append(vlink.Linked3DInteractorStyle)
viewers.append(eval('viewer' + viewer))
self.frame1 = QCILViewerWidget(viewer=viewers[0], shape=(600, 600), interactorStyle=styles[0])
self.frame2 = QCILViewerWidget(viewer=viewers[1], shape=(600, 600), interactorStyle=styles[1])
self.frame1 = QCILViewerWidget(parent, viewer=viewers[0], shape=(600, 600), interactorStyle=styles[0])
self.frame2 = QCILViewerWidget(parent, viewer=viewers[1], shape=(600, 600), interactorStyle=styles[1])

# Initially link viewers
self.linkedViewersSetup()
Expand Down
2 changes: 1 addition & 1 deletion Wrappers/Python/ccpi/viewer/standalone_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@ def main():


if __name__ == '__main__':
main()
main()
2 changes: 0 additions & 2 deletions Wrappers/Python/ccpi/viewer/ui/main_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import sys
from functools import partial
from pathlib import Path

import ccpi.viewer.viewerLinker as vlink
import vtk
from ccpi.viewer import CILViewer2D, CILViewer
Expand Down Expand Up @@ -381,7 +380,6 @@ def updateViewerCoordsDockWidgetWithCoords(self, reader=None):
The reader used to read the image. This contains some extra info about the
original image file.
'''

viewer = self.viewer_coords_dock.viewers[0]

if not isinstance(viewer, (CILViewer2D, CILViewer)):
Expand Down
35 changes: 23 additions & 12 deletions Wrappers/Python/ccpi/viewer/utils/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,31 @@ class Converter(object):

@staticmethod
def numpy2vtkImage(nparray, spacing=(1., 1., 1.), origin=(0, 0, 0), deep=0, output=None):
"""The method converts a numpy array to a vtk image.
The vtk extent is set and needs to differentiate between 3D and 2D images."""
"""
The method converts a numpy array to a vtk image.

Raises an error if the dimension of the image is not 2 or 3.
The array is flattened in the correct order, either fortran or C.
The vtk extent is set and needs to differentiate between 3D and 2D images.
Creates a vtkImageData if `output` is None, otherwise uses the provided empty output.
Adds the vtkarray to the image's point data. If an array is already present, it removes it."""

shape = numpy.shape(nparray)
if (nparray.flags["FNC"]):
num_dims = len(shape)
if num_dims not in [2, 3]:
raise ValueError("Only 2D or 3D numpy arrays are supported.")

if nparray.flags["FNC"]:
order = "F"
i = 0
k = len(shape) - 1
i, k = 0, num_dims - 1
else:
order = "C"
i = len(shape) - 1
k = 0
i, k = num_dims - 1, 0

nparray = nparray.ravel(order)
vtkarray = numpy_support.numpy_to_vtk(num_array=nparray,
deep=deep,
array_type=numpy_support.get_vtk_array_type(nparray.dtype))
vtkarray.SetName('vtkarray')

if output is None:
img_data = vtk.vtkImageData()
Expand All @@ -117,12 +124,16 @@ def numpy2vtkImage(nparray, spacing=(1., 1., 1.), origin=(0, 0, 0), deep=0, outp
else:
img_data = output

img_data.GetPointData().AddArray(vtkarray)
if len(shape) == 3:
point_data = img_data.GetPointData()
while point_data.GetNumberOfArrays() > 0:
point_data.RemoveArray(0)
vtkarray.SetName('ImageScalars')
point_data.AddArray(vtkarray)
img_data.GetPointData().SetScalars(vtkarray)
if num_dims == 3:
img_data.SetExtent(0, shape[i] - 1, 0, shape[1] - 1, 0, shape[k] - 1)
elif len(shape) == 2:
elif num_dims == 2:
img_data.SetExtent(0, shape[i] - 1, 0, shape[k] - 1, 0, 0)
img_data.GetPointData().SetActiveScalars('vtkarray')
img_data.SetOrigin(origin)
img_data.SetSpacing(spacing)

Expand Down
14 changes: 14 additions & 0 deletions Wrappers/Python/examples/2Dimage_reading.py
DanicaSTFC marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from ccpi.viewer.CILViewer2D import CILViewer2D
import vtk

# This example imports a 2D tiff image and tests the 2D viewer
DATASET_TO_READ = [path] # insert path here
if DATASET_TO_READ is not None:
reader = vtk.vtkTIFFReader()
reader.SetFileName(DATASET_TO_READ)
reader.Update()

v = CILViewer2D()
print(reader.GetOutput())
v.setInputData(reader.GetOutput())
v.startRenderLoop()
3 changes: 2 additions & 1 deletion Wrappers/Python/examples/FourDockableLinkedViewerWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def __init__(self, parent=None, reader=None):
#self.resize(800,600)

# create the dockable widgets with the viewer inside
self.v00 = QCILDockableWidget(viewer=viewer2D,
self.v00 = QCILDockableWidget(parent,
viewer=viewer2D,
shape=(600, 600),
title="X",
interactorStyle=vlink.Linked2DInteractorStyle)
Expand Down
2 changes: 1 addition & 1 deletion Wrappers/Python/examples/SingleViewerCentralWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class SingleViewerCenterWidget(QtWidgets.QMainWindow):
def __init__(self, parent=None, viewer=viewer2D):
QtWidgets.QMainWindow.__init__(self, parent)

self.frame = QCILViewerWidget(viewer=viewer, shape=(600, 600))
self.frame = QCILViewerWidget(parent, viewer=viewer, shape=(600, 600))

head = example_data.HEAD.get()

Expand Down
2 changes: 1 addition & 1 deletion Wrappers/Python/examples/SingleViewerCentralWidget2.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class SingleViewerCenterWidget(QtWidgets.QMainWindow):
def __init__(self, parent=None, viewer=viewer2D):
QtWidgets.QMainWindow.__init__(self, parent)
self.setGeometry(450, 250, 1000, 1000)
self.frame = QCILViewerWidget(viewer=viewer, shape=(2000, 2000))
self.frame = QCILViewerWidget(parent, viewer=viewer, shape=(2000, 2000))

head = example_data.HEAD.get()

Expand Down
10 changes: 8 additions & 2 deletions Wrappers/Python/examples/TwoLinkedViewersCentralWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
#self.resize(800,600)

self.frame1 = QCILViewerWidget(viewer=viewer2D, shape=(600, 600), interactorStyle=vlink.Linked2DInteractorStyle)
self.frame2 = QCILViewerWidget(viewer=viewer3D, shape=(600, 600), interactorStyle=vlink.Linked3DInteractorStyle)
self.frame1 = QCILViewerWidget(parent,
viewer=viewer2D,
shape=(600, 600),
interactorStyle=vlink.Linked2DInteractorStyle)
self.frame2 = QCILViewerWidget(parent,
viewer=viewer3D,
shape=(600, 600),
interactorStyle=vlink.Linked3DInteractorStyle)

head = example_data.HEAD.get()

Expand Down
2 changes: 1 addition & 1 deletion Wrappers/Python/examples/opacity_in_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class OpacityViewerWidget(SingleViewerCenterWidget):
def __init__(self, parent=None, viewer=viewer3D):
SingleViewerCenterWidget.__init__(self, parent)

self.frame = QCILViewerWidget(viewer=viewer, shape=(600, 600))
self.frame = QCILViewerWidget(parent, viewer=viewer, shape=(600, 600))

self.setCentralWidget(self.frame)

Expand Down
Loading