Module shapes¶
This module defines a class for drawing shapes that define an area in your
image. The drawing is interactive using mouse- and keyboard buttons.
For each defined area the module maputils
calculates the sum of the intensities,
the area and some other properties of the data. The shapes are one of
polygon, ellipse, circle, rectangle or spline.
The strength of this module is that it duplicates a shape to other selected images using transformations to world coordinates. This enables one to compare e.g. flux in two images with different WCS systems. It works with spatial maps and maps with mixed axes (e.g. position-velocity maps) and maps with linear axes. The order of the two axes in a map can be swapped.
- class kapteyn.shapes.Shapecollection(images, ifigure, wcs=True, inputfilename=None, inputwcs=False, gipsy=False)[source]¶
Administration class for a collection of shapes. The figure
- Parameters:
images (A list of objects from class
maputils.Annotatedimage
) – In each image a shape can be drawn using mouse- and keyboard buttons. This shape is duplicated either in pixel coordinates or world coordinates in the other images of the list with images. These images have two attributes that are relevant for this module. These are fluxfie to define how the flux should be calculated using fixed variables s for the sum of the intensities of the pixels in an area and a which represents the area.ifigure (Matplotlib
Figure
object) – The Matplotlib figure where the images are.wcs (Boolean) – The default is True which implies that in case of multiple images shapes propagate through world coordinates. If you have images with the same size and WCS, then set wcs=False to duplicate shapes in pixel coordinates which is much faster.
inputfilename (String) – Name of file on disk which stores shape information. The objects are read from this file and plotted on all the images in the image list. The coordinates in the file can be either pixel- or world coordinates. You should specify that with parameter inputwcs
inputwcs (Boolean) – Set the shape mode for shapes from file to either pixels coordinates (inputwcs=False) or to world coordinates (inputwcs=True).
This shape interactor reacts to the following keyboard and mouse buttons:
mouse - left : Drag a polygon point to a new position or change the radius of a circle or change the minor axis of an ellipse or change the major axis and position angle of an ellipse mouse - middle: Select an existing object in any frame key - a : Add a point to a polygon or spline key - c : Copy current object at mouse cursor key - d : Delete a point in a polygon or spline key - e : Erase active object and associated objects in other images key - i : Insert a point in a polygon or spline key - n : Start with a new object key - u : Toggle markers. Usually for a hardcopy one does not want to show the markers of a shape. key - w : Write object data in current image to file on disk key - r : Read objects from file for current image key - [ : Next active object in current shape selection key - ] : Previous active object in current shape selection Interactive navigation defined by canvas Amongst others: key - f : Toggle fullscreen key - g : Toggle grid Gui buttons: 'Quit' : Abort program 'plot result' : Plot calculated flux as function of shape and image 'Save result' : Save flux information to disk The file names are generated and contain date and time stamp (e.g flux_24042010_212029.dat) 'Pol.' : Select shape polygon. Start with key 'n' for new polygon. Add new points with key 'a'. 'Ell.' : Select shape ellipse. Start with key 'n' for new ellipse. With left mouse button Drag major axis to change size and rotation or, using a point near the center, drag entire ellipse to a new position. 'Cir.:' : Select shape circle. Start with key 'n' for new circle. The radius can be changed by dragging an arbitrary point on the border to a new position. 'Rec.' : Select shape rectangle. Start with key 'n' for new rectangle. Drag any of the four edges to resize the rectangle. 'Spl.' : Like the polygon but the points between two knots follow a spline curve.
- Notes:
All shapes are derived from a polygon class. There is one method that generates coordinates for all shapes and
kapteyn.maputils.getflux()
uses the same routine to calculate whether a pixel in an enclosing box is within or outside the shape. For circles and ellipses the number of polygon points is 360 and this slows down the calculation significantly. Methods which assume a perfect circle or ellipse can handle the inside/outside problem much faster, but note that due to different WCS’s, ellipses and circles don’t keep their shape in other images. So in fact only a polygon is the common shape. A spline is a polygon with an artificially increased number of points.- Example:
fig = plt.figure(figsize=(12,10)) frame1 = fig.add_axes([0.07,0.1,0.35, 0.8]) frame2 = fig.add_axes([0.5,0.1,0.43, 0.8]) im1 = f1.Annotatedimage(frame1) im2 = f2.Annotatedimage(frame2) im1.Image(); im1.Graticule() im2.Image(); im2.Graticule() im1.interact_imagecolors(); im1.interact_toolbarinfo() im2.interact_imagecolors(); im2.interact_toolbarinfo() im1.plot(); im2.plot() im1.fluxfie = lambda s, a: s/a im2.fluxfie = lambda s, a: s/a im1.pixelstep = 0.5; im2.pixelstep = 0.5 images = [im1, im2] shapes = shapes.Shapecollection(images, fig, wcs=True, inputwcs=True)
Utility functions¶
- kapteyn.shapes.ellipsesamples(xc, yc, major, minor, pa, n)[source]¶
Get sample positions on ellipse Algorithm from ‘Mathematical Elements for Computer Graphics’ by Rogers and Adams, section about ‘Parametric Representation of an Ellipse’ Many methods which calculate sample positions on an ellipse suffer from a reasonable sampling near the positions where the curvature of an ellipse is large. The method we use, finds more sample points near the end points of an ellipse where the curvature is large while the increment between sample points along the sides of the ellipse where the curvature is not large, is small
For an ellipse centered at (0,0), semimajor axis a and semiminor axis b the parametric representation is given by:
x = a * cos(th) y = b * sin(th)
‘th’ is the parameter and it represents the angle between 0 and 2*pi One can derive a recursive relation:
x_i+1 = x_i cos(dth) - (a/b) y_i sin(dth) y_i+1 = (b/a) x_i sin(dth) + y_i cos(dth)
dth is a step size in the angle th. It is equal to 2*pi/(n-1) n-1 is the required number or unique points on the ellipse and therefore an input parameter. The routine returns a result which is empty when either a or b is zero.
The shift of the origin and the rotation of the ellipse can be combined into one matrix:
| cos(a) sin (a) 0 | | 1 0 0 | T = |-sin(a) cos (a) 0 | | 0 1 0 | | 0 0 1 | | xc yc 1 |
Finally the result is computed with:
X, Y, dummy = (x, y, 1).T
The result is a polygon which describes the maximum inscribed area for the given ellipse parameters (Smith, L.B., “Drawing Ellipses, Hyperbolas, or Parabolas With a Fixed Number of Points and Maximum Inscribed Area,” Comp. J., Vol. 14, pp. 81-86, 1969
- Parameters:
- Notes:
The ‘classical’ method involves the calculation of many cosine and sine functions. This method avoids that by using a method which calculates a new sample based on the information of a previous sample. However, we didn’t find a way to do this properly using NumPy. The classic method is very suitable to do implement in NumPy and is therefore faster than the algorithm here. But the sampling is better and we can do with less samples to get the same result.