From f0261d925901abbe669bf973b31fe10eb324844a Mon Sep 17 00:00:00 2001 From: Nicolas Feybesse Date: Mon, 12 Feb 2018 08:04:01 +0100 Subject: [PATCH] Refactoring --- .../cv/application/GraphicApp.java | 14 ++-- .../cv/application/ReferenceManager.java | 53 +++++++------ .../cv/application/SuperFrameImg.java | 2 +- .../TextOrientationLinesDetector.java | 76 +++++++++++++------ 4 files changed, 87 insertions(+), 58 deletions(-) diff --git a/gs-cv/src/main/java/org/genericsystem/cv/application/GraphicApp.java b/gs-cv/src/main/java/org/genericsystem/cv/application/GraphicApp.java index 6561d1443..e7a9eb85c 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/application/GraphicApp.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/application/GraphicApp.java @@ -186,15 +186,15 @@ private Image[] doWork() { SuperTemplate superReferenceTemplate4 = new SuperTemplate(superDeperspectived, CvType.CV_8UC3, SuperFrameImg::getFrame); List horizontals = detectedSuperContoursCopy.stream().filter(SuperTemplate.VERTICAL_FILTER).collect(Collectors.toList()); horizontals.stream().forEach(c -> Imgproc.line(superReferenceTemplate4.getDisplay().getSrc(), c.left, c.right, new Scalar(255, 255, 255), 1)); - // horizontals.stream().map(sc -> sc.center).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(255, 0, 0), -1)); - // horizontals.stream().map(sc -> sc.left).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 255, 0), -1)); - // horizontals.stream().map(sc -> sc.right).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 0, 255), -1)); + horizontals.stream().map(sc -> sc.center).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(255, 0, 0), -1)); + horizontals.stream().map(sc -> sc.left).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 255, 0), -1)); + horizontals.stream().map(sc -> sc.right).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 0, 255), -1)); - List verticals = detectedSuperContoursCopy = detectedSuperContoursCopy.stream().filter(SuperTemplate.HORIZONTAL_FILTER).collect(Collectors.toList()); + List verticals = detectedSuperContoursCopy.stream().filter(SuperTemplate.HORIZONTAL_FILTER).collect(Collectors.toList()); verticals.stream().forEach(c -> Imgproc.line(superReferenceTemplate4.getDisplay().getSrc(), c.left, c.right, new Scalar(255, 255, 255), 1)); - // verticals.stream().map(sc -> sc.center).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(255, 0, 0), -1)); - // verticals.stream().map(sc -> sc.left).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 255, 0), -1)); - // verticals.stream().map(sc -> sc.right).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 0, 255), -1)); + verticals.stream().map(sc -> sc.center).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(255, 0, 0), -1)); + verticals.stream().map(sc -> sc.left).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 255, 0), -1)); + verticals.stream().map(sc -> sc.right).forEach(pt -> Imgproc.circle(superReferenceTemplate4.getDisplay().getSrc(), pt, 3, new Scalar(0, 0, 255), -1)); images[8] = superReferenceTemplate4.getDisplay().toJfxImage(); diff --git a/gs-cv/src/main/java/org/genericsystem/cv/application/ReferenceManager.java b/gs-cv/src/main/java/org/genericsystem/cv/application/ReferenceManager.java index 272be97d9..eeef047b2 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/application/ReferenceManager.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/application/ReferenceManager.java @@ -1,5 +1,13 @@ package org.genericsystem.cv.application; +import org.opencv.core.Core; +import org.opencv.core.CvType; +import org.opencv.core.Mat; +import org.opencv.core.Point; +import org.opencv.core.Rect; +import org.opencv.core.Size; +import org.opencv.utils.Converters; + import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -10,14 +18,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; -import org.opencv.core.Core; -import org.opencv.core.CvType; -import org.opencv.core.Mat; -import org.opencv.core.Point; -import org.opencv.core.Rect; -import org.opencv.core.Size; -import org.opencv.utils.Converters; - public class ReferenceManager { private static final Mat IDENTITY_MAT = Mat.eye(new Size(3, 3), CvType.CV_64F); @@ -62,7 +62,7 @@ public void submit(ImgDescriptor newImgDescriptor, List detectedrects) { bestImgDescriptor = reference; } else { int reconciliationTries = 0; - List list = getRandomPool(lastStored, reference); + List list = getRandomPool(lastStored, reference); Random randomGenerator = new Random(); while (!list.isEmpty() && reconciliationTries < 5) { ImgDescriptor randomImgDescriptor = list.get(randomGenerator.nextInt(list.size())); @@ -139,23 +139,23 @@ private void updateReference() { } private ImgDescriptor findConsensualDescriptor() { - // double bestDistance = Double.MAX_VALUE; - // ImgDescriptor bestDescriptor = null; - // for (Entry entry : toReferenceGraphy.entrySet()) { - // double distance = 0; - // for (Entry entry2 : toReferenceGraphy.entrySet()) { - // if (!entry.getKey().equals(entry2.getKey())) { - // Mat betweenHomography = new Mat(); - // Core.gemm(entry.getValue(), entry2.getValue().inv(), 1, new Mat(), 0, betweenHomography); - // distance += distance(betweenHomography); - // } - // } - // if (distance < bestDistance) { - // bestDistance = distance; - // bestDescriptor = entry.getKey(); - // } - // } - // return bestDescriptor; + // double bestDistance = Double.MAX_VALUE; + // ImgDescriptor bestDescriptor = null; + // for (Entry entry : toReferenceGraphy.entrySet()) { + // double distance = 0; + // for (Entry entry2 : toReferenceGraphy.entrySet()) { + // if (!entry.getKey().equals(entry2.getKey())) { + // Mat betweenHomography = new Mat(); + // Core.gemm(entry.getValue(), entry2.getValue().inv(), 1, new Mat(), 0, betweenHomography); + // distance += distance(betweenHomography); + // } + // } + // if (distance < bestDistance) { + // bestDistance = distance; + // bestDescriptor = entry.getKey(); + // } + // } + // return bestDescriptor; double minArea = Double.MAX_VALUE; ImgDescriptor bestDescriptor = null; @@ -187,7 +187,6 @@ public Rect rescale(Rect rect, double ratio) { return new Rect((int) (rect.x * ratio), (int) (rect.y * ratio), (int) (rect.width * ratio), (int) (rect.height * ratio)); } - private List transpose(List rects, double minX, double minY) { return rects.stream().map(r -> transpose(r, minX, minY)).collect(Collectors.toList()); } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/application/SuperFrameImg.java b/gs-cv/src/main/java/org/genericsystem/cv/application/SuperFrameImg.java index e6f2ad9fe..a3c21e355 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/application/SuperFrameImg.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/application/SuperFrameImg.java @@ -264,7 +264,7 @@ public Img getGrayFrame() { private Img buildDiffFrame() { Mat diffFrame = getGrayFrame().gaussianBlur(new Size(5, 5)).getSrc(); - Core.absdiff(diffFrame, new Scalar(0), diffFrame); + Core.absdiff(diffFrame, new Scalar(150), diffFrame); Imgproc.adaptiveThreshold(diffFrame, diffFrame, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 7, 3); return new Img(diffFrame, false);// .cleanTablesInv(0.05); } diff --git a/gs-cv/src/main/java/org/genericsystem/cv/application/TextOrientationLinesDetector.java b/gs-cv/src/main/java/org/genericsystem/cv/application/TextOrientationLinesDetector.java index f9698a0d8..3a1ee1938 100644 --- a/gs-cv/src/main/java/org/genericsystem/cv/application/TextOrientationLinesDetector.java +++ b/gs-cv/src/main/java/org/genericsystem/cv/application/TextOrientationLinesDetector.java @@ -1,12 +1,5 @@ package org.genericsystem.cv.application; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.BiFunction; - import org.genericsystem.cv.Img; import org.genericsystem.cv.Lines.Line; import org.genericsystem.cv.lm.LevenbergImpl; @@ -21,11 +14,18 @@ import org.opencv.core.Size; import org.opencv.imgproc.Imgproc; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; + public class TextOrientationLinesDetector { static List getTextOrientationLines(SuperFrameImg superFrame) { - List circles = detectCircles(superFrame, 30, 100); - Collection selectedCircles = selectRandomCirles(circles, 20); + List circles = detectCircles(superFrame.getDiffFrame(), 50, 30, 100); + Collection selectedCircles = selectRandomObjects(circles, 30); List result = new ArrayList<>(); for (Circle circle : selectedCircles) { Img circledImg = getCircledImg(superFrame, (int) circle.radius, circle.center); @@ -33,37 +33,63 @@ static List getTextOrientationLines(SuperFrameImg superFrame) { result.add(buildLine(circle.center, angle, circle.radius)); Imgproc.circle(superFrame.getDisplay().getSrc(), circle.center, (int) circle.radius, new Scalar(0, 255, 0), 1); } + + // List rects = detectRects(superFrame.getDiffFrame(), 50, 60, 200, 10, 50); + // Collection selectedRects = selectRandomObjects(rects, 30); + // List result2 = new ArrayList<>(); + // for (Rect rect : selectedRects) { + // Img rectImg = getRectImg(superFrame, rect); + // double angle = getBestAngle(rectImg, 42, 12, 5, 192, null) / 180 * Math.PI; + // result2.add(buildLine(new Point(rect.tl().x + rect.width / 2, rect.tl().y + rect.height / 2), angle, rect.width / 2)); + // Imgproc.rectangle(superFrame.getDisplay().getSrc(), rect.tl(), rect.br(), new Scalar(0, 0, 255), 1); + // } + // return result2; return result; } - private static List detectCircles(SuperFrameImg superFrame, int minRadius, int maxRadius) { + private static List getContours(Img img) { List contours = new ArrayList<>(); - Imgproc.findContours(superFrame.getDiffFrame().getSrc(), contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); + Imgproc.findContours(img.getSrc(), contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); + return contours; + } + + private static List detectCircles(Img img, int maxContourArea, int minRadius, int maxRadius) { + List contours = getContours(img); List circles = new ArrayList<>(); - for (int i = 0; i < contours.size(); i++) { - MatOfPoint contour = contours.get(i); + for (MatOfPoint contour : contours) { double contourarea = Imgproc.contourArea(contour); if (contourarea > 50) { float[] radius = new float[1]; Point center = new Point(); MatOfPoint2f contour2F = new MatOfPoint2f(contour.toArray()); Imgproc.minEnclosingCircle(contour2F, center, radius); - if (radius[0] > minRadius && radius[0] < maxRadius && center.x > radius[0] && center.y > radius[0] && ((center.x + radius[0]) < superFrame.width()) && ((center.y + radius[0]) < superFrame.height())) { + if (radius[0] > minRadius && radius[0] < maxRadius && center.x > radius[0] && center.y > radius[0] && ((center.x + radius[0]) < img.width()) && ((center.y + radius[0]) < img.height())) circles.add(new Circle(center, radius[0])); - // Imgproc.circle(frame, center, (int) radius[0], new Scalar(0, 0, 255)); - } - // Imgproc.drawContours(superFrame.getDisplay().getSrc(), Arrays.asList(contour), 0, new Scalar(0, 0, 255), 1); } } return circles; } - private static Collection selectRandomCirles(List circles, int circlesNumber) { - if (circles.size() <= circlesNumber) - return circles; - Set result = new HashSet<>(); - while (result.size() < circlesNumber) - result.add(circles.get((int) (Math.random() * circles.size()))); + private static List detectRects(Img img, int maxContourArea, int minWidth, int maxWidth, int minHeight, int maxHeight) { + List contours = getContours(img); + List rects = new ArrayList<>(); + for (MatOfPoint contour : contours) { + double contourarea = Imgproc.contourArea(contour); + if (contourarea > 50) { + Rect rect = Imgproc.boundingRect(contour); + if (rect.width >= minWidth && rect.width <= maxWidth && rect.height >= minHeight && rect.height <= maxHeight) + rects.add(rect); + } + } + return rects; + } + + private static Collection selectRandomObjects(List objects, int maxReturnObjects) { + if (objects.size() <= maxReturnObjects) + return objects; + Set result = new HashSet<>(); + while (result.size() < maxReturnObjects) + result.add(objects.get((int) (Math.random() * objects.size()))); return result; } @@ -78,6 +104,10 @@ private static Img getCircledImg(SuperFrameImg superFrame, int radius, Point cen return circledImg; } + private static Img getRectImg(SuperFrameImg superFrame, Rect rect) { + return new Img(new Mat(superFrame.getBinarized().getSrc(), rect), false); + } + private static Line buildLine(Point center, double angle, double size) { double x1 = center.x - Math.sin(angle) * size; double y1 = center.y + Math.cos(angle) * size;