Skip to content

Commit

Permalink
Improve masks conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
ppouchin committed Feb 19, 2024
1 parent 131bd93 commit 33064a0
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 14 deletions.
5 changes: 4 additions & 1 deletion src/main/java/fr/igred/omero/roi/GenericShapeWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import fr.igred.omero.exception.AccessException;
import fr.igred.omero.exception.ServiceException;
import ij.ImagePlus;
import ij.gui.ImageRoi;
import ij.gui.Line;
import ij.gui.Roi;
import ij.gui.ShapeRoi;
Expand Down Expand Up @@ -126,6 +127,8 @@ static ShapeList fromImageJ(ij.gui.Roi ijRoi) {
default:
if (ijRoi instanceof TextRoi) {
list.add(new TextWrapper((TextRoi) ijRoi));
} else if (ijRoi instanceof ImageRoi) {
list.add(new MaskWrapper((ImageRoi) ijRoi));
} else {
list.add(new RectangleWrapper(ijRoi));
}
Expand Down Expand Up @@ -256,7 +259,7 @@ protected void copyToIJRoi(ij.gui.Roi ijRoi) {
ijRoi.setStrokeColor(getStroke());
Color fill = getFill();
if (!TRANSPARENT.equals(fill)) {
ijRoi.setFillColor(getFill());
ijRoi.setFillColor(fill);
}
int c = Math.max(0, getC() + 1);
int z = Math.max(0, getZ() + 1);
Expand Down
59 changes: 58 additions & 1 deletion src/main/java/fr/igred/omero/roi/MaskWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
package fr.igred.omero.roi;


import ij.gui.ImageRoi;
import ij.gui.Roi;
import ij.process.ImageProcessor;
import omero.gateway.model.MaskData;

import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;


/**
Expand All @@ -32,6 +36,9 @@
public class MaskWrapper extends GenericShapeWrapper<MaskData> {


private static final double MAX_UINT8 = 255.0;


/**
* Constructor of the MaskWrapper class using a MaskData.
*
Expand All @@ -50,6 +57,41 @@ public MaskWrapper() {
}


/**
* Constructor of the MaskWrapper class using an ImageJ ImageRoi.
*
* @param imageRoi An ImageJ ImageRoi.
*/
public MaskWrapper(ImageRoi imageRoi) {
this();
data.setX(imageRoi.getXBase());
data.setY(imageRoi.getYBase());
data.setWidth(imageRoi.getFloatWidth());
data.setHeight(imageRoi.getFloatHeight());

ImageProcessor ip = imageRoi.getProcessor();
ip.flipVertical();
data.setMask(ip.getIntArray());
ip.flipVertical();

Color lut = new Color(ip.getCurrentColorModel().getRGB((int) ip.getMax()));
int r = lut.getRed();
int g = lut.getGreen();
int b = lut.getBlue();
int a = (int) (imageRoi.getOpacity() * MAX_UINT8);

data.setText(imageRoi.getName());
super.copyFromIJRoi(imageRoi);
data.getShapeSettings().setFill(new Color(r, g, b, a));

// Always 0 as long as ImageRoi::getAngle() method is not updated
double angle = StrictMath.toRadians(-imageRoi.getAngle());
AffineTransform transform = new AffineTransform();
transform.rotate(angle, imageRoi.getXBase(), imageRoi.getYBase());
super.setTransform(transform);
}


/**
* Constructor of the MaskWrapper class using a new MaskData.
*
Expand Down Expand Up @@ -187,6 +229,16 @@ public int[][] getMaskAsBinaryArray() {
}


/**
* Returns the mask image.
*
* @return See above.
*/
public BufferedImage getMaskAsBufferedImage() {
return data.getMaskAsBufferedImage();
}


/**
* Returns the mask as a byte array.
*
Expand Down Expand Up @@ -288,7 +340,12 @@ public Roi toImageJ() {

Roi roi;
if (transform.getType() == AffineTransform.TYPE_IDENTITY) {
roi = new ij.gui.Roi(getX(), getY(), getWidth(), getHeight());
int x = (int) getX();
int y = (int) getY();
ImageRoi imgRoi = new ImageRoi(x, y, getMaskAsBufferedImage());
imgRoi.setZeroTransparent(true);
imgRoi.setOpacity(getFill().getAlpha() / MAX_UINT8);
roi = imgRoi;
} else {
PointWrapper p1 = new PointWrapper(getX(), getY() + getHeight() / 2);
PointWrapper p2 = new PointWrapper(getX() + getWidth(), getY() + getHeight() / 2);
Expand Down
42 changes: 30 additions & 12 deletions src/test/java/fr/igred/omero/roi/ROI2ImageJTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNull;
Expand Down Expand Up @@ -329,23 +330,40 @@ void convertMask() {
MaskWrapper mask = new MaskWrapper();
mask.setCoordinates(3, 3, 10, 10);
mask.setCZT(0, 0, 2);
mask.setFill(Color.WHITE);

Roi ijRectangle = mask.toImageJ();
assertEquals(mask.toAWTShape().getBounds(), ijRectangle.getBounds());
int[][] maskPixels = new int[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (i > 3 && i < 7 && j > 4 && j < 8) {
maskPixels[i][j] = 1;
}
}
}
mask.setMask(maskPixels);

Roi imgRoi = mask.toImageJ();
assertEquals(mask.toAWTShape().getBounds(), imgRoi.getBounds());

List<Roi> roiList = new ArrayList<>(1);
roiList.add(ijRectangle);
roiList.add(imgRoi);
ROIWrapper roi = ROIWrapper.fromImageJ(roiList).get(0);

RectangleWrapper newRectangle = roi.getShapes().getElementsOf(RectangleWrapper.class).get(0);
MaskWrapper newMask = roi.getShapes().getElementsOf(MaskWrapper.class).get(0);
int[][] checkMask = newMask.getMaskAsBinaryArray();

assertEquals(mask.getX(), newMask.getX(), Double.MIN_VALUE);
assertEquals(mask.getY(), newMask.getY(), Double.MIN_VALUE);
assertEquals(mask.getWidth(), newMask.getWidth(), Double.MIN_VALUE);
assertEquals(mask.getHeight(), newMask.getHeight(), Double.MIN_VALUE);
assertEquals(mask.getC(), newMask.getC());
assertEquals(mask.getZ(), newMask.getZ());
assertEquals(mask.getT(), newMask.getT());
assertEquals(maskPixels.length, checkMask.length);
for (int i = 0; i < maskPixels.length; i++) {
assertArrayEquals(maskPixels[i], checkMask[i]);
}

assertEquals(mask.getX(), newRectangle.getX(), Double.MIN_VALUE);
assertEquals(mask.getY(), newRectangle.getY(), Double.MIN_VALUE);
assertEquals(mask.getWidth(), newRectangle.getWidth(), Double.MIN_VALUE);
assertEquals(mask.getHeight(), newRectangle.getHeight(), Double.MIN_VALUE);
assertEquals(mask.getC(), newRectangle.getC());
assertEquals(mask.getZ(), newRectangle.getZ());
assertEquals(mask.getT(), newRectangle.getT());
}


Expand Down Expand Up @@ -406,7 +424,7 @@ void convertText() {
@ParameterizedTest(name = "{0}")
@ValueSource(ints = {Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC})
void convertText(int style) {
Font font = new Font("Arial", style, 25);
Font font = new Font("Arial", style, 25);
List<Roi> roiList = new ArrayList<>(1);
TextRoi ijText = new TextRoi(3, 3, "Text");
ijText.setAngle(33);
Expand Down

0 comments on commit 33064a0

Please sign in to comment.