dip::MakeRegionsConvex2D(), which works for both labelled and binary images.
Perimeter() (as an alias for
as member functions to
dip::MomentAccumulator has a new method
PlainSecondOrder(), which returns the plain old second
order central moments, compared to the moment of inertia tensor returned by
dip::Image::Mask(), to apply a mask to an image.
dip::PixelSize::Reverse() to reverse the elements of an array.
dip::Image::ReverseDimensions(), which permutes dimensions to reverse their order.
dip::Label has a new string argument,
mode, which can be set to
"largest" to return a labeled
image that only contains the largest connected component in the input image.
dip::PixelSize::SameUnits() to simplify finding the right units for measurement results.
Added operators to multiply and divide two
dip::Vertex objects. They apply an element-wise product.
dip::ChainCode::Length has an optional parameter to include the image boundary pixels in the measurement.
"Perimeter" feature can be configured: setting the
"include boundary pixels" parameter to a non-zero
value causes the perimeter measurement to include pixels at the image boundary.
dip::BackgroundThreshold() have a new parameter
sigma, which defaults to
4 to preserve the old behavior.
The deterministic initialization for
dip::GaussianMixtureModel() is more robust, making the
initial Gaussians overlap instead of setting their sigma to 1.
dip::ConvexHull no longer holds a
dip::Polygon as a private member, instead it uses
as a base class. This makes all of the
dip::Polygon functionality directly available on the convex
dip::ConvexHull::Polygon() now just returns a base class reference.
dip::Units (and by extension
dip::PixelSize) now uses the Greek letter
μ (U+03BC), instead of the legacy symbol µ (U+00B5) for micron (when DIPlib is built with Unicode
enabled). Both symbols are recognized when parsing a string, but the strings generated are now different.
dip::BackgroundThreshold() now determines the half width at half height with sub-sample precision,
and takes the smoothing of the histogram into account, such that the amount of smoothing should have
little influence in the computed threshold.
The “Mu” and “GreyMu” features no longer use the pixel sizes if the units for different image dimensions differ. No uses of the tensor make sense if the units for the various dimensions don’t match, in this case it is more useful to report the tensor in pixel units.
dip::DrawPolygon2D(), when drawing filled polygons, would skip the bottom row in the polygon. The
algorithm is a bit more sophisticated now to properly handle these bottom rows. This also takes care
of some rounding errors that could be seen for polygons with very short edges.
dip::ResampleAt with a
map input argument and using
"cubic" interpolation could overflow,
yielding unsightly artifacts. See issue #107.
Better error messages for some forms of
dip::ImageDisplay() didn’t pay attention to the
dim2 parameters if the image was 2D.
dip::DefineROI() was incorrect if the input and output images were the same object.
dip::GaussianMixtureModel() could produce NaN for amplitude, those components now have a zero amplitude.
The “SolidArea” feature didn’t take the pixel size into account. This also caused the “Roundness” feature to report wrong values. The “SurfaceArea” feature didn’t properly scale the result by the pixel size. Several composed features (computed from other features) didn’t produce correct values for anisotropic pixels (“P2A”, “Roundness”, and “PodczeckShapes”).
dip::div_round() was incorrect, which caused
dip::DirectedPathOpening() to not use certain
dip::DirectionalStatisticsAccumulator::StandardDeviation() returned NaN if the mean was identical to zero.
threshold(.., 'triangle')now accepts a parameter to control how much smoothing to apply.
(See also changes to DIPlib.)
None, but see bugfixes to DIPlib.
Perimeter() (as an alias for
as methods to
dip.ChainCode now both have
meaning that they can be treated like lists or other iterables. Previously, the values of
had to be extracted by conversion to a NumPy array, and the values of
dip.ChainCode by copying to
a list when accessing its
The structure returned by
dip.Moments() has a new component
plainSecondOrder, which contains
the plain old second order central moments, compared to the moment of inertia tensor contained
ReverseDimensions() as methods to
dip.ReverseDimensions(), which reverses the indexing order for images for the remainder of the
session. Has repercussion on how the
dip.Image buffer is exposed, buffer protocol objects are
converted to a
dip.Image, files are read and written, and how DIPviewer displays images.
It is intended to make indexing into a
dip.Image match the indexing into the corresponding
NumPy array, which should make it easier to mix calls to DIPlib and scikit-image in the same
program. Note that this also causes positive angles to be counter-clockwise instead of clockwise.
@= operators for
dip.Image objects. These apply matrix multiplication if both
operands are non-scalar images. That is, the vector or matrix at each pixel is multiplied by the
vector or matrix at the corresponding pixel in the other operand. The two image’s tensor dimensions
must be compatible. If one of the operands is a scalar image, the normal element-wise multiplication
is applied. One of the operands can be a single pixel (a list of numbers).
dip.MeasurementTool.Configure to allow measurement features to be configured.
ApproximatelyEquals() as methods to
Operators overloaded for
dip.Image objects can use lists of numbers as a second argument, which
is interpreted as a 0D tensor image (column vector). This makes
img / img possible.
When PyDIPjavaio fails to load, the error is no longer displayed immediately. Instead, it is
dip.ImageRead() fails. The error message is also a bit more helpful.
See issue #106.
__repr__ string for many classes has changed to be more consistent and informative.
*= operators have changed meaning, they now always apply element-wise multiplication,
their previous behavior is now obtained with the new
NOTE! This breaks backwards compatibility. To keep old code working that depends on image matrix
multiplications, you can do
import diplib as dip dip.Image.__mul__ = dip.Image.__matmul__ dip.Image.__rmul__ = dip.Image.__rmatmul__ dip.Image.__imul__ = dip.Image.__imatmul__
But we recommend instead that you update the code to use the right operators.
(See also changes to DIPlib.)
__len__() now properly returns 0 for an empty (raw) image. This makes
if img fail for a raw image.
Fixed a few issues with indexing into image, allowing using a list of coordinates, and allowing assigning a scalar value into a multi-channel image.
dip.SubpixelMinima(), when a mask image was given, didn’t work correctly.
**= operator did the computations correctly, but then assigned
None to the variable instead of the
result of the operation. The
** operator didn’t work with a single pixel (a number or a list) on the
(See also bugfixes to DIPlib.)