Skip to content

Commit df3405a

Browse files
committed
Add support for TargetListTargetData
1 parent 4268184 commit df3405a

File tree

7 files changed

+418
-147
lines changed

7 files changed

+418
-147
lines changed

client/.idea/codeStyles/codeStyleConfig.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
import com.squareup.moshi.JsonReader;
44
import com.squareup.moshi.JsonWriter;
5-
import okio.Buffer;
6-
import okio.BufferedSource;
7-
85
import java.io.IOException;
96
import java.util.Arrays;
107
import java.util.Objects;
8+
import okio.Buffer;
9+
import okio.BufferedSource;
10+
import org.jetbrains.annotations.NotNull;
1111

1212
public class MinAreaRectTargetData extends TargetData {
1313

@@ -16,27 +16,27 @@ public class MinAreaRectTargetData extends TargetData {
1616
/** Angle of OpenCV rotated rectangle. */
1717
public final double angle;
1818
/** Center of OpenCV rotated rectangle. */
19-
public final Point2D center;
19+
@NotNull public final Point2D center;
2020
/** Width of OpenCV rotated rectangle. */
2121
public final double width;
2222
/** Height of OpenCV rotated rectangle. */
2323
public final double height;
2424
/** Vertices of OpenCV rotated rectangle. */
25-
public final Point2D[] points;
25+
@NotNull public final Point2D[] points;
2626

2727
public MinAreaRectTargetData() {
2828
this("", 0, false, 0, new Point2D(0, 0), 0, 0, new Point2D[0]);
2929
}
3030

3131
public MinAreaRectTargetData(
32-
String id,
32+
@NotNull String id,
3333
int serial,
3434
boolean valid,
3535
double angle,
36-
Point2D center,
36+
@NotNull Point2D center,
3737
double width,
3838
double height,
39-
Point2D[] points) {
39+
@NotNull Point2D[] points) {
4040
super(id, serial, valid);
4141
this.angle = angle;
4242
this.center = center;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,22 @@ public Point(int x, int y) {
1111
this.y = y;
1212
}
1313

14+
/** Return the center of a bounding box formed by top left and bottom right points. */
15+
public static Point boundingBoxCenterFrom(Point topLeft, Point bottomRight) {
16+
return new Point((topLeft.x + bottomRight.x) / 2, (topLeft.y + bottomRight.y) / 2);
17+
}
18+
19+
/** Polar coordinate radius of this point. */
1420
public double r() {
1521
return Math.sqrt(x * x + y * y);
1622
}
1723

24+
/** Polar coordinate angle of this point. */
1825
public double theta() {
1926
return Math.atan2(y, x);
2027
}
2128

29+
/** Distance to another point. */
2230
public double distanceTo(Point that) {
2331
double dx = this.x - that.x;
2432
double dy = this.y - that.y;

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@
22

33
import com.squareup.moshi.JsonReader;
44
import com.squareup.moshi.JsonWriter;
5-
import okio.Buffer;
6-
import okio.BufferedSource;
7-
85
import java.io.IOException;
96
import java.util.Objects;
7+
import okio.Buffer;
8+
import okio.BufferedSource;
9+
import org.jetbrains.annotations.NotNull;
1010

1111
@SuppressWarnings("unused")
1212
public class TargetData {
1313

14-
public final String id;
14+
/** Deadeye unit ID. */
15+
@NotNull public final String id;
16+
/** Serial number of target data message. */
1517
public final int serial;
18+
/** True if target data is valid. */
1619
public final boolean valid;
1720

1821
public TargetData() {
1922
this(null, 0, false);
2023
}
2124

22-
public TargetData(String id, int serial, boolean valid) {
25+
public TargetData(@NotNull String id, int serial, boolean valid) {
2326
this.id = id;
2427
this.serial = serial;
2528
this.valid = valid;
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package org.strykeforce.deadeye;
2+
3+
import com.squareup.moshi.JsonReader;
4+
import com.squareup.moshi.JsonWriter;
5+
import java.io.IOException;
6+
import java.util.ArrayList;
7+
import java.util.Collections;
8+
import java.util.List;
9+
import java.util.Objects;
10+
import okio.Buffer;
11+
import okio.BufferedSource;
12+
import org.jetbrains.annotations.NotNull;
13+
14+
public class TargetListTargetData extends TargetData {
15+
16+
static final int DATA_LENGTH = 5;
17+
18+
@NotNull public final List<Target> targets;
19+
20+
public TargetListTargetData() {
21+
this("", 0, false, Collections.emptyList());
22+
}
23+
24+
public TargetListTargetData(
25+
@NotNull String id, int serial, boolean valid, @NotNull List<Target> targets) {
26+
super(id, serial, valid);
27+
this.targets = targets;
28+
}
29+
30+
@Override
31+
@SuppressWarnings("rawtypes")
32+
public DeadeyeJsonAdapter getJsonAdapter() {
33+
return new JsonAdapterImpl();
34+
}
35+
36+
@Override
37+
public boolean equals(Object o) {
38+
if (this == o) return true;
39+
if (o == null || getClass() != o.getClass()) return false;
40+
if (!super.equals(o)) return false;
41+
TargetListTargetData that = (TargetListTargetData) o;
42+
return targets.equals(that.targets);
43+
}
44+
45+
@Override
46+
public int hashCode() {
47+
return Objects.hash(super.hashCode(), targets);
48+
}
49+
50+
@Override
51+
public String toString() {
52+
return "TargetListTargetData{" + "targets=" + targets + "} " + super.toString();
53+
}
54+
55+
public static class Target {
56+
/** Bounding box top-left corner point. */
57+
@NotNull public final Point topLeft;
58+
/** Bounding box bottom-right corner point. */
59+
@NotNull public final Point bottomRight;
60+
/** Bounding box center. */
61+
@NotNull public final Point center;
62+
/** Contour area. */
63+
public final int contourArea;
64+
65+
public Target(
66+
@NotNull Point topLeft,
67+
@NotNull Point bottomRight,
68+
@NotNull Point center,
69+
int contourArea) {
70+
this.topLeft = topLeft;
71+
this.bottomRight = bottomRight;
72+
this.center = center;
73+
this.contourArea = contourArea;
74+
}
75+
76+
/** Returns bounding box area. */
77+
public int area() {
78+
return width() * height();
79+
}
80+
81+
/** Returns width of bounding box. */
82+
public int width() {
83+
return bottomRight.x - topLeft.x;
84+
}
85+
86+
/** Returns height of bounding box. */
87+
public int height() {
88+
return bottomRight.y - topLeft.y;
89+
}
90+
91+
@Override
92+
public boolean equals(Object o) {
93+
if (this == o) return true;
94+
if (o == null || getClass() != o.getClass()) return false;
95+
Target target = (Target) o;
96+
return contourArea == target.contourArea
97+
&& topLeft.equals(target.topLeft)
98+
&& bottomRight.equals(target.bottomRight)
99+
&& center.equals(target.center);
100+
}
101+
102+
@Override
103+
public int hashCode() {
104+
return Objects.hash(topLeft, bottomRight, center, contourArea);
105+
}
106+
107+
@Override
108+
public String toString() {
109+
return "Target{"
110+
+ "topLeft="
111+
+ topLeft
112+
+ ", bottomRight="
113+
+ bottomRight
114+
+ ", center="
115+
+ center
116+
+ ", contourArea="
117+
+ contourArea
118+
+ '}';
119+
}
120+
}
121+
122+
private static class JsonAdapterImpl implements DeadeyeJsonAdapter<TargetListTargetData> {
123+
124+
// json d field: bb.tl().x, bb.tl().y, bb.br().x, bb.br().y, center.x, center.y
125+
private static final JsonReader.Options OPTIONS = JsonReader.Options.of("id", "sn", "v", "d");
126+
127+
@Override
128+
public TargetListTargetData fromJson(BufferedSource source) throws IOException {
129+
JsonReader reader = JsonReader.of(source);
130+
String id = null;
131+
int serial = -1;
132+
boolean valid = false;
133+
List<Target> targets = new ArrayList<>();
134+
135+
reader.beginObject();
136+
while (reader.hasNext()) {
137+
switch (reader.selectName(OPTIONS)) {
138+
case 0:
139+
id = reader.nextString();
140+
break;
141+
case 1:
142+
serial = reader.nextInt();
143+
break;
144+
case 2:
145+
valid = reader.nextBoolean();
146+
break;
147+
case 3:
148+
reader.beginArray();
149+
while (reader.hasNext()) {
150+
int[] data = new int[DATA_LENGTH];
151+
reader.beginArray();
152+
for (int i = 0; i < DATA_LENGTH; i++) {
153+
data[i] = reader.nextInt();
154+
}
155+
reader.endArray();
156+
// bb.x, bb.y, bb.width, bb.height, area
157+
Point topLeft = new Point(data[0], data[1]);
158+
Point bottomRight = new Point(data[0] + data[2], data[1] + data[3]);
159+
Point center = Point.boundingBoxCenterFrom(topLeft, bottomRight);
160+
targets.add(new Target(topLeft, bottomRight, center, data[4]));
161+
}
162+
reader.endArray();
163+
break;
164+
default:
165+
throw new IllegalStateException("Unexpected value: " + reader.selectName(OPTIONS));
166+
}
167+
}
168+
reader.endObject();
169+
return new TargetListTargetData(Objects.requireNonNull(id), serial, valid, targets);
170+
}
171+
172+
@Override
173+
public String toJson(TargetListTargetData targetData) throws IOException {
174+
Buffer buffer = new Buffer();
175+
JsonWriter writer = JsonWriter.of(buffer);
176+
writer.beginObject();
177+
writer.name("id").value(targetData.id);
178+
writer.name("sn").value(targetData.serial);
179+
writer.name("v").value(targetData.valid);
180+
181+
writer.name("d").beginArray();
182+
for (Target t : targetData.targets) {
183+
writer.beginArray();
184+
writer.value(t.topLeft.x).value(t.topLeft.y);
185+
writer.value(t.width()).value(t.height());
186+
writer.value(t.contourArea);
187+
writer.endArray();
188+
}
189+
writer.endArray();
190+
writer.endObject();
191+
return buffer.readUtf8();
192+
}
193+
}
194+
}

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,52 @@
22

33
import com.squareup.moshi.JsonReader;
44
import com.squareup.moshi.JsonWriter;
5-
import okio.Buffer;
6-
import okio.BufferedSource;
7-
85
import java.io.IOException;
96
import java.util.Objects;
7+
import okio.Buffer;
8+
import okio.BufferedSource;
9+
import org.jetbrains.annotations.NotNull;
1010

1111
@SuppressWarnings("unused")
1212
public class UprightRectTargetData extends TargetData {
1313

1414
static final int DATA_LENGTH = 6;
1515

1616
/** Bounding box top-left corner point. */
17-
public final Point topLeft;
17+
@NotNull public final Point topLeft;
1818
/** Bounding box bottom-right corner point. */
19-
public final Point bottomRight;
19+
@NotNull public final Point bottomRight;
2020
/** Bounding box center. */
21-
public final Point center;
21+
@NotNull public final Point center;
2222

2323
public UprightRectTargetData() {
2424
this("", 0, false, new Point(0, 0), new Point(0, 0), new Point(0, 0));
2525
}
2626

2727
public UprightRectTargetData(
28-
String id, int serial, boolean valid, Point topLeft, Point bottomRight, Point center) {
28+
@NotNull String id,
29+
int serial,
30+
boolean valid,
31+
@NotNull Point topLeft,
32+
@NotNull Point bottomRight,
33+
@NotNull Point center) {
2934
super(id, serial, valid);
3035
this.topLeft = topLeft;
3136
this.bottomRight = bottomRight;
3237
this.center = center;
3338
}
3439

40+
/** Returns bounding box area. */
3541
public int area() {
3642
return width() * height();
3743
}
3844

45+
/** Returns width of bounding box. */
3946
public int width() {
4047
return bottomRight.x - topLeft.x;
4148
}
4249

50+
/** Returns height of bounding box. */
4351
public int height() {
4452
return bottomRight.y - topLeft.y;
4553
}
@@ -122,7 +130,8 @@ public UprightRectTargetData fromJson(BufferedSource source) throws IOException
122130
Point topLeft = new Point(data[0], data[1]);
123131
Point bottomRight = new Point(data[2], data[3]);
124132
Point center = new Point(data[4], data[5]);
125-
return new UprightRectTargetData(id, serial, valid, topLeft, bottomRight, center);
133+
return new UprightRectTargetData(
134+
Objects.requireNonNull(id), serial, valid, topLeft, bottomRight, center);
126135
}
127136

128137
@Override

0 commit comments

Comments
 (0)