def test_skybox(): # Test scene created without skybox scene = window.Scene() npt.assert_warns(UserWarning, scene.skybox) # Test removing automatically shown skybox test_tex = Texture() test_tex.CubeMapOn() checker_arr = np.array([[1, 0], [0, 1]], dtype=np.uint8) * 255 for i in range(6): vtk_img = ImageData() vtk_img.SetDimensions(2, 2, 1) img_arr = np.zeros((2, 2, 3), dtype=np.uint8) img_arr[:, :, i // 2] = checker_arr vtk_arr = numpy_support.numpy_to_vtk(img_arr.reshape((-1, 3), order='F')) vtk_arr.SetName('Image') img_point_data = vtk_img.GetPointData() img_point_data.AddArray(vtk_arr) img_point_data.SetActiveScalars('Image') test_tex.SetInputDataObject(i, vtk_img) scene = window.Scene(skybox=test_tex) report = window.analyze_scene(scene) npt.assert_equal(report.actors, 1) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [0, 0, 255]) npt.assert_array_equal(ss[75, 225, :], [0, 0, 0]) scene.yaw(90) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [255, 0, 0]) npt.assert_array_equal(ss[75, 225, :], [0, 0, 0]) scene.pitch(90) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [0, 0, 0]) npt.assert_array_equal(ss[75, 225, :], [0, 255, 0]) # Test skybox is not added twice scene.skybox() report = window.analyze_scene(scene) npt.assert_equal(report.actors, 1) # Test make skybox invisible scene.skybox(visible=False) report = window.analyze_scene(scene) npt.assert_equal(report.actors, 0) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [0, 0, 0]) scene.yaw(90) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [0, 0, 0]) scene.pitch(90) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 225, :], [0, 0, 0]) # Test make skybox visible again scene.skybox(visible=True) report = window.analyze_scene(scene) npt.assert_equal(report.actors, 1)
def numpy_to_vtk_image_data(array, spacing=(1.0, 1.0, 1.0), origin=(0.0, 0.0, 0.0), deep=True): """Convert numpy array to a vtk image data. Parameters ---------- array : ndarray pixel coordinate and colors values. spacing : (float, float, float) (optional) sets the size of voxel (unit of space in each direction x,y,z) origin : (float, float, float) (optional) sets the origin at the given point deep : bool (optional) decides the type of copy(ie. deep or shallow) Returns ------- vtk_image : vtkImageData """ if array.ndim not in [2, 3]: raise IOError("only 2D (L, RGB, RGBA) or 3D image available") vtk_image = ImageData() depth = 1 if array.ndim == 2 else array.shape[2] vtk_image.SetDimensions(array.shape[1], array.shape[0], depth) vtk_image.SetExtent(0, array.shape[1] - 1, 0, array.shape[0] - 1, 0, 0) vtk_image.SetSpacing(spacing) vtk_image.SetOrigin(origin) temp_arr = np.flipud(array) temp_arr = temp_arr.reshape(array.shape[1] * array.shape[0], depth) temp_arr = np.ascontiguousarray(temp_arr, dtype=array.dtype) vtk_array_type = numpy_support.get_vtk_array_type(array.dtype) uchar_array = numpy_support.numpy_to_vtk(temp_arr, deep=deep, array_type=vtk_array_type) vtk_image.GetPointData().SetScalars(uchar_array) return vtk_image
def rgb_to_vtk(data): """RGB or RGBA images to VTK arrays. Parameters ---------- data : ndarray Shape can be (X, Y, 3) or (X, Y, 4) Returns ------- vtkImageData """ grid = ImageData() grid.SetDimensions(data.shape[1], data.shape[0], 1) nd = data.shape[-1] vtkarr = numpy_support.numpy_to_vtk( np.flip(data.swapaxes(0, 1), axis=1).reshape((-1, nd), order='F')) vtkarr.SetName('Image') grid.GetPointData().AddArray(vtkarr) grid.GetPointData().SetActiveScalars('Image') grid.GetPointData().Update() return grid
def load_image(filename, as_vtktype=False, use_pillow=True): """Load an image. Parameters ---------- filename: str should be png, bmp, jpeg or jpg files as_vtktype: bool, optional if True, return vtk output otherwise an ndarray. Default False. use_pillow: bool, optional Use pillow python library to load the files. Default True Returns ------- image: ndarray or vtk output desired image array """ is_url = filename.lower().startswith('http://') \ or filename.lower().startswith('https://') if is_url: image_name = os.path.basename(filename) if len(image_name.split('.')) < 2: raise IOError(f'{filename} is not a valid image URL') urlretrieve(filename, image_name) filename = image_name if use_pillow: with Image.open(filename) as pil_image: if pil_image.mode in ['RGBA', 'RGB', 'L']: image = np.asarray(pil_image) elif pil_image.mode.startswith('I;16'): raw = pil_image.tobytes('raw', pil_image.mode) dtype = '>u2' if pil_image.mode.endswith('B') else '<u2' image = np.frombuffer(raw, dtype=dtype) image.reshape(pil_image.size[::-1]).astype('=u2') else: try: image = pil_image.convert('RGBA') except ValueError: raise RuntimeError('Unknown image mode {}'.format( pil_image.mode)) image = np.asarray(pil_image) image = np.flipud(image) if as_vtktype: if image.ndim not in [2, 3]: raise IOError("only 2D (L, RGB, RGBA) or 3D image available") vtk_image = ImageData() depth = 1 if image.ndim == 2 else image.shape[2] # width, height vtk_image.SetDimensions(image.shape[1], image.shape[0], depth) vtk_image.SetExtent(0, image.shape[1] - 1, 0, image.shape[0] - 1, 0, 0) vtk_image.SetSpacing(1.0, 1.0, 1.0) vtk_image.SetOrigin(0.0, 0.0, 0.0) image = image.reshape(image.shape[1] * image.shape[0], depth) image = np.ascontiguousarray(image, dtype=image.dtype) vtk_array_type = numpy_support.get_vtk_array_type(image.dtype) uchar_array = numpy_support.numpy_to_vtk(image, deep=True, array_type=vtk_array_type) vtk_image.GetPointData().SetScalars(uchar_array) image = vtk_image if is_url: os.remove(filename) return image d_reader = { ".png": PNGReader, ".bmp": BMPReader, ".jpeg": JPEGReader, ".jpg": JPEGReader, ".tiff": TIFFReader, ".tif": TIFFReader } extension = os.path.splitext(os.path.basename(filename).lower())[1] if extension.lower() not in d_reader.keys(): raise IOError( "Impossible to read the file {0}: Unknown extension {1}".format( filename, extension)) reader = d_reader.get(extension)() reader.SetFileName(filename) reader.Update() reader.GetOutput().GetPointData().GetArray(0).SetName("original") if not as_vtktype: w, h, _ = reader.GetOutput().GetDimensions() vtk_array = reader.GetOutput().GetPointData().GetScalars() components = vtk_array.GetNumberOfComponents() image = numpy_support.vtk_to_numpy(vtk_array).reshape(h, w, components) if is_url: os.remove(filename) return reader.GetOutput() if as_vtktype else image
def save_image(arr, filename, compression_quality=75, compression_type='deflation', use_pillow=True): """Save a 2d or 3d image. Expect an image with the following shape: (H, W) or (H, W, 1) or (H, W, 3) or (H, W, 4). Parameters ---------- arr : ndarray array to save filename : string should be png, bmp, jpeg or jpg files compression_quality : int, optional compression_quality for jpeg data. 0 = Low quality, 100 = High quality compression_type : str, optional compression type for tiff file select between: None, lzw, deflation (default) use_pillow : bool, optional Use imageio python library to save the files. """ if arr.ndim > 3: raise IOError("Image Dimensions should be <=3") d_writer = { ".png": PNGWriter, ".bmp": BMPWriter, ".jpeg": JPEGWriter, ".jpg": JPEGWriter, ".tiff": TIFFWriter, ".tif": TIFFWriter, } extension = os.path.splitext(os.path.basename(filename).lower())[1] if extension.lower() not in d_writer.keys(): raise IOError( "Impossible to save the file {0}: Unknown extension {1}".format( filename, extension)) if use_pillow: arr = np.flipud(arr) im = Image.fromarray(arr) im.save(filename, quality=compression_quality) return if arr.ndim == 2: arr = arr[..., None] shape = arr.shape if extension.lower() in [ '.png', ]: arr = arr.astype(np.uint8) arr = arr.reshape((shape[1] * shape[0], shape[2])) arr = np.ascontiguousarray(arr, dtype=arr.dtype) vtk_array_type = numpy_support.get_vtk_array_type(arr.dtype) vtk_array = numpy_support.numpy_to_vtk(num_array=arr, deep=True, array_type=vtk_array_type) # Todo, look the following link for managing png 16bit # https://stackoverflow.com/questions/15667947/vtkpngwriter-printing-out-black-images vtk_data = ImageData() vtk_data.SetDimensions(shape[1], shape[0], shape[2]) vtk_data.SetExtent(0, shape[1] - 1, 0, shape[0] - 1, 0, 0) vtk_data.SetSpacing(1.0, 1.0, 1.0) vtk_data.SetOrigin(0.0, 0.0, 0.0) vtk_data.GetPointData().SetScalars(vtk_array) writer = d_writer.get(extension)() writer.SetFileName(filename) writer.SetInputData(vtk_data) if extension.lower() in [".jpg", ".jpeg"]: writer.ProgressiveOn() writer.SetQuality(compression_quality) if extension.lower() in [".tif", ".tiff"]: compression_type = compression_type or 'nocompression' l_compression = ['nocompression', 'packbits', 'jpeg', 'deflate', 'lzw'] if compression_type.lower() in l_compression: comp_id = l_compression.index(compression_type.lower()) writer.SetCompression(comp_id) else: writer.SetCompressionToDeflate() writer.Write()
def test_scene(): scene = window.Scene() # Scene size test npt.assert_equal(scene.size(), (0, 0)) # Color background test # Background color for scene (1, 0.5, 0). 0.001 added here to remove # numerical errors when moving from float to int values bg_float = (1, 0.501, 0) # That will come in the image in the 0-255 uint scale bg_color = tuple((np.round(255 * np.array(bg_float))).astype('uint8')) scene.background(bg_float) arr = window.snapshot(scene) report = window.analyze_snapshot(arr, bg_color=bg_color, colors=[bg_color, (0, 127, 0)]) npt.assert_equal(report.objects, 0) npt.assert_equal(report.colors_found, [True, False]) # Add actor to scene to test the remove actor function by analyzing a # snapshot axes = actor.axes() scene.add(axes) arr = window.snapshot(scene) report = window.analyze_snapshot(arr, bg_color) npt.assert_equal(report.objects, 1) # Test remove actor function by analyzing a snapshot scene.rm(axes) arr = window.snapshot(scene) report = window.analyze_snapshot(arr, bg_color) npt.assert_equal(report.objects, 0) # Add actor to scene to test the remove all actors function by analyzing a # snapshot scene.add(axes) arr = window.snapshot(scene) report = window.analyze_snapshot(arr, bg_color) npt.assert_equal(report.objects, 1) # Test remove all actors function by analyzing a snapshot scene.rm_all() arr = window.snapshot(scene) report = window.analyze_snapshot(arr, bg_color) npt.assert_equal(report.objects, 0) # Test change background color from scene by analyzing the scene ren2 = window.Scene(bg_float) ren2.background((0, 0, 0.)) report = window.analyze_scene(ren2) npt.assert_equal(report.bg_color, (0, 0, 0)) # Add actor to scene to test the remove actor function by analyzing the # scene ren2.add(axes) report = window.analyze_scene(ren2) npt.assert_equal(report.actors, 1) # Test remove actor function by analyzing the scene ren2.rm(axes) report = window.analyze_scene(ren2) npt.assert_equal(report.actors, 0) # Test camera information retrieving with captured_output() as (out, err): scene.camera_info() npt.assert_equal(out.getvalue().strip(), '# Active Camera\n ' 'Position (0.00, 0.00, 1.00)\n ' 'Focal Point (0.00, 0.00, 0.00)\n ' 'View Up (0.00, 1.00, 0.00)') npt.assert_equal(err.getvalue().strip(), '') # Test skybox scene = window.Scene() npt.assert_equal(scene.GetUseImageBasedLighting(), False) npt.assert_equal(scene.GetAutomaticLightCreation(), 1) npt.assert_equal(scene.GetSphericalHarmonics(), None) npt.assert_equal(scene.GetEnvironmentTexture(), None) test_tex = Texture() scene = window.Scene(skybox=test_tex) npt.assert_equal(scene.GetUseImageBasedLighting(), True) npt.assert_equal(scene.GetAutomaticLightCreation(), 0) npt.assert_equal(scene.GetSphericalHarmonics(), None) npt.assert_equal(scene.GetEnvironmentTexture(), test_tex) # Test automatically shown skybox test_tex = Texture() test_tex.CubeMapOn() checker_arr = np.array([[1, 0], [0, 1]], dtype=np.uint8) * 255 for i in range(6): vtk_img = ImageData() vtk_img.SetDimensions(2, 2, 1) img_arr = np.zeros((2, 2, 3), dtype=np.uint8) img_arr[:, :, i // 2] = checker_arr vtk_arr = numpy_support.numpy_to_vtk(img_arr.reshape((-1, 3), order='F')) vtk_arr.SetName('Image') img_point_data = vtk_img.GetPointData() img_point_data.AddArray(vtk_arr) img_point_data.SetActiveScalars('Image') test_tex.SetInputDataObject(i, vtk_img) scene = window.Scene(skybox=test_tex) report = window.analyze_scene(scene) npt.assert_equal(report.actors, 1) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [0, 0, 255]) npt.assert_array_equal(ss[75, 225, :], [0, 0, 0]) scene.yaw(90) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [255, 0, 0]) npt.assert_array_equal(ss[75, 225, :], [0, 0, 0]) scene.pitch(90) ss = window.snapshot(scene) npt.assert_array_equal(ss[75, 75, :], [0, 0, 0]) npt.assert_array_equal(ss[75, 225, :], [0, 255, 0])