Writing text to an image using imglib2

I would like to write an identifier to images that I create with imglib2. Much like you would do in OpenCV with the method puttext.
Is there any convenient drawing function for doing this in imglib2?

Hi @michaelmell,

What’s your use case? I’m sure we can find a way to do what you want, but I’m almost certain this doesn’t exist in imglib2 natively.

Imglib2 focuses on raster images, and for text, I’d go with another approach in general.

  • Bigdataviewer has examples using java awt for drawing text.

  • Paintera has examples of drawing text with javafx.

John

1 Like

Hey @bogovicj ,

I would like to do the following:

I am drawing the components that I get from the MSER tree in Moma to an image stack, so that each slice in the stack shows all components in a given component level (see code below). I then use ImageJFunctions.show(Views.stack(componentLevelImageStack)); to show the image stack, which is a poor-mans alternative to writing my own GUI-component to do this.

Since I can open multiple component-stack images from inside Moma (one per time-step), I can end up having multiple windows open for different time-steps and (possibly) also at different component levels. This can quickly become confusing. Therefore I would like see the time-step and component level in/on the corresponding component-level slice.

I would like to achieve this with minimal development effort (this is a temporary solution until we figure out, what we really want/need to visualize this), hence my idea was to continue using ImageJFunctions.show(...) and just draw this information to the images themselves.

Thanks for your reply and thanks for any suggestions,

Michael

public static <C extends Component<FloatType, C>> void drawComponentTree(ComponentForest<C> ct,
                                                                         List<Component<FloatType, ?>> componentsInOptimalSolution) {
    if (ct.roots().isEmpty()) {
        throw new ValueException("ct.roots() is empty");
    }

    // create image factory with correct dimensions
    C first = ct.roots().iterator().next();
    RandomAccessibleInterval sourceImage = ((SimpleComponent) first).getSourceImage();
    long xDim = sourceImage.dimension(0);
    long yDim = sourceImage.dimension(1);
    ArrayImgFactory<ARGBType> imageFactory = new ArrayImgFactory<>(new ARGBType());

    // define consumer that will draw components to image and add them to the image stack
    final ArrayList<RandomAccessibleInterval<ARGBType>> componentLevelImageStack = new ArrayList<>();
    Consumer<Pair<List<C>, Integer>> levelComponentsConsumer = (levelComponentsListAndLevel)-> {
        List<C> componentOfLevel = levelComponentsListAndLevel.getValue0();
        {
            final RandomAccessibleInterval<ARGBType> componentLevelImage = imageFactory.create(xDim, yDim);
            setImageToValue(Views.iterable(componentLevelImage), new ARGBType(ARGBType.rgba(100, 0, 0, 0)));
            for(C ctn : componentOfLevel){
                boolean val = componentsInOptimalSolution.contains(ctn);
                drawComponentToImage(ctn, sourceImage, componentLevelImage, val);
            }
            componentLevelImageStack.add(componentLevelImage);
        }
    };

    // run for components in each level
    ComponentTreeUtils.doForEachComponentInTreeLevel(ct, levelComponentsConsumer);

    // show
    ImageJFunctions.show(Views.stack(componentLevelImageStack));
}


private static void drawComponentToImage(final Component<?, ?> ctn,
                                         RandomAccessibleInterval<FloatType> sourceImage,
                                         RandomAccessibleInterval<ARGBType> targetImage,
                                         boolean ctnIsSelected) {
    RandomAccess<FloatType> source = sourceImage.randomAccess();
    RandomAccess<ARGBType> out = targetImage.randomAccess();

    for (Localizable location : ctn) {
        source.setPosition(location);
        out.setPosition(location);
        int level = (int) (source.get().getRealFloat() * 255);
        ARGBType value = new ARGBType(ARGBType.rgba(level, level, level, 0));
        if (ctnIsSelected) {
            value = new ARGBType(ARGBType.rgba(0, level, 0, 0));
        }
        out.get().set(value);
    }
}
1 Like

Hi @michaelmell,

Since you’re using ImageJFunctions.show, and you want “minimal development effort”,
you can use a bunch of the imagej1 methods, e.g. TextRoi

An example:

imp = ImageJFunctions.show( dataset );
text = new TextRoi( 40, 80, "hiya" );
imp.setRoi( text, true );

There’s also a drawPixels method that may be of interest to you.

John