## DIPimage 2.4 released

I’m pleased to announce that a new version of DIPimage has been released. There’s some performance improvements, some
bug fixes, and some new functions. The `measure`

function has some new features also, that use the convex hull of the
objects. The Feret measure is computed differently now, also using the convex hull. This makes this computation more
accurate and also somewhat faster.

But most importantly, we have rewritten a lot of the code that does binary arithmetic and logic operators. Binary here
means these operators take two inputs. `+`

, `-`

, `*`

, `&`

, `>`

and `==`

are examples of binary operators. All of these
used to be computed using MATLAB code, which required some nifty tricks. For example, computations between images of
different type (i.e. an 8-bit integer image added to an 16-bit integer image) used to require data conversion because
MATLAB cannot perform such a computation. All of these binary operators are now computed by DIPlib instead. This makes
some cases much more efficient. We parallelized the arithmetic and logic code in DIPlib for further speed improvements.

One added benefit of the new implementation is that these operators now all have built-in *singleton dimension
expansion*. What this means is that, if one image has a dimension with size one (a *singleton dimension*), and the
corresponding dimension in the other image has a larger size, the first image is automatically replicated to match the
size of the first. For example, assume we have these two images:

```
a = readim('chromo3d');
t = mean(a,[],[1,2]);
```

The image `a`

, one of the standard images that come with DIPimage, has a size of 160x140x16 pixels. The image `t`

has a
size of 1x1x16 pixels. This image contains the average intensity in each 2D plane of image `a`

. If we now want to divide
each 2D plane by its average, we want to do `a/t`

, except that the two images have different sizes! One way around this
is to replicate the smaller image using `repmat`

:

```
a = a / repmat(t,imsize(a,1),imsize(a,2),1);
```

This requires lots of memory, because a large array is created by `repmat`

. Another option is to do the operation on
each 2D slice using a `for`

loop:

```
for ii=0:imsize(a,3)-1
a(:,:,ii) = a(:,:,ii)/t(ii);
end
```

This method is slower, because a slice has to be extracted and inserted into the image `a`

. MATLAB has a relatively new
function, `bsxfun`

(**b**inary **s**ingleton e**x**pansion **fun**ction), which can efficiently calculate our
operation (see for
example this post by Loren). Of
course, it doesn’t work with `dip_image`

objects, and also requires that the two inputs are of the same data type, so we
convert the images to single-precision floating-point arrays:

```
a = bsxfun(@rdivide,single(a),single(t));
a = dip_image(a);
```

This looses a lot of the efficiency because the large image must be converted to `single`

. Luckily, DIPlib has had
binary singleton expansion included in its operators since its inception. Now these operators are used by DIPimage, so
we can simply type:

```
a = a / t;
```

and obtain the same result we have been after!

For a full log of changes see the DIPlib website.