From 57823ea5109e2eed3173a3e6a78aadd033abeeba Mon Sep 17 00:00:00 2001 From: Pierrik Lassalas Date: Fri, 10 Nov 2017 14:16:09 +0100 Subject: [PATCH] gs-cv: AbstractField: replaced private Rect with GSRect (coordinates as double instead of int) --- .../cv/newmodel/FillNewModelWithData.java | 5 +- .../cv/retriever/AbstractField.java | 53 +++++----- .../cv/retriever/AbstractFields.java | 6 +- .../genericsystem/cv/retriever/DocField.java | 8 +- .../genericsystem/cv/retriever/DocFields.java | 6 +- .../org/genericsystem/cv/retriever/Field.java | 7 +- .../genericsystem/cv/retriever/Fields.java | 65 ++++++------ .../genericsystem/cv/utils/ModelTools.java | 17 ++++ .../cv/utils/RectToolsMapper.java | 98 ++----------------- 9 files changed, 102 insertions(+), 163 deletions(-) diff --git a/gs-cv/src/main/java/org/genericsystem/cv/newmodel/FillNewModelWithData.java b/gs-cv/src/main/java/org/genericsystem/cv/newmodel/FillNewModelWithData.java index 79d1e085b..2d8fbeb52 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/newmodel/FillNewModelWithData.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/newmodel/FillNewModelWithData.java @@ -40,8 +40,9 @@ import org.genericsystem.cv.utils.ImgFunction; import org.genericsystem.cv.utils.ModelTools; import org.genericsystem.cv.utils.NativeLibraryLoader; +import org.genericsystem.cv.utils.RectToolsMapper; import org.genericsystem.kernel.Engine; -import org.opencv.core.Rect; +import org.genericsystem.reinforcer.tools.GSRect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,7 +117,7 @@ public static boolean registerNewFile(Root engine, Path relativeImgPath, Path ba public static JsonObject detectFields(Path imgPath) { try (Img deskewed = new Img(imgPath.toString())) { - List rects = ClassifierUsingFields.detectRects(deskewed); + List rects = RectToolsMapper.rectToGSRect(ClassifierUsingFields.detectRects(deskewed)); DocFields fields = DocFields.of(rects); JsonObject result = fields.toJsonObject(); return result; diff --git a/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractField.java b/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractField.java index 58b64fbc5..3dbbdbe2b 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractField.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractField.java @@ -16,6 +16,8 @@ import org.genericsystem.cv.utils.OCRPlasty.RANSAC; import org.genericsystem.cv.utils.OCRPlasty.Tuple; import org.genericsystem.cv.utils.RectToolsMapper; +import org.genericsystem.reinforcer.tools.GSRect; +import org.genericsystem.reinforcer.tools.RectangleTools; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfPoint2f; @@ -34,7 +36,7 @@ public abstract class AbstractField { protected static final int MIN_SIZE_CONSOLIDATION = 5; private static final int OCR_CONFIDENCE_THRESH = 0; - protected Rect rect; + protected GSRect rect; protected Point center; protected Map labels; protected String consolidated; @@ -44,10 +46,10 @@ public abstract class AbstractField { protected int deadCounter; public AbstractField() { - this(new Rect()); + this(new GSRect()); } - public AbstractField(Rect rect) { + public AbstractField(GSRect rect) { updateRect(rect); this.labels = new HashMap<>(); this.consolidated = null; @@ -65,9 +67,9 @@ public AbstractField(AbstractField other) { this.deadCounter = other.getDeadCounter(); } - void updateRect(Rect rect) { + void updateRect(GSRect rect) { this.rect = rect; - this.center = new Point(rect.x + rect.width / 2, rect.y + rect.height / 2); + this.center = new Point(rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2); } public void ocr(Img rootImg) { @@ -124,7 +126,8 @@ public void drawOcrPerspectiveInverse(Img display, Mat homography, Scalar color, } public void drawRect(Img stabilizedDisplay, Scalar color, int thickness) { - drawRect(stabilizedDisplay, RectToolsMapper.decomposeClockwise(rect), color, thickness); + Point[] points = RectToolsMapper.gsPointToPoint(Arrays.asList(rect.decomposeClockwise())).toArray(new Point[0]); + drawRect(stabilizedDisplay, points, color, thickness); } public void drawRect(Img display, Point[] targets, Scalar color, int thickness) { @@ -146,17 +149,17 @@ public void drawText(Img display, Point[] targets, Scalar color, int thickness) } protected Point[] getRectPointsWithHomography(Mat homography) { - List points = Arrays.asList(RectToolsMapper.decomposeClockwise(rect)); + List points = RectToolsMapper.gsPointToPoint(Arrays.asList(rect.decomposeClockwise())); MatOfPoint2f results = new MatOfPoint2f(); Core.perspectiveTransform(Converters.vector_Point2f_to_Mat(points), results, homography); return results.toArray(); } public Rect getLargeRect(Img imgRoot, double deltaW, double deltaH) { - int adjustW = 3 + Double.valueOf(Math.floor(rect.width * deltaW)).intValue(); - int adjustH = 3 + Double.valueOf(Math.floor(rect.height * deltaH)).intValue(); - Point tl = new Point(rect.tl().x - adjustW > 0 ? rect.tl().x - adjustW : 0, rect.tl().y - adjustH > 0 ? rect.tl().y - adjustH : 0); - Point br = new Point(rect.br().x + adjustW > imgRoot.width() ? imgRoot.width() : rect.br().x + adjustW, rect.br().y + adjustH > imgRoot.height() ? imgRoot.height() : rect.br().y + adjustH); + int adjustW = 3 + Double.valueOf(Math.floor(rect.getWidth() * deltaW)).intValue(); + int adjustH = 3 + Double.valueOf(Math.floor(rect.getHeight() * deltaH)).intValue(); + Point tl = new Point(rect.tl().getX() - adjustW > 0 ? rect.tl().getX() - adjustW : 0, rect.tl().getY() - adjustH > 0 ? rect.tl().getY() - adjustH : 0); + Point br = new Point(rect.br().getX() + adjustW > imgRoot.width() ? imgRoot.width() : rect.br().getX() + adjustW, rect.br().getY() + adjustH > imgRoot.height() ? imgRoot.height() : rect.br().getY() + adjustH); return new Rect(tl, br); } @@ -164,8 +167,8 @@ public boolean contains(Point center) { return Math.sqrt(Math.pow(this.center.x - center.x, 2) + Math.pow(this.center.y - center.y, 2)) <= 10; } - public boolean isOverlapping(Rect otherRect) { - return RectToolsMapper.isOverlapping(this.rect, otherRect); + public boolean isOverlapping(GSRect otherRect) { + return this.rect.isOverlapping(otherRect); } public boolean isOverlapping(AbstractField other) { @@ -173,19 +176,19 @@ public boolean isOverlapping(AbstractField other) { } public boolean isIn(AbstractField other) { - return RectToolsMapper.getInsider(rect, other.getRect()).map(r -> r.equals(rect) ? true : false).orElse(false); + return rect.getInsider(other.getRect()).map(r -> r.equals(rect) ? true : false).orElse(false); } - public boolean overlapsMoreThanThresh(Rect otherRect, double overlapThreshold) { - return RectToolsMapper.inclusiveArea(this.rect, otherRect) > overlapThreshold; + public boolean overlapsMoreThanThresh(GSRect otherRect, double overlapThreshold) { + return this.rect.inclusiveArea(otherRect) > overlapThreshold; } - public boolean isClusteredWith(Rect otherRect, double epsilon) { - return RectToolsMapper.isInCluster(this.rect, otherRect, epsilon); + public boolean isClusteredWith(GSRect otherRect, double epsilon) { + return RectangleTools.isInCluster(this.rect, otherRect, epsilon); } - public boolean isClusteredWith(Rect otherRect, double epsilon, int sides) { - return RectToolsMapper.isInCluster(this.rect, otherRect, epsilon, sides); + public boolean isClusteredWith(GSRect otherRect, double epsilon, int sides) { + return RectangleTools.isInCluster(this.rect, otherRect, epsilon, sides); } public boolean overlapsMoreThanThresh(AbstractField other, double overlapThreshold) { @@ -193,18 +196,14 @@ public boolean overlapsMoreThanThresh(AbstractField other, double overlapThresho } public boolean isOnDisplay(Img display) { - Rect imgRect = new Rect(0, 0, display.width(), display.height()); - return RectToolsMapper.isOverlapping(imgRect, this.rect); + GSRect imgRect = new GSRect(0, 0, display.width(), display.height()); + return imgRect.isOverlapping(this.rect); } public boolean isConsolidated() { return consolidated != null; } - // public boolean needOcr() { - // return ThreadLocalRandom.current().nextBoolean(); - // } - public void incrementDeadCounter() { deadCounter++; } @@ -233,7 +232,7 @@ public Point getCenter() { return center; } - public Rect getRect() { + public GSRect getRect() { return rect; } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractFields.java b/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractFields.java index d95a47d6c..11f25e59d 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractFields.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/retriever/AbstractFields.java @@ -7,9 +7,9 @@ import java.util.stream.Stream; import org.genericsystem.cv.Img; +import org.genericsystem.reinforcer.tools.GSRect; import org.opencv.core.Mat; import org.opencv.core.Point; -import org.opencv.core.Rect; import org.opencv.core.Scalar; public abstract class AbstractFields implements Iterable { @@ -35,12 +35,12 @@ protected List findClusteredFields(F field, double epsilon) { return fields.stream().filter(f -> f.isClusteredWith(field.getRect(), epsilon)).collect(Collectors.toList()); } - protected List findPossibleMatches(Rect rect, double epsilon) { + protected List findPossibleMatches(GSRect rect, double epsilon) { return fields.stream().filter(f -> f.isClusteredWith(rect, epsilon)).collect(Collectors.toList()); } // like findPossibleMatches(Rect, double) but will match only a number of sides (e.g., 3 instead of 4 sides) - protected List findPossibleMatches(Rect rect, double epsilon, int sides) { + protected List findPossibleMatches(GSRect rect, double epsilon, int sides) { return fields.stream().filter(f -> f.isClusteredWith(rect, epsilon, sides)).collect(Collectors.toList()); } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocField.java b/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocField.java index c469e6a9b..b6f0ecb14 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocField.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocField.java @@ -4,9 +4,9 @@ import org.genericsystem.cv.Img; import org.genericsystem.cv.utils.ModelTools; +import org.genericsystem.reinforcer.tools.GSRect; import org.opencv.core.Core; import org.opencv.core.Point; -import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.imgproc.Imgproc; @@ -18,14 +18,14 @@ public DocField() { super(); } - public DocField(int num, Rect rect) { + public DocField(int num, GSRect rect) { super(rect); this.num = num; this.uid = ModelTools.generateZoneUID(rect); } public void writeNum(Img img, String text, double fontScale, Scalar color, int thickness) { - Imgproc.putText(img.getSrc(), text, new Point(rect.tl().x, rect.br().y), Core.FONT_HERSHEY_PLAIN, fontScale, color, thickness); + Imgproc.putText(img.getSrc(), text, new Point(rect.tl().getX(), rect.br().getY()), Core.FONT_HERSHEY_PLAIN, fontScale, color, thickness); } public void annotateImage(Img annotated, double fontScale, Scalar color, int thickness) { @@ -45,7 +45,7 @@ public String getUid() { // The private setters are needed by Jackson to serialize/de-serialize the JSON objects - protected void setRect(Rect rect) { + protected void setRect(GSRect rect) { updateRect(rect); this.uid = ModelTools.generateZoneUID(rect); } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocFields.java b/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocFields.java index 4c52a2096..4aa69444c 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocFields.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/retriever/DocFields.java @@ -8,7 +8,7 @@ import org.genericsystem.cv.Img; import org.genericsystem.cv.utils.ParallelTasks; -import org.opencv.core.Rect; +import org.genericsystem.reinforcer.tools.GSRect; import org.opencv.core.Scalar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ public DocFields(List fields) { super(fields); } - public static DocFields of(List rects) { + public static DocFields of(List rects) { DocFields fields = new DocFields(); fields.buildFields(rects); return fields; @@ -56,7 +56,7 @@ public JsonObject toJsonObject() { return new JsonObject().put(FIELDS, fields); } - public void buildFields(List rects) { + public void buildFields(List rects) { int[] counter = new int[] { 0 }; fields = rects.stream().map(rect -> new DocField(counter[0]++, rect)).collect(Collectors.toList()); } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/retriever/Field.java b/gs-cv/src/main/java/org/genericsystem/cv/retriever/Field.java index 0d6580c33..baa259c60 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/retriever/Field.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/retriever/Field.java @@ -9,9 +9,8 @@ import java.util.stream.Collectors; import org.genericsystem.cv.Img; -import org.genericsystem.cv.utils.RectToolsMapper; +import org.genericsystem.reinforcer.tools.GSRect; import org.opencv.core.Mat; -import org.opencv.core.Rect; import org.opencv.core.Scalar; public class Field extends AbstractField { @@ -24,7 +23,7 @@ public class Field extends AbstractField { private static final double CONFIDENCE_THRESHOLD = 0.92; private boolean locked = false; - public Field(Rect rect) { + public Field(GSRect rect) { super(rect); this.parent = null; this.children = new HashSet<>(); @@ -95,7 +94,7 @@ public boolean removeChild(Field child) { } public boolean containsChild(Field field) { - return children.stream().anyMatch(child -> RectToolsMapper.inclusiveArea(child.getRect(), field.getRect()) > 0.95); + return children.stream().anyMatch(child -> child.getRect().inclusiveArea(field.getRect()) > 0.95); } public boolean addChildren(Collection children) { diff --git a/gs-cv/src/main/java/org/genericsystem/cv/retriever/Fields.java b/gs-cv/src/main/java/org/genericsystem/cv/retriever/Fields.java index eabde38cc..ab1340d0a 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/retriever/Fields.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/retriever/Fields.java @@ -19,10 +19,12 @@ import org.genericsystem.cv.utils.Ransac; import org.genericsystem.cv.utils.Ransac.Model; import org.genericsystem.cv.utils.RectToolsMapper; +import org.genericsystem.reinforcer.tools.GSPoint; +import org.genericsystem.reinforcer.tools.GSRect; +import org.genericsystem.reinforcer.tools.RectangleTools; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Point; -import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.utils.Converters; import org.slf4j.Logger; @@ -64,14 +66,14 @@ public void displayFieldsTree() { public void merge(RectDetector rectDetector) { // Get the lists of rectangles - List rects = rectDetector.getFilteredRects(1d); - List children = rectDetector.getFilteredRects2(1d); + List rects = RectToolsMapper.rectToGSRect(rectDetector.getFilteredRects(1d)); + List children = RectToolsMapper.rectToGSRect(rectDetector.getFilteredRects2(1d)); // Remove the duplicates of rects in children rects.forEach(rect -> { - Iterator it = children.iterator(); + Iterator it = children.iterator(); while (it.hasNext()) { - if (RectToolsMapper.isInCluster(rect, it.next(), 0.1)) + if (RectangleTools.isInCluster(rect, it.next(), 0.1)) it.remove(); } }); @@ -80,7 +82,7 @@ public void merge(RectDetector rectDetector) { fields.forEach(f -> f.incrementDeadCounter()); // Loop over all the rectangles and try to find any matching field - for (Rect rect : rects) { + for (GSRect rect : rects) { List matches = findPossibleMatches(rect, 0.1); matches = cleanMatches(matches, rect); if (!matches.isEmpty()) { @@ -106,21 +108,21 @@ public void merge(RectDetector rectDetector) { adjustUnmergedParents(); } - public static double[] getShift(Rect oldRect, Rect newRect) { - double tlX = newRect.tl().x - oldRect.tl().x; - double tlY = newRect.tl().y - oldRect.tl().y; - double brX = newRect.br().x - oldRect.br().x; - double brY = newRect.br().y - oldRect.br().y; + public static double[] getShift(GSRect oldRect, GSRect newRect) { + double tlX = newRect.tl().getX() - oldRect.tl().getX(); + double tlY = newRect.tl().getY() - oldRect.tl().getY(); + double brX = newRect.br().getX() - oldRect.br().getX(); + double brY = newRect.br().getY() - oldRect.br().getY(); return new double[] { tlX, tlY, brX, brY }; } - public void mergeChildren(List children) { - List fieldsRects = fields.stream().map(f -> f.getRect()).collect(Collectors.toList()); + public void mergeChildren(List children) { + List fieldsRects = fields.stream().map(f -> f.getRect()).collect(Collectors.toList()); for (int i = 0; i < fieldsRects.size(); ++i) { Field parent = fields.get(i); - Rect rect = fieldsRects.get(i); + GSRect rect = fieldsRects.get(i); - List possibleChildren = findChildren(children, rect); + List possibleChildren = findChildren(children, rect); if (!possibleChildren.isEmpty()) { logger.warn("Found possible child(ren) for {}: {}", rect, possibleChildren); possibleChildren.forEach(childRect -> { @@ -161,10 +163,10 @@ private void adjustUnmergedParents() { System.err.println("unable to compute ransac, using mean instead"); } } - Rect rect = field.getRect(); - Point tl = new Point(rect.tl().x - mean[0], rect.tl().y - mean[1]); - Point br = new Point(rect.br().x - mean[2], rect.br().y - mean[3]); - field.updateRect(new Rect(tl, br)); + GSRect rect = field.getRect(); + GSPoint tl = new GSPoint(rect.tl().getX() - mean[0], rect.tl().getY() - mean[1]); + GSPoint br = new GSPoint(rect.br().getX() - mean[2], rect.br().getY() - mean[3]); + field.updateRect(new GSRect(tl, br)); System.out.println("updated rect from " + rect + " to " + field.getRect()); field.clearShifts(); } else @@ -298,8 +300,8 @@ public void removeOverlaps() { } } - private String formatLog(Field field, Rect rect) { - double mergeArea = RectToolsMapper.inclusiveArea(field.getRect(), rect); + private String formatLog(Field field, GSRect rect) { + double mergeArea = field.getRect().inclusiveArea(rect); StringBuffer sb = new StringBuffer(); sb.append(String.format("Merging %s with %s (%.1f%% common area)", field.getRect(), rect, mergeArea * 100)); if (field.getConsolidated() != null) @@ -307,15 +309,15 @@ private String formatLog(Field field, Rect rect) { return sb.toString(); } - private List findChildren(List children, Rect putativeParent) { + private List findChildren(List children, GSRect putativeParent) { double minArea = 0.95; - return children.stream().filter(child -> RectToolsMapper.commonArea(child, putativeParent)[0] > minArea).collect(Collectors.toList()); + return children.stream().filter(child -> RectangleTools.commonArea(child, putativeParent)[0] > minArea).collect(Collectors.toList()); } - private List cleanMatches(List matches, Rect rect) { + private List cleanMatches(List matches, GSRect rect) { List copy = new ArrayList<>(matches); // Remove the false positives - copy = copy.stream().filter(f -> RectToolsMapper.inclusiveArea(f.getRect(), rect) > MIN_OVERLAP / 10).collect(Collectors.toList()); + copy = copy.stream().filter(f -> f.getRect().inclusiveArea(rect) > MIN_OVERLAP / 10).collect(Collectors.toList()); if (copy.isEmpty()) { return Collections.emptyList(); } else { @@ -323,12 +325,12 @@ private List cleanMatches(List matches, Rect rect) { if (copy.size() > 1) { logger.info("Multiple matches ({}), removing false positives", copy.size()); // Remove the overlaps with less than 10% common area - copy = copy.stream().filter(f -> RectToolsMapper.inclusiveArea(f.getRect(), rect) >= MIN_OVERLAP).collect(Collectors.toList()); + copy = copy.stream().filter(f -> f.getRect().inclusiveArea(rect) >= MIN_OVERLAP).collect(Collectors.toList()); if (copy.size() > 1) { logger.warn("Still multiple matches ({}), selecting the maximum overlap", copy.size()); copy = Arrays.asList(copy.stream().max((f1, f2) -> { - double area1 = RectToolsMapper.inclusiveArea(f1.getRect(), rect); - double area2 = RectToolsMapper.inclusiveArea(f2.getRect(), rect); + double area1 = f1.getRect().inclusiveArea(rect); + double area2 = f2.getRect().inclusiveArea(rect); return Double.compare(area1, area2); }).orElseThrow(IllegalStateException::new)); } @@ -344,9 +346,10 @@ public void restabilizeFields(Mat homography) { logger.info("Restabilized {} fields in {} ms", fields.size(), String.format("%.3f", ((double) (stop - start)) / 1_000_000)); } - private Rect findNewRect(Rect rect, Mat homography) { - List points = restabilize(Arrays.asList(rect.tl(), rect.br()), homography); - return new Rect(points.get(0), points.get(1)); + private GSRect findNewRect(GSRect rect, Mat homography) { + List originals = RectToolsMapper.gsPointToPoint(Arrays.asList(rect.tl(), rect.br())); + List points = RectToolsMapper.pointToGSPoint(restabilize(originals, homography)); + return new GSRect(points.get(0), points.get(1)); } private List restabilize(List originals, Mat homography) { diff --git a/gs-cv/src/main/java/org/genericsystem/cv/utils/ModelTools.java b/gs-cv/src/main/java/org/genericsystem/cv/utils/ModelTools.java index 1ac02668c..77d9d46e2 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/utils/ModelTools.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/utils/ModelTools.java @@ -18,6 +18,7 @@ import org.apache.commons.io.FilenameUtils; import org.genericsystem.cv.Zone; +import org.genericsystem.reinforcer.tools.GSRect; import org.opencv.core.Rect; /** @@ -219,4 +220,20 @@ public static String generateZoneUID(Rect rect) { } } + /** + * Generate a unique ID for a given {@link GSRect}. + * + * @param rect - the {@link GSRect} for which a label has to be generated + * @return a String representing the rectangle's unique ID + */ + public static String generateZoneUID(GSRect rect) { + try { + byte[] bytes = rect.toString().getBytes(Charset.forName("UTF8")); + String zoneUID = ModelTools.getHashFromBytes(bytes, "sha-256"); + return zoneUID; + } catch (RuntimeException e) { + throw new RuntimeException("An error has occured during the generation of the hashcode from zone", e); + } + } + } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/utils/RectToolsMapper.java b/gs-cv/src/main/java/org/genericsystem/cv/utils/RectToolsMapper.java index 61d4870b3..b0afbd15d 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/utils/RectToolsMapper.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/utils/RectToolsMapper.java @@ -1,21 +1,18 @@ package org.genericsystem.cv.utils; -import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import org.genericsystem.reinforcer.tools.GSPoint; import org.genericsystem.reinforcer.tools.GSRect; import org.genericsystem.reinforcer.tools.RectangleTools; -import org.genericsystem.reinforcer.tools.RectangleTools.MERGE_METHOD; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Size; /** - * This is an adaptater class for gs-reinforcer {@link RectangleTools}, that accept of OpenCV's {@link Rect}, {@link Point} and {@link Size}. + * This is an adapter class for gs-reinforcer {@link RectangleTools}, that provides translation between OpenCV's {@link Rect}, {@link Point} and {@link Size} and their GS counterparts. * * @author Pierrik Lassalas */ @@ -42,97 +39,20 @@ private static GSPoint convert(Point point) { return new GSPoint(point.x, point.y); } - public static List groupRectangles(List input, MERGE_METHOD method) { - List rects = input.stream().map(rectToGSRect).collect(Collectors.toList()); - List result = RectangleTools.groupRectangles(rects, method); - return result.stream().map(gsRectToRect).collect(Collectors.toList()); + public static List gsRectToRect(List gsRects) { + return gsRects.stream().map(gsRectToRect).collect(Collectors.toList()); } - public static List groupRectangles(List input, double eps, double groupThreshold, MERGE_METHOD method) { - List rects = input.stream().map(rectToGSRect).collect(Collectors.toList()); - List result = RectangleTools.groupRectangles(rects, eps, groupThreshold, method); - return result.stream().map(gsRectToRect).collect(Collectors.toList()); + public static List rectToGSRect(List rects) { + return rects.stream().map(rectToGSRect).collect(Collectors.toList()); } - public static List> cluster(List input, double eps) { - List rects = input.stream().map(rectToGSRect).collect(Collectors.toList()); - List> result = RectangleTools.cluster(rects, eps); - return result.stream().map(list -> (List) list.stream().map(gsRectToRect).collect(Collectors.toList())).collect(Collectors.toList()); + public static List gsPointToPoint(List gsPoints) { + return gsPoints.stream().map(gsPointToPoint).collect(Collectors.toList()); } - public static boolean isInCluster(Rect rect1, Rect rect2, double eps) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - return RectangleTools.isInCluster(r1, r2, eps); - } - - public static boolean isInCluster(Rect rect1, Rect rect2, double eps, int sides) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - return RectangleTools.isInCluster(r1, r2, eps, sides); - } - - public static double[] commonArea(Rect rect1, Rect rect2) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - return RectangleTools.commonArea(r1, r2); - } - - public static double inclusiveArea(Rect rect1, Rect rect2) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - return r1.inclusiveArea(r2); - } - - public static Optional getIntersection(Rect rect1, Rect rect2) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - Optional optional = r1.getIntersection(r2); - return optional.map(gsRectToRect); - } - - public static Rect getUnion(Rect rect1, Rect rect2) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - GSRect result = r1.getUnion(r2); - return convert(result); - } - - public static Rect getMean(List rects) { - List rectangles = rects.stream().map(rectToGSRect).collect(Collectors.toList()); - GSRect result = RectangleTools.getMean(rectangles); - return convert(result); - } - - public static boolean isOverlapping(Rect rect1, Rect rect2) throws IllegalArgumentException { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - return r1.isOverlapping(r2); - } - - public static Optional getInsider(Rect rect1, Rect rect2) { - GSRect r1 = convert(rect1); - GSRect r2 = convert(rect2); - Optional optional = r1.getInsider(r2); - return optional.map(gsRectToRect); - } - - public static boolean contains(Rect rect, Point point) { - GSRect r = convert(rect); - GSPoint p = convert(point); - return r.contains(p); - } - - public static Point[] decomposeClockwise(Rect rect) { - GSRect r = convert(rect); - List points = Arrays.asList(r.decomposeClockwise()); - return points.stream().map(gsPointToPoint).toArray(Point[]::new); - } - - public static List nonMaximumSuppression(List boxes, double overlapThreshold) { - List rectangles = boxes.stream().map(rectToGSRect).collect(Collectors.toList()); - List results = RectangleTools.nonMaximumSuppression(rectangles, overlapThreshold); - return results.stream().map(gsRectToRect).collect(Collectors.toList()); + public static List pointToGSPoint(List points) { + return points.stream().map(pointToGSPoint).collect(Collectors.toList()); } }