Too many changes to list

running in to bug in CameraStreamer with native exceptions
This commit is contained in:
Banks Troutman
2019-11-21 05:32:19 -05:00
parent 35509c0162
commit 48da9f5dfd
21 changed files with 678 additions and 211 deletions

View File

@@ -1,7 +1,9 @@
package com.chameleonvision;
import com.chameleonvision.classabstraction.VisionManager;
import com.chameleonvision.classabstraction.config.ConfigManager;
import com.chameleonvision.network.NetworkManager;
import com.chameleonvision.settings.GeneralSettings;
import com.chameleonvision.settings.Platform;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.util.Utilities;
@@ -134,34 +136,40 @@ public class Main {
}
if (testMode) {
ConfigManager.initializeSettings();
NetworkManager.initialize(manageNetwork);
NetworkTableInstance.getDefault().startServer();
boolean visionSourcesOk = VisionManager.initializeSources();
if (!visionSourcesOk) {
System.out.println("No cameras connected!");
return;
}
NetworkManager.initialize(manageNetwork);
boolean visionProcessesOk = VisionManager.initializeProcesses();
if (!visionProcessesOk) {
System.err.println("shit");
return;
}
runServer();
VisionManager.startProcesses();
// runServer(true);
} else {
if (CameraManager.initializeCameras()) {
SettingsManager.initialize();
NetworkManager.initialize(manageNetwork);
CameraManager.initializeThreads();
runServer();
runServer(false);
} else {
System.err.println("No cameras connected!");
}
}
}
private static void runServer() {
private static void runServer(boolean test) {
GeneralSettings settings = test ? ConfigManager.settings : SettingsManager.generalSettings;
if (ntServerMode) {
System.out.println("Starting NT Server");
NetworkTableInstance.getDefault().startServer();
@@ -170,7 +178,7 @@ public class Main {
if (ntClientModeServer != null) {
NetworkTableInstance.getDefault().startClient(ntClientModeServer);
} else {
NetworkTableInstance.getDefault().startClientTeam(SettingsManager.generalSettings.teamNumber);
NetworkTableInstance.getDefault().startClientTeam(settings.teamNumber);
}
}

View File

@@ -3,6 +3,7 @@ package com.chameleonvision.classabstraction;
import com.chameleonvision.classabstraction.camera.USBCameraProcess;
import com.chameleonvision.classabstraction.config.CameraConfig;
import com.chameleonvision.classabstraction.config.ConfigManager;
import com.chameleonvision.settings.Platform;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.util.FileHelper;
import edu.wpi.cscore.UsbCamera;
@@ -11,9 +12,7 @@ import org.opencv.videoio.VideoCapture;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.*;
public class VisionManager {
@@ -22,6 +21,7 @@ public class VisionManager {
private static final Path CamConfigPath = Paths.get(SettingsManager.SettingsPath.toString(), "cameras");
public static final LinkedHashMap<String, UsbCameraInfo> UsbCameraInfosByCameraName = new LinkedHashMap<>();
private static final LinkedList<CameraConfig> LoadedCameraConfigs = new LinkedList<>();
public static final LinkedHashMap<String, VisionProcess> VisionProcessesByCameraName = new LinkedHashMap<>();
public static boolean initializeSources() {
@@ -46,70 +46,41 @@ public class VisionManager {
FileHelper.CheckPath(CamConfigPath);
// load the config
List<CameraConfig> loadedConfigs = ConfigManager.initializeCameraConfig(new ArrayList<>(UsbCameraInfosByCameraName.keySet()));
loadedConfigs.forEach(config -> {
var camera = new USBCameraProcess(
new edu.wpi.cscore.UsbCamera(config.name, config.path),
config
);
VisionProcessesByCameraName.put(config.name, new VisionProcess(camera, config.name));
List<CameraConfig> preliminaryConfigs = new ArrayList<>();
UsbCameraInfosByCameraName.values().forEach((cameraInfo) -> {
String truePath;
if (Platform.CurrentPlatform.isWindows()) {
truePath = cameraInfo.path;
} else {
truePath = Arrays.stream(cameraInfo.otherPaths).filter(x -> x.contains("/dev/v4l/by-path")).findFirst().orElse(cameraInfo.path);
}
preliminaryConfigs.add(new CameraConfig(truePath, cameraInfo.name));
});
LoadedCameraConfigs.addAll(ConfigManager.initializeCameraConfig(preliminaryConfigs));
// UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
// Path cameraConfigFolder = Paths.get(CamConfigPath.toString(), String.format("%s\\", cameraName));
// Path cameraConfigPath = Paths.get(cameraConfigFolder.toString(), String.format("%s.json", cameraName));
// Path cameraPipelinesPath = Paths.get(cameraConfigFolder.toString(), "pipelines.json");
// Path cameraDrivermodePath = Paths.get(cameraConfigFolder.toString(), "drivermode.json");
//
// try {
//
// boolean cameraFolderExists = Files.exists(cameraConfigFolder);
//
// if (!cameraFolderExists) {
// Files.createDirectory(cameraConfigFolder);
// }
// boolean cameraConfigExists = cameraFolderExists && Files.exists(cameraConfigPath);
//
// if (Files.exists(cameraConfigFolder)) {
// if (Files.exists(cameraConfigPath)) {
// File cameraConfigFile = new File(cameraConfigPath.toString());
// if (cameraConfigFile.length() != 0) {
// try {
// Gson gson = new GsonBuilder().create();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// } else {
// Files.createFile(cameraConfigPath);
// }
// } else {
// Files.createDirectory(cameraConfigFolder);
// }
// } catch (IOException ex) {
//
// }
//
//
// });
// FileHelper.CheckPath(CamConfigPath);
// UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
// Path cameraConfigPath = Paths.get(CamConfigPath.toString(), String.format("%s.json", cameraName));
// File cameraConfigFile = new File(cameraConfigPath.toString());
// if (cameraConfigFile.exists() && cameraConfigFile.length() != 0) {
//// try {
//// Gson gson = new GsonBuilder().registerTypeAdapter(USBCameraProcess.class, new CameraDeserializer());
//// }
// }
// })
// TODO: implement new camera JSON loads
return true;
}
public static boolean initializeProcesses() {
LoadedCameraConfigs.forEach(config -> {
var camera = new USBCameraProcess(config);
VisionProcessesByCameraName.put(config.name, new VisionProcess(camera, config.name));
});
return true;
}
public static void startProcesses() {
VisionProcessesByCameraName.forEach((name, process) -> {
process.start();
});
}
}

View File

@@ -34,17 +34,29 @@ public class VisionProcess {
// Thread to grab frames from the camera
// TODO: fix video modes!!!
this.cameraRunnable = new CameraFrameRunnable(cameraProcess.getProperties().videoModes.get(0).fps);
new Thread(cameraRunnable).start();
// Thread to put frames on the dashboard
this.cameraStreamer = new CameraStreamer(cameraProcess, name);
this.streamRunnable = new CameraStreamerRunnable(1000L/32, cameraStreamer);
new Thread(streamRunnable).start();
// Thread to process vision data
this.visionRunnable = new VisionProcessRunnable();
new Thread(visionRunnable).start();
}
public void start() {
System.out.println("Starting camera thread.");
new Thread(cameraRunnable).start();
while (cameraRunnable.cameraFrame == null) {
try {
if (cameraRunnable.cameraFrame.cols() > 0) break;
} catch (Exception e) {
// e.printStackTrace();
}
}
System.out.println("Starting vision thread.");
new Thread(visionRunnable).start();
System.out.println("Starting stream thread.");
new Thread(streamRunnable).start();
}
public void setPipeline(int pipelineIndex) {
@@ -73,7 +85,7 @@ public class VisionProcess {
* at a specified loopTime
*/
protected class CameraFrameRunnable extends LoopingRunnable {
private Mat cameraFrame = new Mat();
private Mat cameraFrame;
private long timestampMicros;
private final Object frameLock = new Object();
@@ -95,18 +107,23 @@ public class VisionProcess {
// Grab camera frames
var camData = cameraProcess.getFrame();
synchronized (frameLock) {
cameraFrame = camData.getLeft();
if (camData.getLeft().cols() > 0) {
// System.out.println("grabbing frame");
// synchronized (frameLock) {
cameraFrame = camData.getLeft();
// }
timestampMicros = camData.getRight();
}
timestampMicros = camData.getRight();
}
}
public Mat getFrame(Mat dst) {
synchronized (frameLock) {
cameraFrame.copyTo(dst);
return dst;
if (cameraFrame != null) {
dst = cameraFrame;
} else {
System.out.println("no frame");
}
return dst;
}
public long getTimestampMicros() {
@@ -125,7 +142,12 @@ public class VisionProcess {
@Override
public void run() {
while(!Thread.interrupted()) {
result = currentPipeline.runPipeline(cameraRunnable.getFrame(streamBuffer));
streamBuffer = cameraRunnable.getFrame(streamBuffer);
if (streamBuffer.cols() > 0 && streamBuffer.rows() > 0) {
result = currentPipeline.runPipeline(streamBuffer);
} else {
// System.err.println("Bad streambuffer mat");
}
// TODO do something with the result
}
}
@@ -143,7 +165,16 @@ public class VisionProcess {
@Override
protected void process() {
streamer.runStream(cameraRunnable.getFrame(streamBuffer));
CVPipelineResult latestResult = visionRunnable.result;
if (latestResult != null) {
Mat toStreamMat = visionRunnable.result.outputMat;
streamBuffer = toStreamMat;
streamer.runStream(toStreamMat);
// if (toStreamMat != null && toStreamMat.cols() > 0) {
// } else {
// System.out.println("fuuuuck");
// }
}
}
}
}

View File

@@ -1,11 +1,8 @@
package com.chameleonvision.classabstraction.camera;
import com.chameleonvision.Main;
import com.chameleonvision.classabstraction.config.CameraConfig;
import com.chameleonvision.settings.Platform;
import com.chameleonvision.vision.camera.USBCamera;
import edu.wpi.cscore.UsbCamera;
import edu.wpi.cscore.UsbCameraInfo;
import edu.wpi.cscore.VideoMode;
import org.apache.commons.math3.util.FastMath;
@@ -16,7 +13,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CameraProperties {
private static final double DEFAULT_FOV = 70;
public static final double DEFAULT_FOV = 70;
private static final int DEFAULT_EXPOSURE = 50;
private static final int DEFAULT_BRIGHTNESS = 50;
private static final int MINIMUM_FPS = 30;
@@ -61,8 +58,16 @@ public class CameraProperties {
System.out.printf("USBCameraProcess initialized in %.2fms\n", initTimeMs);
}
// TODO: find way to determine if camera is a PS3Eye
hasGain = false;
var props = baseCamera.enumerateProperties();
// var props = baseCamera.enumerateProperties();
// for (var prop : props) {
// var name = prop.getName();
// var min = prop.getMin();
// var max = prop.getMax();
// var _default = prop.getDefault();
// var kind = prop.getKind();
// }
videoModes = filterVideoModes(baseCamera.enumerateVideoModes());
}
@@ -85,12 +90,12 @@ public class CameraProperties {
staticProperties = new CameraStaticProperties(videoMode.width, videoMode.height, FOV);
}
public double CalculatePitch(double PixelY, double centerY) {
public double calculatePitch(double PixelY, double centerY) {
double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.verticalFocalLength));
return (pitch * -1);
}
public double CalculateYaw(double PixelX, double centerX) {
public double calculateYaw(double PixelX, double centerX) {
return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.horizontalFocalLength));
}
}

View File

@@ -1,14 +1,11 @@
package com.chameleonvision.classabstraction.camera;
import com.chameleonvision.vision.camera.StreamDivisor;
import com.chameleonvision.web.ServerHandler;
import edu.wpi.cscore.CvSource;
import edu.wpi.cscore.VideoMode;
import edu.wpi.first.cameraserver.CameraServer;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
public class CameraStreamer {
private final CameraProcess cameraProcess;
@@ -24,6 +21,7 @@ public class CameraStreamer {
this.cvSource = CameraServer.getInstance().putVideo(name,
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
setDivisor(divisor);
}
public void setDivisor(StreamDivisor newDivisor) {
@@ -37,7 +35,7 @@ public class CameraStreamer {
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
}
ServerHandler.sendFullSettings();
// ServerHandler.sendFullSettings();
}
public void setNewVideoMode(VideoMode newVideoMode) {
@@ -47,14 +45,16 @@ public class CameraStreamer {
}
public void runStream(Mat image) {
image.copyTo(streamBuffer);
if (divisor.value != 1) {
var camVal = cameraProcess.getProperties().staticProperties;
var newWidth = camVal.imageWidth / divisor.value;
var newHeight = camVal.imageHeight / divisor.value;
Size newSize = new Size(newWidth, newHeight);
Imgproc.resize(streamBuffer, streamBuffer, newSize);
synchronized (streamBufferLock) {
streamBuffer = image;
}
// if (divisor.value != 1) {
// var camVal = cameraProcess.getProperties().staticProperties;
// var newWidth = camVal.imageWidth / divisor.value;
// var newHeight = camVal.imageHeight / divisor.value;
// Size newSize = new Size(newWidth, newHeight);
// Imgproc.resize(streamBuffer, streamBuffer, newSize);
// }
cvSource.putFrame(streamBuffer);
}

View File

@@ -15,11 +15,10 @@ public class USBCameraProcess implements CameraProcess {
private Mat imageBuffer = new Mat();
private CameraProperties properties;
public USBCameraProcess(UsbCamera camera, CameraConfig config) {
baseCamera = camera;
public USBCameraProcess(CameraConfig config) {
baseCamera = new UsbCamera(config.name, config.path);
cvSink = CameraServer.getInstance().getVideo(baseCamera);
properties = new CameraProperties(baseCamera, config.fov);
properties = new CameraProperties(baseCamera, config);
setVideoMode(properties.videoModes.get(0));
}

View File

@@ -1,17 +1,31 @@
package com.chameleonvision.classabstraction.config;
import com.chameleonvision.classabstraction.camera.CameraProperties;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CameraConfig {
public final double fov;
public final String path;
public final String name;
public final String nickname;
public CameraConfig(double FOV,
String path, String name,
String nickname) {
this.fov = FOV;
@JsonCreator
public CameraConfig(
@JsonProperty("fov") double fov,
@JsonProperty("path") String path,
@JsonProperty("name") String name,
@JsonProperty("nickname") String nickname) {
this.fov = fov;
this.path = path;
this.name = name;
this.nickname = nickname;
}
public CameraConfig(String path, String name) {
this.fov = CameraProperties.DEFAULT_FOV;
this.path = path;
this.name = name;
this.nickname = name;
}
}

View File

@@ -2,37 +2,25 @@ package com.chameleonvision.classabstraction.config;
import com.chameleonvision.classabstraction.util.ProgramDirectoryUtilities;
import com.chameleonvision.settings.GeneralSettings;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.util.FileHelper;
import com.chameleonvision.vision.camera.CameraDeserializer;
import com.chameleonvision.vision.camera.USBCamera;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ConfigManager {
private ConfigManager() {}
private static final Path SettingsPath = Paths.get(ProgramDirectoryUtilities.getProgramDirectory(), "settings");
private static final Path cameraConfigPath = Paths.get(ProgramDirectoryUtilities.getProgramDirectory(), "cameras");
private static final Path cameraConfigPath = Paths.get(SettingsPath.toString(), "cameras");
public static GeneralSettings settings = new GeneralSettings();
public static void initializeSettings() {
boolean settingsFolderExists = Files.exists(SettingsPath);
if (!settingsFolderExists) {
if (Files.notExists(SettingsPath)) {
try {
Files.createDirectory(SettingsPath);
} catch (IOException e) {
@@ -42,11 +30,10 @@ public class ConfigManager {
// try to load the settings file and deserialize it
Path settingsFilePath = Paths.get(SettingsPath.toString(), "settings.json");
boolean settingsFileExists = Files.exists(settingsFilePath);
if (!settingsFileExists) {
if (Files.notExists(settingsFilePath)) {
try {
FileHelper.Serializer(settings, settingsFilePath);
FileHelper.Serializer(settingsFilePath, settings);
} catch (IOException e) {
e.printStackTrace();
}
@@ -57,53 +44,41 @@ public class ConfigManager {
System.err.println("Failed to load settings.json, using defaults.");
}
}
// try to load camera file and deserialize it
// var cameraConfigs = initializeCameraConfig();
}
public static List<CameraConfig> initializeCameraConfig(List<String> cameraNames) {
public static List<CameraConfig> initializeCameraConfig(List<CameraConfig> preliminaryConfigs) {
var configList = new ArrayList<CameraConfig>();
// loop over all the camera names and try to create settings folders for it
cameraNames.forEach((cameraName) -> {
final Path cameraConfigFolder = Paths.get(cameraConfigPath.toString(), String.format("%s\\", cameraName));
final Path cameraConfigPath = Paths.get(cameraConfigFolder.toString(), String.format("%s.json", cameraName));
preliminaryConfigs.forEach((preliminaryConfig) -> {
final Path cameraConfigFolderPath = Paths.get(cameraConfigPath.toString(), String.format("%s\\", preliminaryConfig.name));
final Path cameraConfigPath = Paths.get(cameraConfigFolderPath.toString(), "camera.json");
// check if the config folder exists, and if not, create it
boolean cameraConfigFolderExists = Files.exists(cameraConfigFolder);
if (!cameraConfigFolderExists) {
if (Files.notExists(cameraConfigFolderPath)) {
try {
Files.createDirectory(cameraConfigFolder);
} catch (IOException e) {
e.printStackTrace();
}
}
// try to deserialize the file
var camJsonFile = new File(cameraConfigPath.toString());
if(camJsonFile.exists() && camJsonFile.length() > 0) {
try {
var config = FileHelper.DeSerializer(cameraConfigPath, CameraConfig.class);
configList.add(config);
Files.createDirectory(cameraConfigFolderPath);
} catch (IOException e) {
e.printStackTrace();
}
} else {
// create a default one
configList.add(new CameraConfig(
70.0,
cameraConfigPath.toString(),
cameraName,
cameraName
));
CameraConfig config = preliminaryConfig;
if(!Files.exists(cameraConfigPath)) {
try {
FileHelper.Serializer(cameraConfigPath, preliminaryConfig);
} catch (IOException e) {
e.printStackTrace();
}
} else {
try {
config = FileHelper.DeSerializer(cameraConfigPath, CameraConfig.class);
} catch (IOException e) {
e.printStackTrace();
}
}
configList.add(config);
}
});
return configList;

View File

@@ -10,7 +10,7 @@ import java.util.function.Supplier;
* @param <R> Pipeline result type
*/
public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelineSettings> {
protected Mat outputMat;
protected Mat outputMat = new Mat();
CameraProcess cameraProcess;
final Supplier<S> settingsSupplier;

View File

@@ -35,7 +35,7 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
var settings = settingsSupplier.get();
CameraStaticProperties camProps = cameraProcess.getProperties().staticProperties;
inputMat.copyTo(rawCameraMat);
rawCameraMat = inputMat;
// prepare pipes
RotateFlipPipe rotateFlipPipe = new RotateFlipPipe(ImageRotation.DEG_0, settings.flipMode);

View File

@@ -7,13 +7,13 @@ import java.util.List;
public abstract class CVPipelineResult<T> {
public final List<T> targets;
public final boolean hasTarget;
public final Mat outputMat = new Mat();
public final Mat outputMat;
public final long processTime;
public CVPipelineResult(List<T> targets, Mat outputMat, long processTime) {
this.targets = targets;
hasTarget = targets != null && !targets.isEmpty();
outputMat.copyTo(this.outputMat);
this.outputMat = outputMat;
this.processTime = processTime;
}
}

View File

@@ -1,12 +1,13 @@
package com.chameleonvision.classabstraction.pipeline;
import com.chameleonvision.classabstraction.camera.CameraProcess;
import com.chameleonvision.classabstraction.pipeline.pipes.Draw2dContoursPipe;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.Mat;
import java.util.List;
import java.util.function.Supplier;
import static com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline.*;
import static com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline.DriverPipelineResult;
public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPipelineSettings> {
@@ -14,16 +15,18 @@ public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPip
super(settingsSupplier);
}
@Override
public void initPipeline(CameraProcess camera) {
camera.setBrightness((int) getSettings().brightness);
camera.setExposure((int) getSettings().exposure);
}
@Override
public DriverPipelineResult runPipeline(Mat inputMat) {
inputMat.copyTo(outputMat);
outputMat = inputMat;
var camProps = cameraProcess.getProperties().staticProperties;
Draw2dContoursPipe.Draw2dContoursSettings draw2dContoursSettings = new Draw2dContoursPipe.Draw2dContoursSettings();
draw2dContoursSettings.showCrosshair = true;
Draw2dContoursPipe draw2dContoursPipe = new Draw2dContoursPipe(draw2dContoursSettings, camProps);
outputMat = draw2dContoursPipe.run(Pair.of(outputMat, null)).getLeft();
return new DriverPipelineResult(null, inputMat, 0);
}

View File

@@ -1,9 +1,10 @@
package com.chameleonvision.classabstraction.pipeline.pipes;
import com.chameleonvision.classabstraction.camera.CameraStaticProperties;
import com.chameleonvision.classabstraction.util.Helpers;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import java.awt.*;
@@ -26,37 +27,41 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
public Pair<Mat, Long> run(Pair<Mat, List<RotatedRect>> input) {
long processStartNanos = System.nanoTime();
input.getLeft().copyTo(outputMat);
outputMat = input.getLeft();
for (RotatedRect r : input.getRight()) {
if (r == null) continue;
if (input.getRight() != null && !input.getRight().isEmpty()) {
for (RotatedRect r : input.getRight()) {
if (r == null) continue;
List<MatOfPoint> drawnContour = new ArrayList<>();
Point[] vertices = new Point[4];
r.points(vertices);
MatOfPoint contour = new MatOfPoint(vertices);
drawnContour.add(contour);
List<MatOfPoint> drawnContour = new ArrayList<>();
Point[] vertices = new Point[4];
r.points(vertices);
MatOfPoint contour = new MatOfPoint(vertices);
drawnContour.add(contour);
if (settings.showCentroid) {
Imgproc.circle(outputMat, r.center, 3, colorToScalar(settings.centroidColor));
if (settings.showCentroid) {
Imgproc.circle(outputMat, r.center, 3, Helpers.colorToScalar(settings.centroidColor));
}
if (settings.showRotatedBox) {
Imgproc.drawContours(outputMat, drawnContour, 0, Helpers.colorToScalar(settings.rotatedBoxColor), settings.boxOutlineSize);
}
if (settings.showMaximumBox) {
Rect box = Imgproc.boundingRect(contour);
Imgproc.rectangle(outputMat, new Point(box.x, box.y), new Point((box.x + box.width), (box.y + box.height)), Helpers.colorToScalar(settings.maximumBoxColor), settings.boxOutlineSize);
}
}
}
if (settings.showCrosshair) {
Point xMax = new Point(camProps.centerX + 10, camProps.centerY);
Point xMin = new Point(camProps.centerX - 10, camProps.centerY);
Point yMax = new Point(camProps.centerX, camProps.centerY + 10);
Point yMin = new Point(camProps.centerX, camProps.centerY - 10);
Imgproc.line(outputMat, xMax, xMin, colorToScalar(settings.crosshairColor), 2);
Imgproc.line(outputMat, yMax, yMin, colorToScalar(settings.crosshairColor), 2);
}
if (settings.showRotatedBox) {
Imgproc.drawContours(outputMat, drawnContour, 0, colorToScalar(settings.rotatedBoxColor), settings.boxOutlineSize);
}
if (settings.showMaximumBox) {
Rect box = Imgproc.boundingRect(contour);
Imgproc.rectangle(outputMat, new Point(box.x, box.y), new Point((box.x + box.width), (box.y + box.height)), colorToScalar(settings.maximumBoxColor), settings.boxOutlineSize);
if (settings.showCrosshair) {
Point xMax = new Point(camProps.centerX + 10, camProps.centerY);
Point xMin = new Point(camProps.centerX - 10, camProps.centerY);
Point yMax = new Point(camProps.centerX, camProps.centerY + 10);
Point yMin = new Point(camProps.centerX, camProps.centerY - 10);
if (outputMat != null && outputMat.cols() > 0) {
Imgproc.line(outputMat, xMax, xMin, Helpers.colorToScalar(settings.crosshairColor), 2);
Imgproc.line(outputMat, yMax, yMin, Helpers.colorToScalar(settings.crosshairColor), 2);
}
}
@@ -66,10 +71,6 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
return output;
}
private Scalar colorToScalar(Color color) {
return new Scalar(color.getRed(), color.getGreen(), color.getBlue());
}
public static class Draw2dContoursSettings {
public boolean showCentroid = false;
public boolean showCrosshair = false;
@@ -80,6 +81,5 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
public Color crosshairColor = Color.GREEN;
public Color rotatedBoxColor = Color.BLUE;
public Color maximumBoxColor = Color.RED;
}
}

View File

@@ -17,11 +17,7 @@ public class OutputMatPipe implements Pipe<Pair<Mat, Mat>, Mat> {
public Pair<Mat, Long> run(Pair<Mat, Mat> input) {
long processStartNanos = System.nanoTime();
if (showThresholded) {
input.getRight().copyTo(outputMat);
} else {
input.getLeft().copyTo(outputMat);
}
outputMat = showThresholded ? input.getRight() : input.getLeft();
long processTime = processStartNanos - System.nanoTime();
Pair<Mat, Long> output = Pair.of(outputMat, processTime);

View File

@@ -0,0 +1,14 @@
package com.chameleonvision.classabstraction.util;
import org.opencv.core.Scalar;
import java.awt.*;
public class Helpers {
private Helpers() {}
public static Scalar colorToScalar(Color color) {
return new Scalar(color.getRed(), color.getGreen(), color.getBlue());
}
}

View File

@@ -27,7 +27,8 @@ public class ProgramDirectoryUtilities
return getCurrentJARDirectory();
} else
{
return getCurrentProjectDirectory();
return System.getProperty("user.dir");
// return getCurrentProjectDirectory();
}
}

View File

@@ -8,8 +8,6 @@ import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import static com.chameleonvision.settings.Platform.CurrentPlatform;
public class NetworkManager {
private NetworkManager() {}
@@ -22,9 +20,11 @@ public class NetworkManager {
return;
}
if (CurrentPlatform.isLinux()) {
Platform platform = Platform.getCurrentPlatform();
if (platform.isLinux()) {
networking = new LinuxNetworking();
} else if (CurrentPlatform.isWindows()) {
} else if (platform.isWindows()) {
// networking = new WindowsNetworking();
System.out.println("Windows networking is not yet supported. Running unmanaged.");
return;

View File

@@ -28,15 +28,20 @@ public class FileHelper {
}
}
public static void Serializer(Object object, Path path) throws IOException {
public static void Serializer(Path path, Object object) throws IOException {
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build();
ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build();
objectMapper.writeValue(new File(path.toString()), object);
objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(path.toString()), object);
}
public static <T> T DeSerializer(Path path, Class<T> ref) throws IOException {
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build();
ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build();
return objectMapper.readValue(new File(path.toString()), ref);
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(ref).build();
ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv).build();
File jsonFile = new File(path.toString());
if (jsonFile.exists() && jsonFile.length() > 0) {
T readObject = objectMapper.readValue(jsonFile, ref);
return readObject;
}
return null;
}
}