From 0c97e389031781f33cc2a0b69ca88c714887743d Mon Sep 17 00:00:00 2001
From: Daniel Gonzalez <dgonzale@pasteur.fr>
Date: Mon, 10 Aug 2020 10:50:54 +0200
Subject: [PATCH] Code commit

---
 RandomCrops/.classpath                        |   9 ++
 RandomCrops/.gitignore                        |   3 +
 RandomCrops/.project                          |  17 +++
 RandomCrops/export.jardesc                    |  18 +++
 .../randomcrops/RandomRectangleGenerator.java | 120 +++++++++++++++
 .../randomcrops/GenerateRandomCrops.java      | 142 ++++++++++++++++++
 .../GenerateRandomRectangleRois.java          | 138 +++++++++++++++++
 icon100px.png                                 | Bin 0 -> 1211 bytes
 8 files changed, 447 insertions(+)
 create mode 100644 RandomCrops/.classpath
 create mode 100644 RandomCrops/.gitignore
 create mode 100644 RandomCrops/.project
 create mode 100644 RandomCrops/export.jardesc
 create mode 100644 RandomCrops/src/main/java/danyfel80/randomcrops/RandomRectangleGenerator.java
 create mode 100644 RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomCrops.java
 create mode 100644 RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomRectangleRois.java
 create mode 100644 icon100px.png

