Skip to content
Snippets Groups Projects
Commit 5c768871 authored by Andrew Maclean's avatar Andrew Maclean
Browse files

Added TexturedSphere, ResizeImage

parent 5675036e
No related branches found
No related tags found
1 merge request!389C++ to python api 08
......@@ -2,7 +2,7 @@
Resize an image using a sinc interpolator. Without command line arguments, the example resizes a synthetic image. An image file can be passed on the command lines. The new dimensions can also be passed as well as an integer specifying the window for sinc interpolator. See vtkImageSincInterpolator for details. A -1 turns off interpolation.
Several window functions are provided. See [this article](https://en.wikipedia.org/wiki/Window_function) for a description og window functions.
Several window functions are provided. See [this article](https://en.wikipedia.org/wiki/Window_function) for a description of window functions.
vtkImageResize maintains the physical size of the image.
......
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkImageReader.h>
#include <vtkImageReader2Factory.h>
#include <vtkNamedColors.h>
......@@ -15,7 +16,6 @@
#include <vtkTransformTextureCoords.h>
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
......@@ -34,12 +34,12 @@ int main(int argc, char* argv[])
}
else
{
translate[0] = 0.0;
translate[0] = 0.25;
}
translate[1] = 0.0;
translate[2] = 0.0;
std::cout << translate[0] << ", " << translate[1] << ", " << translate[2]
<< "\n";
std::cout << "Translate: (" << translate[0] << ", " << translate[1] << ", "
<< translate[2] << ")\n";
// Create a sphere with texture coordinates
vtkNew<vtkTexturedSphereSource> source;
source->SetThetaResolution(100);
......@@ -74,6 +74,12 @@ int main(int argc, char* argv[])
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("TexturedSphere");
renderer->ResetCamera();
// Orient so we are directly above Null Island!
// The location is at (0°N 0°E), i.e., where the
// prime meridian and the equator intersect.
renderer->GetActiveCamera()->Elevation(-90);
vtkNew<vtkRenderWindowInteractor> renWinInteractor;
renWinInteractor->SetRenderWindow(renderWindow);
......
......@@ -492,6 +492,8 @@ This section includes ?vtkUnstructuredGrid?.
[TextureCutSphere](/PythonicAPI/Texture/TextureCutSphere) | Examples of texture thresholding using a boolean combination of two planes to cut nested spheres.
[TexturePlane](/PythonicAPI/Texture/TexturePlane) | Example of texture mapping.
[TextureThreshold](/PythonicAPI/Texture/TextureThreshold) | Demonstrate the use of scalar thresholds to show values of flow density on three planes.
[TexturedSphere](/PythonicAPI/Texture/TexturedSphere) | Texture a sphere.
## Tutorial
......@@ -646,6 +648,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri
[RGBToHSI](/PythonicAPI/Images/RGBToHSI) | Convert RGB to HSI.
[RGBToHSV](/PythonicAPI/Images/RGBToHSV) | Convert RGB to HSV.
[RGBToYIQ](/PythonicAPI/Images/RGBToYIQ) | Convert RGB to YIQ.
[ResizeImage](/PythonicAPI/Images/ResizeImage) | Resize an image using a sinc interpolator.
[VTKSpectrum](/PythonicAPI/ImageProcessing/VTKSpectrum) | The discrete Fourier transform changes an image from the spatial domain into the frequency domain, where each pixel represents a sinusoidal function. This figure shows an image and its power spectrum displayed using a logarithmic transfer function.
## Widgets
......
### Description
Resize an image using a sinc interpolator. Without command line arguments, the example resizes a synthetic image. An image file can be passed on the command lines. The new dimensions can also be passed as well as an integer specifying the window for sinc interpolator. See vtkImageSincInterpolator for details. A -1 turns off interpolation.
Several window functions are provided. See [this article](https://en.wikipedia.org/wiki/Window_function) for a description of window functions.
vtkImageResize maintains the physical size of the image.
!!! note
This example was inspired by a question asked by *Qiang Wang*.
!!! seealso
The paper ["Some windows with very good sidelobe behavior"](http://mwlab.pmo.ac.cn/~lzh/about_work/dspfftpaper/Some_Windows_with_Very_Good_Sidelobe_Behavior.pdf) describes the windows implemented in vtkImageSincInterpolator.
#!/usr/bin/env python3
from pathlib import Path
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkIOImage import vtkImageReader2Factory
from vtkmodules.vtkImagingCore import (
vtkImageResize,
vtkImageSincInterpolator
)
from vtkmodules.vtkImagingSources import vtkImageCanvasSource2D
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleImage
from vtkmodules.vtkRenderingCore import (
vtkImageActor,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor
)
def get_program_parameters():
def to_int_range(x):
try:
x = int(x)
except ValueError:
raise argparse.ArgumentTypeError(f'This value: {x} is not a integer literal')
if x < -1 or x > 10:
raise argparse.ArgumentTypeError(f'The absolute value of {x} must be in the range [-1...10]')
return x
import argparse
description = 'ResizeImage.'
epilogue = '''
Try: -f ../../../src/Testing/Data/Gourds2.jpg -sx 1280 -sy 1024 -w 5
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-f', '--file_name', default=None, help='The image file name to use e.g. Gourds2.jpg.')
parser.add_argument('-sx', default=200, type=int, help='Size in the X-direction')
parser.add_argument('-sy', default=200, type=int, help='Size in the Y-direction')
parser.add_argument('-w', default=-1, type=to_int_range,
help='The sinc interpolator to use. -1 turns off interpolation.')
args = parser.parse_args()
return args.file_name, args.sx, args.sy, args.w
def main():
new_size = [0, 0, 1]
fn, new_size[0], new_size[1], window_function = get_program_parameters()
if fn:
fp = Path(fn)
file_check = True
if not fp.is_file():
print(f'Missing image file: {fp}.')
file_check = False
if not file_check:
return
else:
fp = None
colors = vtkNamedColors()
if fp:
# Read texture file.
reader: vtkImageReader2Factory = vtkImageReader2Factory().CreateImageReader2(str(fp))
reader.file_name = fp
image_data = reader.update().output
else:
draw_color1 = colors.GetColor3ub('Gray')
draw_color2 = colors.GetColor3ub('Aquamarine')
draw_color3 = colors.GetColor3ub('Violet')
canvas_source = vtkImageCanvasSource2D(extent=(0, 100, 0, 100, 0, 0), number_of_scalar_components=3)
canvas_source.draw_color = tuple(draw_color1)
canvas_source.FillBox(0, 100, 0, 100)
canvas_source.draw_color = tuple(draw_color2)
canvas_source.FillTriangle(10, 10, 25, 10, 25, 25)
canvas_source.draw_color = tuple(draw_color3)
canvas_source.FillTube(75, 75, 0, 75, 5.0)
image_data = canvas_source.update().output
interpolator = vtkImageSincInterpolator(use_window_parameter=True)
if 0 <= window_function <= 10:
interpolator.window_function = window_function
resize = vtkImageResize(input_data=image_data, output_dimensions=new_size,
interpolator=interpolator, interpolate=True)
resize.update()
print(f'Original dimensions: {image_data.dimensions}')
print(f'Resized dimensions: {resize.output.dimensions}')
if window_function < 0:
resize.interpolate = False
print(f'Using nearest neighbor interpolation.')
else:
print(f'Using window function : {interpolator.GetWindowFunctionAsString()}')
# Create an image actor to display the image
image_actor = vtkImageActor()
resize >> image_actor.mapper
image_actor.InterpolateOff()
# Setup renderer
renderer = vtkRenderer(background=colors.GetColor3d('Burlywood'))
renderer.AddActor(image_actor)
renderer.ResetCamera()
if fp:
renderer.active_camera.Dolly(5.0)
else:
renderer.active_camera.Dolly(1.0)
renderer.ResetCameraClippingRange()
# Setup render window
render_window = vtkRenderWindow(size=(1280, 1024), window_name='ResizeImage')
render_window.AddRenderer(renderer)
# Setup render window interactor
render_window_interactor = vtkRenderWindowInteractor()
style = vtkInteractorStyleImage()
render_window_interactor.interactor_style = style
render_window_interactor.render_window = render_window
# Render and start interaction
render_window.Render()
render_window_interactor.Initialize()
render_window_interactor.Start()
if __name__ == '__main__':
main()
#!/usr/bin/env python3
from pathlib import Path
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersSources import vtkTexturedSphereSource
from vtkmodules.vtkFiltersTexture import vtkTransformTextureCoords
from vtkmodules.vtkIOImage import vtkImageReader2Factory
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkTexture,
)
def get_program_parameters():
def to_float_range(x):
try:
x = float(x)
except ValueError:
raise argparse.ArgumentTypeError(f'This value: {x} is not a floating-point literal')
if abs(x) < 0.0 or abs(x) > 1.0:
raise argparse.ArgumentTypeError(f'The absolute value of {x} must be in the range [0...1]')
return x
import argparse
description = 'TexturedSphere.'
epilogue = '''
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('file_name', help='The texture(.png/.ppm) file name to use e.g. earth.ppm.')
parser.add_argument('-t', '--translate', type=to_float_range, default=0.25, help='Translation for the x-direction.')
args = parser.parse_args()
return args.file_name, args.translate
def main():
translate = [0.0] * 3
fn, translate[0] = get_program_parameters()
fp = Path(fn)
file_check = True
if not fp.is_file():
print(f'Missing image file: {fp}.')
file_check = False
elif not fp.suffix.lower() in ['.ppm', '.png']:
file_check = False
print(f'Bad extension: only .ppm or .png extensions are allowed.')
if not file_check:
return
print(f'Translate: ({fmt_floats(translate)})')
colors = vtkNamedColors()
# Create a sphere with texture coordinates
source = vtkTexturedSphereSource(theta_resolution=100, phi_resolution=100)
# Read texture file.
reader: vtkImageReader2Factory = vtkImageReader2Factory().CreateImageReader2(str(fp))
reader.file_name = fp
# Create the texture.
texture = vtkTexture()
reader >> texture
transform_texture = vtkTransformTextureCoords(position=translate)
mapper = vtkPolyDataMapper()
source >> transform_texture >> mapper
actor = vtkActor(mapper=mapper)
actor.SetTexture(texture)
renderer = vtkRenderer(background=colors.GetColor3d('Black'))
renderer.AddActor(actor)
render_window = vtkRenderWindow(window_name='TexturedSphere')
render_window.AddRenderer(renderer)
renderer.ResetCamera()
# Orient so we are directly above Null Island!
# The location is at (0°N 0°E), i.e., where the
# prime meridian and the equator intersect.
renderer.active_camera.Elevation(-90)
ren_win_interactor = vtkRenderWindowInteractor()
ren_win_interactor.render_window = render_window
render_window.Render()
ren_win_interactor.Start()
def fmt_floats(v, w=0, d=6, pt='g'):
"""
Pretty print a list or tuple of floats.
:param v: The list or tuple of floats.
:param w: Total width of the field.
:param d: The number of decimal places.
:param pt: The presentation type, 'f', 'g' or 'e'.
:return: A string.
"""
pt = pt.lower()
if pt not in ['f', 'g', 'e']:
pt = 'f'
return ', '.join([f'{element:{w}.{d}{pt}}' for element in v])
if __name__ == '__main__':
main()
src/Testing/Baseline/Cxx/Texture/TestTexturedSphere.png

130 B | W: | H:

src/Testing/Baseline/Cxx/Texture/TestTexturedSphere.png

130 B | W: | H:

src/Testing/Baseline/Cxx/Texture/TestTexturedSphere.png
src/Testing/Baseline/Cxx/Texture/TestTexturedSphere.png
src/Testing/Baseline/Cxx/Texture/TestTexturedSphere.png
src/Testing/Baseline/Cxx/Texture/TestTexturedSphere.png
  • 2-up
  • Swipe
  • Onion skin
src/Testing/Baseline/PythonicAPI/Images/TestResizeImage.png

131 B

src/Testing/Baseline/PythonicAPI/Texture/TestTexturedSphere.png

130 B

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment