Skip to content

Commit e06c907

Browse files
authored
Merge pull request #36 from strykeforce/min-area-target
Add min-area rectangle target capability
2 parents 5735820 + 1087529 commit e06c907

File tree

12 files changed

+363
-53
lines changed

12 files changed

+363
-53
lines changed

client/.idea/codeStyles/Project.xml

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package org.strykeforce.deadeye;
2+
3+
import com.squareup.moshi.JsonReader;
4+
import com.squareup.moshi.JsonWriter;
5+
import okio.Buffer;
6+
import okio.BufferedSource;
7+
8+
import java.io.IOException;
9+
import java.util.Arrays;
10+
import java.util.Objects;
11+
12+
public class MinAreaRectTargetData extends TargetData {
13+
14+
static final int DATA_LENGTH = 13;
15+
16+
/**
17+
* Angle of OpenCV rotated rectangle.
18+
*/
19+
final double angle;
20+
/**
21+
* Center of OpenCV rotated rectangle.
22+
*/
23+
final Point2D center;
24+
/**
25+
* Width of OpenCV rotated rectangle.
26+
*/
27+
final double width;
28+
/**
29+
* Height of OpenCV rotated rectangle.
30+
*/
31+
final double height;
32+
/**
33+
* Vertices of OpenCV rotated rectangle.
34+
*/
35+
final Point2D[] points;
36+
37+
public MinAreaRectTargetData() {
38+
this("", 0, false, 0, new Point2D(0, 0), 0, 0, new Point2D[0]);
39+
}
40+
41+
public MinAreaRectTargetData(String id, int serial, boolean valid, double angle,
42+
Point2D center, double width, double height, Point2D[] points) {
43+
super(id, serial, valid);
44+
this.angle = angle;
45+
this.center = center;
46+
this.width = width;
47+
this.height = height;
48+
this.points = points;
49+
}
50+
51+
public double area() {
52+
return width * height;
53+
}
54+
55+
@SuppressWarnings("rawtypes")
56+
@Override
57+
public DeadeyeJsonAdapter getJsonAdapter() {
58+
return new JsonAdapterImpl();
59+
}
60+
61+
@Override
62+
public boolean equals(Object o) {
63+
if (this == o) return true;
64+
if (o == null || getClass() != o.getClass()) return false;
65+
if (!super.equals(o)) return false;
66+
MinAreaRectTargetData that = (MinAreaRectTargetData) o;
67+
return Double.compare(that.angle, angle) == 0 &&
68+
Double.compare(that.width, width) == 0 &&
69+
Double.compare(that.height, height) == 0 &&
70+
center.equals(that.center) &&
71+
Arrays.equals(points, that.points);
72+
}
73+
74+
@Override
75+
public int hashCode() {
76+
int result = Objects.hash(super.hashCode(), angle, center, width, height);
77+
result = 31 * result + Arrays.hashCode(points);
78+
return result;
79+
}
80+
81+
@Override
82+
public String toString() {
83+
return "MinAreaRectTargetData{" +
84+
"angle=" + angle +
85+
", center=" + center +
86+
", width=" + width +
87+
", height=" + height +
88+
", points=" + Arrays.toString(points) +
89+
"} " + super.toString();
90+
}
91+
92+
private static class JsonAdapterImpl implements DeadeyeJsonAdapter<MinAreaRectTargetData> {
93+
94+
// json d field:
95+
// rect.angle,
96+
// rect.center.x,
97+
// rect.center.y,
98+
// rect.size.height,
99+
// rect.size.width,
100+
// corners[0].x,
101+
// corners[0].y,
102+
// corners[1].x,
103+
// corners[1].y,
104+
// corners[2].x,
105+
// corners[2].y,
106+
// corners[3].x,
107+
// corners[3].y,
108+
private static final JsonReader.Options OPTIONS = JsonReader.Options.of("id", "sn", "v",
109+
"d");
110+
111+
@Override
112+
public MinAreaRectTargetData fromJson(BufferedSource source) throws IOException {
113+
JsonReader reader = JsonReader.of(source);
114+
String id = null;
115+
int serial = -1;
116+
boolean valid = false;
117+
double[] data = new double[DATA_LENGTH];
118+
reader.beginObject();
119+
while (reader.hasNext()) {
120+
switch (reader.selectName(OPTIONS)) {
121+
case 0:
122+
id = reader.nextString();
123+
break;
124+
case 1:
125+
serial = reader.nextInt();
126+
break;
127+
case 2:
128+
valid = reader.nextBoolean();
129+
break;
130+
case 3:
131+
reader.beginArray();
132+
for (int i = 0; i < DATA_LENGTH; i++) {
133+
data[i] = reader.nextDouble();
134+
}
135+
reader.endArray();
136+
break;
137+
case -1:
138+
reader.skipName();
139+
reader.skipValue();
140+
break;
141+
default:
142+
throw new IllegalStateException("Unexpected value: " + reader.selectName(OPTIONS));
143+
}
144+
}
145+
reader.endObject();
146+
Point2D center = new Point2D(data[1], data[2]);
147+
Point2D[] points = new Point2D[]{
148+
new Point2D(data[5], data[6]),
149+
new Point2D(data[7], data[8]),
150+
new Point2D(data[9], data[10]),
151+
new Point2D(data[11], data[12]),
152+
};
153+
return new MinAreaRectTargetData(id, serial, valid, data[0], center, data[4], data[3]
154+
, points);
155+
}
156+
157+
@Override
158+
public String toJson(MinAreaRectTargetData targetData) throws IOException {
159+
Buffer buffer = new Buffer();
160+
JsonWriter writer = JsonWriter.of(buffer);
161+
writer.beginObject();
162+
writer.name("id").value(targetData.id);
163+
writer.name("sn").value(targetData.serial);
164+
writer.name("v").value(targetData.valid);
165+
writer.name("d").beginArray();
166+
writer.value(targetData.angle);
167+
writer.value(targetData.center.x).value(targetData.center.y);
168+
writer.value(targetData.height).value(targetData.width);
169+
for (int i = 0; i < 4; i++) {
170+
writer.value(targetData.points[i].x).value(targetData.points[i].y);
171+
}
172+
writer.endArray();
173+
writer.endObject();
174+
return buffer.readUtf8();
175+
}
176+
}
177+
}

