redone grouped contours and fixed ratio slider

This commit is contained in:
ori agranat
2019-10-04 16:46:16 +03:00
parent b618b7f897
commit 259753e582
3 changed files with 41 additions and 25 deletions

View File

@@ -1,4 +1,6 @@
package com.chameleonvision.Handler;
import org.apache.commons.math3.util.FastMath;
import java.lang.Math;
public class MathHandler {
MathHandler(){}
@@ -12,4 +14,7 @@ public class MathHandler {
}
return ((k / (1 + Math.pow(Math.E,(a + (b * x))))) + bias);
}
public static double toSlope(double angle){
return FastMath.atan(FastMath.toRadians(angle - 90));
}
}

View File

@@ -6,6 +6,8 @@ import org.apache.commons.math3.util.FastMath;
import org.jetbrains.annotations.NotNull;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgproc.Moments;
import java.util.*;
@SuppressWarnings("WeakerAccess")
@@ -20,14 +22,16 @@ public class CVProcess {
put("Quintuple", 5);
}};
private Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
private Size blur = new Size(1,1);
private Mat hsvImage = new Mat();
private List<MatOfPoint> foundContours = new ArrayList<>();
private Mat binaryMat = new Mat();
private List<MatOfPoint> filteredContours = new ArrayList<>();
private Comparator<RotatedRect> sortByCentermostComparator = Comparator.comparingDouble(this::calcDistance);
private Comparator<MatOfPoint> sortByMomentsX = Comparator.comparingDouble(this::calcMomentsX);
private List<RotatedRect> finalCountours = new ArrayList<>();
private Mat intersectMatA = new Mat();
private Mat intersectMatB = new Mat();
private MatOfPoint2f intersectMatA = new MatOfPoint2f();
private MatOfPoint2f intersectMatB = new MatOfPoint2f();
CVProcess(CameraValues cameraValues) {
this.cameraValues = cameraValues;
@@ -35,6 +39,7 @@ public class CVProcess {
void hsvThreshold(Mat srcImage, Mat dst, @NotNull Scalar hsvLower, @NotNull Scalar hsvUpper, boolean shouldErode, boolean shouldDilate) {
Imgproc.cvtColor(srcImage, hsvImage, Imgproc.COLOR_RGB2HSV, 3);
Imgproc.blur(hsvImage, hsvImage, blur);
Core.inRange(hsvImage, hsvLower, hsvUpper, dst);
if (shouldErode) {
Imgproc.erode(dst, dst, kernel);
@@ -57,20 +62,22 @@ public class CVProcess {
for (MatOfPoint Contour : inputContours) {
try {
double contourArea = Imgproc.contourArea(Contour);
double minArea = (MathHandler.sigmoid(area.get(0)) * cameraValues.ImageArea) / 100;
double maxArea = (MathHandler.sigmoid(area.get(1)) * cameraValues.ImageArea) / 100;
if (contourArea <= minArea || contourArea >= maxArea) {
double AreaRatio = (contourArea / cameraValues.ImageArea)*100;
double minArea = (MathHandler.sigmoid(area.get(0)));
double maxArea = (MathHandler.sigmoid(area.get(1)));
if (AreaRatio < minArea || AreaRatio > maxArea) {
continue;
}
var rect = Imgproc.minAreaRect(new MatOfPoint2f(Contour.toArray()));
var targetFullness = contourArea;
double minExtent = (double) (extent.get(0) * rect.size.area())/ 100;
double minExtent = (double) (extent.get(0) * rect.size.area()) / 100;
double maxExtent = (double) (extent.get(1) * rect.size.area()) / 100;
if (targetFullness <= minExtent || contourArea >= maxExtent) {
continue;
}
double aspectRatio = rect.size.width / rect.size.height;//TODO i think aspectRatio is inverted
Rect bb = Imgproc.boundingRect(Contour);
double aspectRatio = (bb.width / bb.height);
if (aspectRatio < ratio.get(0) || aspectRatio > ratio.get(1)) {
continue;
}
@@ -86,7 +93,10 @@ public class CVProcess {
private double calcDistance(RotatedRect rect) {
return FastMath.sqrt(FastMath.pow(cameraValues.CenterX - rect.center.x, 2) + FastMath.pow(cameraValues.CenterY - rect.center.y, 2));
}
private double calcMomentsX(MatOfPoint c){
Moments m = Imgproc.moments(c);
return (m.get_m10()/m.get_m00());
}
RotatedRect sortTargetsToOne(List<RotatedRect> inputRects, String sortMode) {
switch (sortMode) {
case "Largest":
@@ -111,6 +121,7 @@ public class CVProcess {
List<RotatedRect> groupTargets(List<MatOfPoint> inputContours, String intersectionPoint, String targetGroup) {
finalCountours.clear();
if (!targetGroup.equals("Single")) {
inputContours.sort(sortByMomentsX);
for (var i = 0; i < inputContours.size(); i++) {
List<Point> FinalContourList = new ArrayList<>(inputContours.get(i).toList());
for (var c = 0; c < (targetGrouping.get(targetGroup) - 1); c++) {
@@ -157,24 +168,20 @@ public class CVProcess {
return true;
}
try {
Imgproc.fitLine(ContourOne, intersectMatA, Imgproc.CV_DIST_L2, 0, 0.01, 0.01);
Imgproc.fitLine(ContourTwo, intersectMatB, Imgproc.CV_DIST_L2, 0, 0.01, 0.01);
double vxA = intersectMatA.get(0, 0)[0];
double vyA = intersectMatA.get(1, 0)[0];
double x0A = intersectMatA.get(2, 0)[0];
double y0A = intersectMatA.get(3, 0)[0];
double mA = vyA / vxA;
double vxB = intersectMatB.get(0, 0)[0];
double vyB = intersectMatB.get(1, 0)[0];
double x0B = intersectMatB.get(2, 0)[0];
double y0B = intersectMatB.get(3, 0)[0];
double mB = vyB / vxB;
double bA = y0A - (mA*x0A);
double bB = y0B - (mB*x0B);
intersectMatA.fromArray(ContourOne.toArray());
intersectMatB.fromArray(ContourTwo.toArray());
RotatedRect a = Imgproc.fitEllipse(intersectMatA);
RotatedRect b = Imgproc.fitEllipse(intersectMatB);
double mA = MathHandler.toSlope(a.angle);
double mB = MathHandler.toSlope(b.angle);
double x0A = a.center.x;
double y0A = a.center.y;
double x0B = b.center.x;
double y0B = b.center.y;
double intersectionX = ((mA * x0A) - y0A - (mB * x0B) + y0B )/ (mA - mB);
double intersectionY = (mA * (intersectionX - x0A)) + y0A;
double massX = intersectionX + 1;
double massY = intersectionY + ((mA + bA + mB +bB) / 2);
double massX = (x0A + x0B) / 2;
double massY = (y0A + y0B) / 2;
switch (IntersectionPoint) {
case "Up": {
if (intersectionY < massY) {

View File

@@ -37,6 +37,7 @@ public class VisionProcess implements Runnable {
private Mat hsvThreshMat = new Mat();
private Mat streamOutputMat = new Mat();
private Scalar contourRectColor = new Scalar(255, 0, 0);
private Scalar BoxRectColor = new Scalar(0, 0, 233);
private long timeStamp = 0;
public VisionProcess(Camera processCam) {
@@ -103,9 +104,12 @@ public class VisionProcess implements Runnable {
List<MatOfPoint> drawnContour = new ArrayList<>();
Point[] vertices = new Point[4];
contourRect.points(vertices);
drawnContour.add(new MatOfPoint(vertices));
MatOfPoint contour = new MatOfPoint(vertices);
drawnContour.add(contour);
Rect box = Imgproc.boundingRect(contour);
Imgproc.drawContours(inputMat, drawnContour, 0, contourRectColor, 3);
Imgproc.circle(inputMat, contourRect.center, 3, contourRectColor);
Imgproc.rectangle(inputMat,new Point(box.x, box.y), new Point((box.x + box.width),(box.y + box.height)), BoxRectColor,2);
}
private void updateNetworkTables(PipelineResult pipelineResult) {