ImageJ-Fiji Quick Tip #4: Draw objects for Deep Learning Ground Truth

With the growth of AI-based tools (e.g. Deep Learning) requiring drawn object examples (Ground Truth), there might be a need for manual drawing (also named annotation) tools. ImageJ had such tools for a while, but did you use them so far?

Show me quickly...

A good solution to be able to draw shapes is to have a toolbar. We designed one for you to try it - find it here: (right-click on this link > "Save Link As") https://github.com/AiviaCommunity/ImageJ-Macros-Utilities/raw/master/Drawing%20Tools_for%20DL_1.0.ijm

  • Copy / Paste this file in \ImageJ\macros\toolsets\ folder

  • Then, after starting ImageJ, select it like this:


Here is how to use it:

  1. Create a new "Channel" in your image, with "Image > Stacks > Add Slice" and select "Channel" if you have a multi-dimensional image...

  2. Select the brush tool with the icon and click on the white square to set white color

  3. Now you can draw on your new channel, adjust the brush size with "-" and "+"

  4. You can erase your drawings by setting the black color (square icon) or use selection tools (rectangle, freehand, magic wand, etc.) and press "Delete" on your keyboard if background color is black

  5. You can use the magic wand to select a contour and fill it with "F" key

  6. Final icon in the toolbar is to alternate between composite view and single color view, if you want to quickly review your drawings, for instance...


Step by Step for macro editors


  • Paintbrush tool: it exists as a built-in tool which is available in the original "Drawing Toolset". If you open the provided toolset file, you'll find the older version of it, because we want here to have control on the brush width :) So we had an extra line to retrieve latest width set by user...

macro "Paintbrush Tool - C037La077Ld098L6859L4a2fL2f4fL3f99L5e9bL9b98L6888L5e8dL888c" {
    brushWidth = CollectBrushWidth();   // This is the extra line!
    getCursorLoc(x, y, z, flags);
    if (flags&alt!=0)      // see original global 'alt' var in the file
        setColorToBackgound();   // see unmodified function in the file
    draw(brushWidth);            // see unmodified function in the file
}

We create a function that (tries to) collect the size from our beloved ij.Prefs file. ^^ If it fails because the key doesn't exist in your version of ImageJ, then the trick of drawing a line works to retrieve "Line Width" value, at least...

function CollectBrushWidth() {
    // Trying to collect Paintbrush width in prefs
    brushWidth = parseInt(call("ij.Prefs.get", "brush.width", 0));
    
    // Set dummy line to get line width if previous fails
    if (brushWidth == 0) {
        makeLine(0,0,1,0);
        brushWidth = getValue("selection.width");
        run("Select None");
    }
    
    // Setting key if not existing
    call("ij.Prefs.set", "brush.width", brushWidth);
    
    return brushWidth;
}

  • Interesting option to keep for the paintbrush tool is to set a width with an input window:

macro 'Paintbrush Tool Options...' {
    brushWidth = call("ij.Prefs.get", "brush.width", 1);
    newBrushWidth = getNumber("Brush Width (pixels):", brushWidth);
    call("ij.Prefs.set", "brush.width", newBrushWidth);
}

  • Then we can play with brush size, and avoid getting errors due to width = 0:

macro "DecreaseBrushSize Action Tool - T6e20-" {
    brushWidth = parseInt(call("ij.Prefs.get", "brush.width", 2));
    newBrushWidth = brushWidth - 1;
    if (newBrushWidth < 1) newBrushWidth = 1;
    
    call("ij.Prefs.set", "brush.width", newBrushWidth);
}

  • Color buttons are really simple piece of code but good shortcuts:

setForegroundColor(255, 255, 255);

  • Extra is about fast toggling between "composite" and "color" mode:

macro "SwapCompositeView Action Tool - Cb00T0b11CC0b0T7b09oC00bTcb09l" {
    if (!is("composite") || nSlices < 2) {exit("Use Make Composite first...");}
    Stack.getDisplayMode(mode);
    if (mode == "color") {
        Stack.setDisplayMode("composite");
    } else {
        Stack.setDisplayMode("color");
    }
}

Remember, your dealing with painting on a new channel to create a binary mask, so feel free to create extra tools (reset button for instance?)...


Additional Thoughts

This post is also useful to learn about building toolsets on your own. We'll do another post about this later on - depends also on your feedback :)


A toolset file is a simple text file which can be easily edited. We recommend you to use an advanced text editor (Notepad++, Sublime Text, Atom, etc.) to properly manage indentations and optionally use some color code...


Very interesting tip: you can edit a toolset file, save it while ImageJ is opened. You just have to select the toolset again in the ImageJ toolbar. No need to "Refresh Menus"! :D


Toolset code was inspired from Jérôme Mutterer post here: http://imagej.1557.x6.nabble.com/How-do-I-set-Pencil-Width-Brush-Width-or-Eraser-Width-from-within-a-Java-Plug-in-td3682608.html