client/src/main/java/org/strykeforce/deadeye/Point.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ public boolean equals(Object o) {
3030
if (this == o) return true;
3131
if (o == null || getClass() != o.getClass()) return false;
3232
Point point = (Point) o;
33-
return x == point.x &&
34-
y == point.y;
33+
return x == point.x && y == point.y;
3534
}
3635

3736
@Override
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.strykeforce.deadeye;
2+
3+
import java.util.Objects;
4+
5+
public final class Point2D {
6+
final double x;
7+
final double y;
8+
9+
public Point2D(double x, double y) {
10+
this.x = x;
11+
this.y = y;
12+
}
13+
14+
public double r() {
15+
return Math.sqrt(x * x + y * y);
16+
}
17+
18+
public double theta() {
19+
return Math.atan2(y, x);
20+
}
21+
22+
public double distanceTo(Point that) {
23+
double dx = this.x - that.x;
24+
double dy = this.y - that.y;
25+
return Math.sqrt(dx * dx + dy * dy);
26+
}
27+
28+
@Override
29+
public boolean equals(Object o) {
30+
if (this == o) return true;
31+
if (o == null || getClass() != o.getClass()) return false;
32+
Point2D point = (Point2D) o;
33+
return x == point.x && y == point.y;
34+
}
35+
36+
@Override
37+
public int hashCode() {
38+
return Objects.hash(x, y);
39+
}
40+
41+
@Override
42+
public String toString() {
43+
return "(" + x + ", " + y + ")";
44+
}
45+
}

client/src/main/java/org/strykeforce/deadeye/UprightRectTargetData.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,31 @@ public class UprightRectTargetData extends TargetData {
1313

1414
static final int DATA_LENGTH = 6;
1515

16+
/**
17+
* Bounding box top-left corner point.
18+
*/
1619
final Point topLeft;
20+
/**
21+
* Bounding box bottom-right corner point.
22+
*/
1723
final Point bottomRight;
24+
/**
25+
* Bounding box center.
26+
*/
1827
final Point center;
1928

2029
public UprightRectTargetData() {
21-
this(null, 0, false, null, null, null);
30+
this("", 0, false, new Point(0, 0), new Point(0, 0), new Point(0, 0));
2231
}
2332

24-
public UprightRectTargetData(String id, int serial, boolean valid, Point topLeft, Point bottomRight, Point center) {
33+
public UprightRectTargetData(String id, int serial, boolean valid, Point topLeft,
34+
Point bottomRight, Point center) {
2535
super(id, serial, valid);
2636
this.topLeft = topLeft;
2737
this.bottomRight = bottomRight;
2838
this.center = center;
2939
}
3040

31-
@Override
32-
@SuppressWarnings("rawtypes")
33-
public DeadeyeJsonAdapter getJsonAdapter() {
34-
return new JsonAdapterImpl();
35-
}
36-
3741
public int area() {
3842
return width() * height();
3943
}
@@ -46,6 +50,12 @@ public int height() {
4650
return bottomRight.y - topLeft.y;
4751
}
4852

53+
@Override
54+
@SuppressWarnings("rawtypes")
55+
public DeadeyeJsonAdapter getJsonAdapter() {
56+
return new JsonAdapterImpl();
57+
}
58+
4959
@Override
5060
public boolean equals(Object o) {
5161
if (this == o) return true;
@@ -67,14 +77,15 @@ public String toString() {
6777
return "UprightRectTargetData{" +
6878
"topLeft=" + topLeft +
6979
", bottomRight=" + bottomRight +
70-
", offset=" + center +
80+
", center=" + center +
7181
"} " + super.toString();
7282
}
7383

7484
private static class JsonAdapterImpl implements DeadeyeJsonAdapter<UprightRectTargetData> {
7585

76-
//json d field: bb.tl().x, bb.tl().y, bb.br().x, bb.br().y, center.x, center.y
77-
private static final JsonReader.Options OPTIONS = JsonReader.Options.of("id", "sn", "v", "d");
86+
// json d field: bb.tl().x, bb.tl().y, bb.br().x, bb.br().y, center.x, center.y
87+
private static final JsonReader.Options OPTIONS = JsonReader.Options.of("id", "sn", "v",
88+
"d");
7889

7990
@Override
8091
public UprightRectTargetData fromJson(BufferedSource source) throws IOException {

0 commit comments

Comments
 (0)