-
Save Input Snapshot
-
Save Output Snapshot
+
+ Save Input Snapshot
+ Save Output Snapshot
diff --git a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java
index 43a9520748..f7f0345723 100644
--- a/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java
+++ b/photon-server/src/main/java/org/photonvision/server/DataSocketHandler.java
@@ -278,17 +278,17 @@ public void onBinaryMessage(WsBinaryMessageContext context) {
break;
}
case SMT_SAVEOUTPUTSNAPSHOT:
- {
- var takeOutputSnapshotEvent =
- new IncomingWebSocketEvent<>(
- DataChangeDestination.DCD_ACTIVEMODULE,
- "saveOutputSnapshot",
- 0,
- cameraIndex,
- context);
- dcService.publishEvent(takeOutputSnapshotEvent);
- break;
- }
+ {
+ var takeOutputSnapshotEvent =
+ new IncomingWebSocketEvent<>(
+ DataChangeDestination.DCD_ACTIVEMODULE,
+ "saveOutputSnapshot",
+ 0,
+ cameraIndex,
+ context);
+ dcService.publishEvent(takeOutputSnapshotEvent);
+ break;
+ }
case SMT_TAKECALIBRATIONSNAPSHOT:
{
var takeCalSnapshotEvent =
From c5a75b1a6e90fe96ea7ef420b641ae78782cff23 Mon Sep 17 00:00:00 2001
From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com>
Date: Mon, 9 Oct 2023 17:41:38 -0400
Subject: [PATCH 07/10] Update CameraCalibrationCard.vue
---
photon-client/src/components/cameras/CameraCalibrationCard.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/photon-client/src/components/cameras/CameraCalibrationCard.vue b/photon-client/src/components/cameras/CameraCalibrationCard.vue
index a5b3be4c4f..065e372de7 100644
--- a/photon-client/src/components/cameras/CameraCalibrationCard.vue
+++ b/photon-client/src/components/cameras/CameraCalibrationCard.vue
@@ -381,7 +381,7 @@ const endCalibration = () => {
color="secondary"
style="width: 100%"
:disabled="!settingsValid"
- @click="isCalibrating ? useCameraSettingsStore().takeCalibrationSnapshot(true) : startCalibration()"
+ @click="isCalibrating ? useCameraSettingsStore().takeCalibrationSnapshot() : startCalibration()"
>
{{ isCalibrating ? "Take Snapshot" : "Start Calibration" }}
From e1d5609d3dc0cd9b34d5ff0e88fc7446ffe27dc7 Mon Sep 17 00:00:00 2001
From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com>
Date: Mon, 9 Oct 2023 18:38:03 -0400
Subject: [PATCH 08/10] Refactor FileSaveFrameConsumer to be more
understandable
---
.../frame/consumer/FileSaveFrameConsumer.java | 88 +++++++++----------
1 file changed, 44 insertions(+), 44 deletions(-)
diff --git a/photon-core/src/main/java/org/photonvision/vision/frame/consumer/FileSaveFrameConsumer.java b/photon-core/src/main/java/org/photonvision/vision/frame/consumer/FileSaveFrameConsumer.java
index 241ad8fbca..57bc312b2f 100644
--- a/photon-core/src/main/java/org/photonvision/vision/frame/consumer/FileSaveFrameConsumer.java
+++ b/photon-core/src/main/java/org/photonvision/vision/frame/consumer/FileSaveFrameConsumer.java
@@ -32,58 +32,57 @@
import org.photonvision.vision.opencv.CVMat;
public class FileSaveFrameConsumer implements Consumer
{
+ private final Logger logger = new Logger(FileSaveFrameConsumer.class, LogGroup.General);
+
// Formatters to generate unique, timestamped file names
- private static String FILE_PATH = ConfigManager.getInstance().getImageSavePath().toString();
- private static String FILE_EXTENSION = ".jpg";
+ private static final String FILE_PATH = ConfigManager.getInstance().getImageSavePath().toString();
+ private static final String FILE_EXTENSION = ".jpg";
+ private static final String NT_SUFFIX = "SaveImgCmd";
+
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
DateFormat tf = new SimpleDateFormat("hhmmssSS");
- private final String NT_SUFFIX = "SaveImgCmd";
- private final String ntEntryName;
- private NetworkTable subTable;
+
private final NetworkTable rootTable;
- private final Logger logger;
- private long imgSaveCountInternal = 0;
- private String camNickname;
- private String fnamePrefix;
- private IntegerEntry entry;
+ private NetworkTable subTable;
+ private final String ntEntryName;
+ private IntegerEntry saveFrameEntry;
+
+ private String cameraNickname;
+ private final String streamType;
+
+ private long savedImagesCount = 0;
public FileSaveFrameConsumer(String camNickname, String streamPrefix) {
- this.fnamePrefix = camNickname + "_" + streamPrefix;
this.ntEntryName = streamPrefix + NT_SUFFIX;
+ this.cameraNickname = camNickname;
+ this.streamType = streamPrefix;
+
this.rootTable = NetworkTablesManager.getInstance().kRootTable;
updateCameraNickname(camNickname);
- this.logger = new Logger(FileSaveFrameConsumer.class, this.camNickname, LogGroup.General);
}
public void accept(CVMat image) {
if (image != null && image.getMat() != null && !image.getMat().empty()) {
- var curCommand = entry.get(); // default to just our current count
- if (curCommand >= 0) {
- // Only do something if we got a valid current command
- if (imgSaveCountInternal < curCommand) {
- // Save one frame.
- // Create the filename
- Date now = new Date();
- String savefile =
- FILE_PATH
- + File.separator
- + fnamePrefix
- + "_"
- + df.format(now)
- + "T"
- + tf.format(now)
- + FILE_EXTENSION;
-
- // write to file
- Imgcodecs.imwrite(savefile, image.getMat());
-
- // Count one more image saved
- imgSaveCountInternal++;
- logger.info("Saved new image at " + savefile);
-
- } else if (imgSaveCountInternal > curCommand) {
- imgSaveCountInternal = curCommand;
- }
+ long currentCount = saveFrameEntry.get();
+
+ // Await save request
+ if (currentCount == -1) return;
+
+ // The requested count is greater than the actual count
+ if (savedImagesCount < currentCount) {
+ Date now = new Date();
+
+ String fileName =
+ cameraNickname + "_" + streamType + "_" + df.format(now) + "T" + tf.format(now);
+ String saveFilePath = FILE_PATH + File.separator + fileName + FILE_EXTENSION;
+
+ Imgcodecs.imwrite(saveFilePath, image.getMat());
+
+ savedImagesCount++;
+ logger.info("Saved new image at " + saveFilePath);
+ } else if (savedImagesCount > currentCount) {
+ // Reset local value with NT value in case of de-sync
+ savedImagesCount = currentCount;
}
}
}
@@ -97,13 +96,14 @@ public void updateCameraNickname(String newCameraNickname) {
}
// Recreate and re-init network tables structure
- this.camNickname = newCameraNickname;
- this.subTable = rootTable.getSubTable(this.camNickname);
- this.subTable.getEntry(ntEntryName).setInteger(imgSaveCountInternal);
- this.entry = subTable.getIntegerTopic(ntEntryName).getEntry(-1); // Default negative
+ this.cameraNickname = newCameraNickname;
+ this.subTable = rootTable.getSubTable(this.cameraNickname);
+ this.subTable.getEntry(ntEntryName).setInteger(savedImagesCount);
+ this.saveFrameEntry = subTable.getIntegerTopic(ntEntryName).getEntry(-1); // Default negative
}
public void overrideTakeSnapshot() {
- entry.set(entry.get() + 1);
+ // Simulate NT change
+ saveFrameEntry.set(saveFrameEntry.get() + 1);
}
}
From 923854977a9bbdf9526c17f554a0fdf09582fcbe Mon Sep 17 00:00:00 2001
From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com>
Date: Mon, 16 Oct 2023 00:29:27 -0400
Subject: [PATCH 09/10] move capture button to be an overlay on the stream
---
.../components/app/photon-camera-stream.vue | 74 ++++++++++++++---
.../src/components/cameras/CamerasView.vue | 81 +++++++------------
.../src/components/dashboard/CamerasCard.vue | 71 ++++++++--------
3 files changed, 122 insertions(+), 104 deletions(-)
diff --git a/photon-client/src/components/app/photon-camera-stream.vue b/photon-client/src/components/app/photon-camera-stream.vue
index 2868ae7180..c75c6eab2c 100644
--- a/photon-client/src/components/app/photon-camera-stream.vue
+++ b/photon-client/src/components/app/photon-camera-stream.vue
@@ -4,13 +4,14 @@ import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
import { useStateStore } from "@/stores/StateStore";
import loadingImage from "@/assets/images/loading.svg";
import type { StyleValue } from "vue/types/jsx";
+import CvIcon from "@/components/common/cv-icon.vue";
const props = defineProps<{
streamType: "Raw" | "Processed";
id?: string;
}>();
-const src = computed(() => {
+const streamSrc = computed(() => {
const port =
useCameraSettingsStore().currentCameraSettings.stream[props.streamType === "Raw" ? "inputPort" : "outputPort"];
@@ -20,25 +21,74 @@ const src = computed(() => {
return `http://${inject("backendHostname")}:${port}/stream.mjpg`;
});
-const alt = computed(() => `${props.streamType} Stream View`);
-
-const style = computed(() => {
+const streamDesc = computed(() => `${props.streamType} Stream View`);
+const streamStyle = computed(() => {
if (useStateStore().colorPickingMode) {
- return { cursor: "crosshair" };
- } else if (src.value !== loadingImage) {
- return { cursor: "pointer" };
+ return { width: "100%", cursor: "crosshair" };
+ } else if (streamSrc.value !== loadingImage) {
+ return { width: "100%", cursor: "pointer" };
}
- return {};
+ return { width: "100%" };
});
-const handleClick = () => {
- if (!useStateStore().colorPickingMode && src.value !== loadingImage) {
- window.open(src.value);
+const overlayStyle = computed(() => {
+ if (useStateStore().colorPickingMode || streamSrc.value == loadingImage) {
+ return { display: "none" };
+ } else {
+ return {};
+ }
+});
+
+const handleStreamClick = () => {
+ if (!useStateStore().colorPickingMode && streamSrc.value !== loadingImage) {
+ window.open(streamSrc.value);
+ }
+};
+const handleCaptureClick = () => {
+ if (props.streamType === "Raw") {
+ useCameraSettingsStore().saveInputSnapshot();
+ } else {
+ useCameraSettingsStore().saveOutputSnapshot();
}
};
-
+
+
+
+
+
+
+
+
diff --git a/photon-client/src/components/cameras/CamerasView.vue b/photon-client/src/components/cameras/CamerasView.vue
index ebb7644445..c9e3d32cb9 100644
--- a/photon-client/src/components/cameras/CamerasView.vue
+++ b/photon-client/src/components/cameras/CamerasView.vue
@@ -41,48 +41,39 @@ const fpsTooLow = computed(() => {
-
+
-
-
-
- Cameras
-
-
-
-
- {{ Math.round(useStateStore().pipelineResults?.fps || 0) }} FPS –
- {{ Math.min(Math.round(useStateStore().pipelineResults?.latency || 0), 9999) }} ms latency
-
-
-
+
+
+ Cameras
-
+
+
+ {{ Math.round(useStateStore().pipelineResults?.fps || 0) }} FPS –
+ {{ Math.min(Math.round(useStateStore().pipelineResults?.latency || 0), 9999) }} ms latency
+
+
-
-
Save Input Snapshot
-
Save Output Snapshot
+
+
+
@@ -142,32 +133,16 @@ th {
.stream {
display: flex;
justify-content: center;
- width: 100%;
}
-@media only screen and (min-width: 562px) and (max-width: 960px) {
+@media only screen and (min-width: 512px) and (max-width: 960px) {
.stream-container {
flex-wrap: nowrap;
+ justify-content: center;
}
.stream {
- width: 50%;
- }
-
- .snapshot-btn {
- width: 45%;
- }
-}
-
-@media only screen and (min-width: 960px) and (max-width: 1587px) {
- .snapshot-btn {
- width: 100%;
- }
-}
-
-@media only screen and (max-width: 562px) {
- .snapshot-btn {
- width: 100%;
+ max-width: 50%;
}
}
diff --git a/photon-client/src/components/dashboard/CamerasCard.vue b/photon-client/src/components/dashboard/CamerasCard.vue
index 7037e2cc15..8500f13c42 100644
--- a/photon-client/src/components/dashboard/CamerasCard.vue
+++ b/photon-client/src/components/dashboard/CamerasCard.vue
@@ -33,47 +33,40 @@ const fpsTooLow = computed
(() => {
-
-
-
-
Cameras
-
+
+ Cameras
+
+
+ Processing @ {{ Math.round(useStateStore().pipelineResults?.fps || 0) }} FPS –
+
+
-
- Processing @ {{ Math.round(useStateStore().pipelineResults?.fps || 0) }} FPS –
-
-
- HSV thresholds are too broad; narrow them for better performance
-
-
- stop viewing the raw stream for better performance
-
-
- {{ Math.min(Math.round(useStateStore().pipelineResults?.latency || 0), 9999) }} ms latency
-
-
-
-
-
-
+ HSV thresholds are too broad; narrow them for better performance
+
+
+ stop viewing the raw stream for better performance
+
+
+ {{ Math.min(Math.round(useStateStore().pipelineResults?.latency || 0), 9999) }} ms latency
+
+
-
-
Save Input Snapshot
-
Save Output Snapshot
+
+
From 13900086ca54ecf460c884c010644d10dd4bf4b0 Mon Sep 17 00:00:00 2001
From: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com>
Date: Mon, 16 Oct 2023 00:32:20 -0400
Subject: [PATCH 10/10] Update photon-camera-stream.vue
---
photon-client/src/components/app/photon-camera-stream.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/photon-client/src/components/app/photon-camera-stream.vue b/photon-client/src/components/app/photon-camera-stream.vue
index c75c6eab2c..1349da2f9d 100644
--- a/photon-client/src/components/app/photon-camera-stream.vue
+++ b/photon-client/src/components/app/photon-camera-stream.vue
@@ -68,8 +68,8 @@ const handleCaptureClick = () => {