RoiEnlarger Pixel Limitation to 255

Hi there,

I was wondering, why the RoiEnlarger function limits the number of pixels to enlarge a ROI to 255. In the source code, this is hard-coded in the enlarge-function

public static Roi enlarge(Roi roi, double pixels) {
        if (pixels==0)
            return roi;
        int type = roi.getType();
        int n = (int)Math.round(pixels);
        if (type==Roi.RECTANGLE || type==Roi.OVAL)
            return enlargeRectOrOval(roi, n);
        if (n>255)
            n = 255;
        if (n<0)
            return shrink(roi, -n);
        Rectangle bounds = roi.getBounds();
        int width = bounds.width;
        int height = bounds.height;
        width += 2*n + 2;
        height += 2*n + 2;
        ImageProcessor ip = new ByteProcessor(width, height);
        ip.invert();
        roi.setLocation(n+1, n+1);
        ip.setColor(0);
        ip.fill(roi);
        ip.setThreshold(0, 0, ImageProcessor.NO_LUT_UPDATE);
        Roi roi2 = (new ThresholdToSelection()).convert(ip);
        Rectangle bounds2 = roi2.getBounds();
        int xoffset = bounds2.x - (n+1);
        int yoffset = bounds2.y - (n+1);
        roi.setLocation(bounds.x, bounds.y);
        boolean bb = Prefs.blackBackground;
        Prefs.blackBackground = true;
        new EDM().toEDM(ip);
        Prefs.blackBackground = bb;
        ip.setThreshold(0, n, ImageProcessor.NO_LUT_UPDATE);
        //new ImagePlus("ip", ip).show();
        roi2 = (new ThresholdToSelection()).convert(ip);
        if (roi2==null)
            return roi; 
        roi2.setLocation(bounds.x-n+xoffset, bounds.y-n+yoffset);
        roi2.setStrokeColor(roi.getStrokeColor());
        if (roi.getStroke()!=null)
            roi2.setStroke(roi.getStroke());
        return roi2;
    }

There is no evident reason for this limitation in my opinion.

Would it be possible to ask for an update to overcome this limitation, since sometimes I want to enlarge the ROI more than 255 pixels and still keep the overall shape of the ROIs.

Is there maybe another handy solution to that problem, maybe using IJ2 functions?

Thank you very much!

Cheers,
David

I’d guess the reason for this limitation is that (in order to provide acceptable performance/speed) it uses a Euclidean Distance Map (EDM) to compute the enlarged ROI. The method EDM.toEDM(ip) is only implemented for 8-bit images, i.e. has a maximum of 255:

As a workaround, you can convert your ROIs to binary masks and use a morphological dilation (or a maximum filter) to enlarge them. But note that morphological operations and non-linear filters with such a large structuring element will have very slow performance. Alternatively, you could downsample, then enlarge, then upsample your mask.

4 Likes

Nice guess (I’d been foolishly thinking max filters…) - the code is here.

But would swapping this for makeFloatEDM be a relatively straightforward way to lift the limitation in ImageJ1?

1 Like

Thanks for linking. As @dcolam included the relevant source code in their first post here, all I did to base my guess on was scrolling down… :wink:

@Wayne, what do you think about that change?

3 Likes

The latest ImageJ daily build (1.52u40) removes the 255 pixel limit from the RoiEnlarger (Edit>Selection>Enlarge).

2 Likes

Thank you, all the three of you @imagejan, @petebankhead and @Wayne. This solved the problem.

Cheers,
David