Calculate aspect ratio using rotated rect (#447)

This commit is contained in:
Matt
2022-03-31 22:51:14 -04:00
committed by GitHub
parent b80e436f02
commit 971ff3ac40
4 changed files with 42 additions and 8 deletions

View File

@@ -18,6 +18,14 @@
step="0.1"
@input="handlePipelineData('contourRatio')"
/>
<CVselect
v-model="contourTargetOrientation"
name="Target Orientation"
tooltip="Used to determine how to calculate target landmarks, as well as aspect ratio"
:list="['Portrait', 'Landscape']"
@input="handlePipelineData('contourTargetOrientation')"
@rollback="e=> rollback('contourTargetOrientation', e)"
/>
<CVrangeSlider
v-if="currentPipelineType() !== 3"
v-model="contourFullness"
@@ -203,6 +211,14 @@ export default {
this.$store.commit("mutatePipeline", {"contourRatio": val});
}
},
contourTargetOrientation: {
get() {
return this.$store.getters.currentPipelineSettings.contourTargetOrientation
},
set(val) {
this.$store.commit("mutatePipeline", {"contourTargetOrientation": val});
}
},
contourFullness: {
get() {
return this.$store.getters.currentPipelineSettings.contourFullness

View File

@@ -18,16 +18,14 @@
package org.photonvision.vision.pipe.impl;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.opencv.core.Rect;
import org.opencv.core.RotatedRect;
import org.photonvision.common.util.math.MathUtils;
import org.photonvision.common.util.numbers.DoubleCouple;
import org.photonvision.vision.frame.FrameStaticProperties;
import org.photonvision.vision.opencv.Contour;
import org.photonvision.vision.pipe.CVPipe;
import org.photonvision.vision.target.TargetCalculations;
public class FilterContoursPipe
extends CVPipe<List<Contour>, List<Contour>, FilterContoursPipe.FilterContoursParams> {
@@ -114,8 +112,7 @@ public class FilterContoursPipe
if (contourArea <= minFullness || contourArea >= maxFullness) return;
// Aspect Ratio Filtering.
Rect boundingRect = contour.getBoundingRect();
double aspectRatio = (double) boundingRect.width / boundingRect.height;
double aspectRatio = TargetCalculations.getAspectRatio(contour.getMinAreaRect(), params.isLandscape);
if (aspectRatio < params.getRatio().getFirst() || aspectRatio > params.getRatio().getSecond())
return;
@@ -129,6 +126,7 @@ public class FilterContoursPipe
private final FrameStaticProperties m_frameStaticProperties;
private final double xTol; // IQR tolerance for x
private final double yTol; // IQR tolerance for x
public final boolean isLandscape;
public FilterContoursParams(
DoubleCouple area,
@@ -136,13 +134,14 @@ public class FilterContoursPipe
DoubleCouple extent,
FrameStaticProperties camProperties,
double xTol,
double yTol) {
double yTol, boolean isLandscape) {
this.m_area = area;
this.m_ratio = ratio;
this.m_fullness = extent;
this.m_frameStaticProperties = camProperties;
this.xTol = xTol;
this.yTol = yTol;
this.isLandscape = isLandscape;
}
public DoubleCouple getArea() {

View File

@@ -30,6 +30,7 @@ import org.photonvision.vision.pipe.CVPipe.CVPipeResult;
import org.photonvision.vision.pipe.impl.*;
import org.photonvision.vision.pipeline.result.CVPipelineResult;
import org.photonvision.vision.target.PotentialTarget;
import org.photonvision.vision.target.TargetOrientation;
import org.photonvision.vision.target.TrackedTarget;
/** Represents a pipeline for tracking retro-reflective targets. */
@@ -102,7 +103,8 @@ public class ReflectivePipeline extends CVPipeline<CVPipelineResult, ReflectiveP
settings.contourFullness,
frameStaticProperties,
settings.contourFilterRangeX,
settings.contourFilterRangeY);
settings.contourFilterRangeY,
settings.contourTargetOrientation == TargetOrientation.Landscape);
filterContoursPipe.setParams(filterContoursParams);
var groupContoursParams =

View File

@@ -111,6 +111,23 @@ public class TargetCalculations {
}
}
public static double getAspectRatio(RotatedRect rect, boolean isLandscape) {
if (rect.size.width == 0 || rect.size.height == 0) return 0;
double ratio = rect.size.width / rect.size.height;
// In landscape, we should be shorter than we are wide (that is, aspect ratio should be >1)
if (isLandscape && ratio < 1) {
ratio = 1.0 / ratio;
}
// If portrait, should always be taller than wide (ratio < 1)
else if (!isLandscape && ratio > 1) {
ratio = 1.0 / ratio;
}
return ratio;
}
public static Point calculateDualOffsetCrosshair(
DualOffsetValues dualOffsetValues, double currentArea) {
boolean firstLarger = dualOffsetValues.firstPointArea >= dualOffsetValues.secondPointArea;