diff --git a/RandomCrops/.classpath b/RandomCrops/.classpath
new file mode 100644
index 0000000..f2bb7c1
--- /dev/null
+++ b/RandomCrops/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="var" path="ICY_JAR"/>
+	<classpathentry kind="var" path="ICY_PLUGINS/adufour/ezplug/EzPlug.jar"/>
+	<classpathentry kind="var" path="ICY_PLUGINS/adufour/blocks/Blocks.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/RandomCrops/.gitignore b/RandomCrops/.gitignore
new file mode 100644
index 0000000..c40361a
--- /dev/null
+++ b/RandomCrops/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/.settings/
+*.jar
\ No newline at end of file
diff --git a/RandomCrops/.project b/RandomCrops/.project
new file mode 100644
index 0000000..f437f6b
--- /dev/null
+++ b/RandomCrops/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>RandomCrops</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/RandomCrops/export.jardesc b/RandomCrops/export.jardesc
new file mode 100644
index 0000000..5052a61
--- /dev/null
+++ b/RandomCrops/export.jardesc
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
+<jardesc>
+    <jar path="RandomCrops/RandomCrops.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/RandomCrops/export.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
+        <javaElement handleIdentifier="=RandomCrops/src\/main\/java"/>
+        <file path="/RandomCrops/.classpath"/>
+        <file path="/RandomCrops/.project"/>
+    </selectedElements>
+</jardesc>
diff --git a/RandomCrops/src/main/java/danyfel80/randomcrops/RandomRectangleGenerator.java b/RandomCrops/src/main/java/danyfel80/randomcrops/RandomRectangleGenerator.java
new file mode 100644
index 0000000..99c8a6d
--- /dev/null
+++ b/RandomCrops/src/main/java/danyfel80/randomcrops/RandomRectangleGenerator.java
@@ -0,0 +1,120 @@
+package danyfel80.randomcrops;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.function.Supplier;
+
+import icy.roi.ROI2D;
+import plugins.kernel.roi.roi2d.ROI2DRectangle;
+
+public class RandomRectangleGenerator implements Callable<List<ROI2DRectangle>>
+{
+
+    public static class Builder
+    {
+
+        private Dimension rectangleSize;
+        private int rectangleCount;
+        private List<ROI2D> limitingRois;
+
+        public Builder(Dimension rectangleSize, int rectangleCount, List<ROI2D> limitingRois)
+        {
+            Objects.requireNonNull(rectangleSize);
+            Objects.requireNonNull(limitingRois);
+            if (limitingRois.isEmpty())
+                throw new IllegalArgumentException("limitingRois is empty. At least one roi is needed");
+
+            this.rectangleSize = rectangleSize;
+            this.rectangleCount = rectangleCount;
+            this.limitingRois = limitingRois;
+        }
+
+        public RandomRectangleGenerator build()
+        {
+            RandomRectangleGenerator generator = new RandomRectangleGenerator();
+            generator.rectangleSize = rectangleSize;
+            generator.rectangleCount = rectangleCount;
+            generator.limitingRois = limitingRois;
+            return generator;
+        }
+
+    }
+
+    private Random randomValueGenerator;
+    private Dimension rectangleSize;
+    private int rectangleCount;
+    private List<ROI2D> limitingRois;
+
+    private RandomRectangleGenerator()
+    {
+        randomValueGenerator = new Random();
+    }
+
+    @Override
+    public List<ROI2DRectangle> call() throws Exception
+    {
+        computeValueBoundary();
+        if (valueBoundary.getWidth() < rectangleSize.width || valueBoundary.getHeight() < rectangleSize.height)
+            throw new IllegalArgumentException("Rectangle");
+
+        List<ROI2DRectangle> rectangles = new ArrayList<>(rectangleCount);
+        for (int count = 0; count < rectangleCount; count++)
+        {
+            if (Thread.interrupted())
+                throw new InterruptedException();
+
+            rectangles.add(getValidRandomRectangle());
+        }
+        return rectangles;
+    }
+
+    private Rectangle2D valueBoundary;
+    private Supplier<Integer> xGenerator;
+    private Supplier<Integer> yGenerator;
+
+    private void computeValueBoundary()
+    {
+        Rectangle2D seedBounds = limitingRois.get(0).getBounds2D();
+        valueBoundary = new Rectangle2D.Double(seedBounds.getX(), seedBounds.getY(), seedBounds.getWidth(),
+                seedBounds.getHeight());
+        limitingRois.stream().map(ROI2D::getBounds2D)
+                .forEach(rect2d -> Rectangle2D.union(valueBoundary, rect2d, valueBoundary));
+
+        int minX = (int) Math.floor(valueBoundary.getMinX());
+        int maxX = (int) Math.floor(valueBoundary.getMaxX());
+        int xLength = maxX - minX;
+        xGenerator = () -> minX + randomValueGenerator.nextInt(xLength);
+
+        int minY = (int) Math.floor(valueBoundary.getMinY());
+        int maxY = (int) Math.floor(valueBoundary.getMaxY());
+        int yLength = maxY - minY;
+        yGenerator = () -> minY + randomValueGenerator.nextInt(yLength);
+    }
+
+    private ROI2DRectangle getValidRandomRectangle() throws InterruptedException
+    {
+        Rectangle rect = new Rectangle(rectangleSize);
+        do
+        {
+            if (Thread.interrupted())
+                throw new InterruptedException();
+
+            rect.x = xGenerator.get();
+            rect.y = yGenerator.get();
+        }
+        while (!isValidRectangle(rect));
+        return new ROI2DRectangle(rect);
+    }
+
+    private boolean isValidRectangle(Rectangle rect)
+    {
+        return limitingRois.stream().anyMatch(roi -> roi.getBounds2D().contains(rect) && roi.contains(rect));
+    }
+
+}
diff --git a/RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomCrops.java b/RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomCrops.java
new file mode 100644
index 0000000..f499637
--- /dev/null
+++ b/RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomCrops.java
@@ -0,0 +1,142 @@
+package plugins.danyfel80.randomcrops;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import danyfel80.randomcrops.RandomRectangleGenerator;
+import icy.roi.ROI2D;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import icy.system.IcyHandledException;
+import plugins.adufour.blocks.lang.Block;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.ezplug.EzGroup;
+import plugins.adufour.ezplug.EzPlug;
+import plugins.adufour.ezplug.EzStoppable;
+import plugins.adufour.ezplug.EzVarBoolean;
+import plugins.adufour.ezplug.EzVarInteger;
+import plugins.adufour.ezplug.EzVarSequence;
+import plugins.adufour.vars.lang.VarSequenceArray;
+import plugins.kernel.roi.roi2d.ROI2DRectangle;
+
+public class GenerateRandomCrops extends EzPlug implements Block, EzStoppable
+{
+
+    private EzVarSequence varInSequence;
+    private EzVarInteger varInRectangleWidth;
+    private EzVarInteger varInRectangleHeight;
+    private EzVarInteger varInNumberOfRectangles;
+    private EzVarBoolean varInLimitRectanglesToROIs;
+
+    @Override
+    protected void initialize()
+    {
+        initializeInputVars();
+        addEzComponent(varInSequence);
+        addEzComponent(new EzGroup("Generated rectangles", varInRectangleWidth, varInRectangleHeight,
+                varInNumberOfRectangles));
+        addEzComponent(varInLimitRectanglesToROIs);
+    }
+
+    private void initializeInputVars()
+    {
+        varInSequence = new EzVarSequence("Sequence");
+        varInRectangleWidth = new EzVarInteger("Rectangle width (px)", 512, 1, 10000, 1);
+        varInRectangleHeight = new EzVarInteger("Rectangle height (px)", 512, 1, 10000, 1);
+        varInNumberOfRectangles = new EzVarInteger("Number of rectangles", 10, 0, 10000000, 1);
+        varInLimitRectanglesToROIs = new EzVarBoolean("Limit rectangles to ROIs", false);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        initializeInputVars();
+        inputMap.add(varInSequence.name, varInSequence.getVariable());
+        inputMap.add(varInRectangleWidth.name, varInRectangleWidth.getVariable());
+        inputMap.add(varInRectangleHeight.name, varInRectangleHeight.getVariable());
+        inputMap.add(varInNumberOfRectangles.name, varInNumberOfRectangles.getVariable());
+        inputMap.add(varInLimitRectanglesToROIs.name, varInLimitRectanglesToROIs.getVariable());
+    }
+
+    private VarSequenceArray varOutSequences;
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        varOutSequences = new VarSequenceArray("Random crops");
+        outputMap.add(varOutSequences.getName(), varOutSequences);
+    }
+
+    @Override
+    protected void execute()
+    {
+        readParameters();
+        try
+        {
+            generateRandomRectangles();
+        }
+        catch (Exception e)
+        {
+            throw new IcyHandledException("Error generating random rectangles: " + e.getMessage(), e);
+        }
+        setOutput();
+    }
+
+    private Sequence sequence;
+    private Dimension rectangleSize;
+    private Integer rectangleCount;
+    private Boolean limitRectanglesToRois;
+    private List<ROI2D> limitingRois;
+
+    private void readParameters()
+    {
+        sequence = varInSequence.getValue(true);
+        rectangleSize = new Dimension(varInRectangleWidth.getValue(), varInRectangleHeight.getValue());
+        rectangleCount = varInNumberOfRectangles.getValue();
+        limitRectanglesToRois = varInLimitRectanglesToROIs.getValue();
+        limitingRois = new ArrayList<>();
+        List<ROI2D> sequenceRois = sequence.getROI2Ds();
+        if (!limitRectanglesToRois || sequenceRois.isEmpty())
+        {
+            limitingRois.add(new ROI2DRectangle(new Rectangle(sequence.getWidth(), sequence.getHeight())));
+        }
+        else
+        {
+
+            limitingRois.addAll(sequenceRois);
+        }
+    }
+
+    private List<Sequence> croppedSequences;
+
+    private void generateRandomRectangles() throws Exception
+    {
+        RandomRectangleGenerator rectGenerator = new RandomRectangleGenerator.Builder(rectangleSize, rectangleCount,
+                limitingRois).build();
+        List<ROI2DRectangle> rectangles = rectGenerator.call();
+        croppedSequences = rectangles.stream().map(roi -> SequenceUtil.getSubSequence(sequence, roi))
+                .collect(Collectors.toList());
+    }
+
+    private void setOutput()
+    {
+        if (isHeadLess())
+        {
+            varOutSequences.setValue(croppedSequences.stream().toArray(Sequence[]::new));
+        }
+        else
+
+        {
+            croppedSequences.stream().forEach(seq -> addSequence(seq));
+        }
+    }
+
+    @Override
+    public void clean()
+    {// Nothing to do here
+    }
+
+}
diff --git a/RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomRectangleRois.java b/RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomRectangleRois.java
new file mode 100644
index 0000000..a7bc96e
--- /dev/null
+++ b/RandomCrops/src/main/java/plugins/danyfel80/randomcrops/GenerateRandomRectangleRois.java
@@ -0,0 +1,138 @@
+package plugins.danyfel80.randomcrops;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+
+import danyfel80.randomcrops.RandomRectangleGenerator;
+import icy.roi.ROI;
+import icy.roi.ROI2D;
+import icy.sequence.Sequence;
+import icy.system.IcyHandledException;
+import plugins.adufour.blocks.lang.Block;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.ezplug.EzGroup;
+import plugins.adufour.ezplug.EzPlug;
+import plugins.adufour.ezplug.EzVarBoolean;
+import plugins.adufour.ezplug.EzVarInteger;
+import plugins.adufour.ezplug.EzVarSequence;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.kernel.roi.roi2d.ROI2DRectangle;
+
+public class GenerateRandomRectangleRois extends EzPlug implements Block
+{
+
+    private EzVarSequence varInSequence;
+    private EzVarInteger varInRectangleWidth;
+    private EzVarInteger varInRectangleHeight;
+    private EzVarInteger varInNumberOfRectangles;
+    private EzVarBoolean varInLimitRectanglesToROIs;
+
+    @Override
+    protected void initialize()
+    {
+        initializeInputVars();
+        addEzComponent(varInSequence);
+        addEzComponent(new EzGroup("Generated rectangles", varInRectangleWidth, varInRectangleHeight,
+                varInNumberOfRectangles));
+        addEzComponent(varInLimitRectanglesToROIs);
+    }
+
+    private void initializeInputVars()
+    {
+        varInSequence = new EzVarSequence("Sequence");
+        varInRectangleWidth = new EzVarInteger("Rectangle width (px)", 512, 1, 10000, 1);
+        varInRectangleHeight = new EzVarInteger("Rectangle height (px)", 512, 1, 10000, 1);
+        varInNumberOfRectangles = new EzVarInteger("Number of rectangles", 10, 0, 10000000, 1);
+        varInLimitRectanglesToROIs = new EzVarBoolean("Limit rectangles to ROIs", false);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        initializeInputVars();
+        inputMap.add(varInSequence.name, varInSequence.getVariable());
+        inputMap.add(varInRectangleWidth.name, varInRectangleWidth.getVariable());
+        inputMap.add(varInRectangleHeight.name, varInRectangleHeight.getVariable());
+        inputMap.add(varInNumberOfRectangles.name, varInNumberOfRectangles.getVariable());
+        inputMap.add(varInLimitRectanglesToROIs.name, varInLimitRectanglesToROIs.getVariable());
+    }
+
+    private VarROIArray varOutRectangles;
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        varOutRectangles = new VarROIArray("Random rectangles");
+        outputMap.add(varOutRectangles.getName(), varOutRectangles);
+    }
+
+    @Override
+    protected void execute()
+    {
+        readParameters();
+        try
+        {
+            generateRandomRectangles();
+        }
+        catch (Exception e)
+        {
+            throw new IcyHandledException("Error generating random rectangles: " + e.getMessage(), e);
+        }
+        setOutput();
+    }
+
+    private Sequence sequence;
+    private Dimension rectangleSize;
+    private Integer rectangleCount;
+    private Boolean limitRectanglesToRois;
+    private List<ROI2D> limitingRois;
+
+    private void readParameters()
+    {
+        sequence = varInSequence.getValue(true);
+        rectangleSize = new Dimension(varInRectangleWidth.getValue(), varInRectangleHeight.getValue());
+        rectangleCount = varInNumberOfRectangles.getValue();
+        limitRectanglesToRois = varInLimitRectanglesToROIs.getValue();
+        limitingRois = new ArrayList<>();
+        List<ROI2D> sequenceRois = sequence.getROI2Ds();
+        if (!limitRectanglesToRois || sequenceRois.isEmpty())
+        {
+            limitingRois.add(new ROI2DRectangle(new Rectangle(sequence.getWidth(), sequence.getHeight())));
+        }
+        else
+        {
+
+            limitingRois.addAll(sequenceRois);
+        }
+    }
+
+    private List<ROI2DRectangle> rectangles;
+
+    private void generateRandomRectangles() throws Exception
+    {
+        RandomRectangleGenerator rectGenerator = new RandomRectangleGenerator.Builder(rectangleSize, rectangleCount,
+                limitingRois).build();
+        rectangles = rectGenerator.call();
+    }
+
+    private void setOutput()
+    {
+        if (isHeadLess())
+        {
+            varOutRectangles.setValue(rectangles.stream().toArray(ROI[]::new));
+        }
+        else
+        {
+            sequence.addROIs(rectangles, true);
+        }
+
+    }
+
+    @Override
+    public void clean()
+    {// Nothing to do here
+    }
+
+}
diff --git a/icon100px.png b/icon100px.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2b9c1701760295ef4aeeb86276303461a41ef19
GIT binary patch
literal 1211
zcmeAS@N?(olHy`uVBq!ia0vp^DIm<j1|$m}O$`B3EX7WqAsj$Z!;#Vf<Z~8yL>4nJ
z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq<{ulc)B=-
zRLpsM$3G*+Rfhe;`}}R45&=s%%%+6ho%5$$h-)5;zgSgvaMgAX(GaH-``+dTB*w=H
zF|k!=zYkrZux(3I*NqAR+Ya{ppb27sn3sB$ZCg^gUrs7_M#}cPwfW_BpFjPMIkfMl
zz5S20w6bS=Ya4>RG?z}%k{7LQ-nnz9^068H3^uo)d)FHu+jBW<tDflEg<d`v%@r0I
zzp&?FSYiBm=A!xWrl~AN2^X##eZK5!zdwtMebK3<jU0<n(dOmR&f7(Q{P|P!@M^8T
z=cEq?_v<^nZdSgy<;=C_K>6yRGPx>NqYqp)+qIIPJ3bdkG{K9iSc_^?LRb7R<yATV
zIhY}@XM<R)+;e9!F|mCN8|quOGD!UUIgOpO*3J!X)UI=iL6O<tEuQlUUespbGx|LF
z%pJ31e^?)=GsG{?tTHZ`$=t0r;pNMhQG4U;-_EI)KA`gX@6PER8=iiAtKxYsHz()D
z(W6K0ov%c>m^fd%a^=cu20I3WpAF0Hm>%dRpXv9Uw8!MnsZ*l93YGKhFP{Hwu7BxA
zO<G#o`w3oBT^VgU4BNN;`P(ydz0gJ8JHMA(u{`i)_`T=4jj^5GJO&T9@HE4VESvW2
z`}g<8jT@c}^HU<ft-oGVSXNfHG;DRPvx|OJuKL=o%hzuG+2N(DGRtAw^y#t<oA2J5
zK5g2+JhR#F4L^s+U5<Nxhnt~JGOJOwGmWoOB0D>KHN(3f$9oMg#(W81=@1qcmdAYK
zTd4W@&ruCUY(Xm>)@*&uFz-{p@n?C)Q<5G_nO>Gyt!MmD?R?wvdvQk<Ti{HGS!dJc
z&a}U`@a3Op0b;Eg`%-^O^&U$;He+$+Jb$U=dCAX`8RWjsE9>sK#~*lq!6M!x5}y@~
z_rHFdoO@Mm(c{cnangmEtuEFnhMy1W`C2w~ADc1#vdQ0~DW+2uZ^<zw+_iUbIsVxu
z{_G~5TiJ|@cw0Jd-3usH_r2`zd^LF5jP^C#$}@C56ji&;1Q^a$uW4*Ka%MHdI>sHG
z55gIqH;aW#%6L9O=d>Qf4uM^Ln_O=@|4Uw5TT{%xT4>Q*MbAkxYz5~mxAQZYOZ93C
z3k$oi-TE&@eriTFhv3p3^{1wFy!h(3yjUs4H?_lT!rXVW4x9;A%+d_r(#UXQTl4P2
zw^XbQ*+0##Z|K;^8|X1}(cCMHdl(<ED^<;#`QPwZOy1V0aA)z*kcan^ME=^kzPR7)
zA^dqlsHaqi0T3O0J|T9+^SzQ=+k4{9R~u(3Fn-x(zL-s^2QTuGY<#g-^7oN5`^&Sn
zWjgN7-k5(qd+V*07hE-#PFW?lSM8MWFDv8Nc6jc}G5>JRdA;b5!<QUvSj*%}Sl3Mf
eW?<E8vG<G(7B!bG-VZEj7(8A5T-G@yGywpHR~Bvn

literal 0
HcmV?d00001

-- 
GitLab