mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-26 01:51:40 +00:00
Merge branch 'dev' of https://gitlab.com/chameleon-vision/Chameleon-Vision into dev
# Conflicts: # chameleon-client/src/views/CameraViewes/OutputTab.vue
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-nop:1.7.26" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.javalin:javalin:3.4.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.31" level="project" />
|
||||
@@ -33,7 +34,7 @@
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.19.v20190610" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.19.v20190610" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.json:json:20190722" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.26" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-nop:1.7.26" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.msgpack:msgpack-core:0.8.18" level="project" />
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<!--slf4j for javalin -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<artifactId>slf4j-nop</artifactId>
|
||||
<version>1.7.26</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.chameleonvision.vision;
|
||||
|
||||
public enum CalibrationMode {
|
||||
None,Single,Dual
|
||||
}
|
||||
@@ -22,6 +22,7 @@ public class Pipeline {
|
||||
public TargetIntersection targetIntersection = TargetIntersection.Up;
|
||||
public double m = 1;
|
||||
public double b = 0;
|
||||
public boolean isCalibrated = false;
|
||||
public List<Number> point = Arrays.asList(0,0);
|
||||
public CalibrationMode calibrationMode = CalibrationMode.None;
|
||||
public String nickname;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ public class CameraValues {
|
||||
public final double CenterX;
|
||||
public final double CenterY;
|
||||
public final double DiagonalView;
|
||||
public final double DiagonalAspect;
|
||||
public final Fraction AspectFraction;
|
||||
public final int HorizontalRatio;
|
||||
public final int VerticalRatio;
|
||||
@@ -35,8 +36,9 @@ public class CameraValues {
|
||||
AspectFraction = new Fraction(ImageWidth, ImageHeight);
|
||||
HorizontalRatio = AspectFraction.getNumerator();
|
||||
VerticalRatio = AspectFraction.getDenominator();
|
||||
HorizontalView = FastMath.atan(FastMath.tan(DiagonalView / 2) * (HorizontalRatio / DiagonalView)) * 2;
|
||||
VerticalView = FastMath.atan(FastMath.tan(DiagonalView/2) * (VerticalRatio / DiagonalView)) * 2;
|
||||
DiagonalAspect = FastMath.hypot(HorizontalRatio, VerticalRatio);
|
||||
HorizontalView = FastMath.atan(FastMath.tan(DiagonalView / 2) * (HorizontalRatio / DiagonalAspect)) * 2;
|
||||
VerticalView = FastMath.atan(FastMath.tan(DiagonalView / 2) * (VerticalRatio / DiagonalAspect)) * 2;
|
||||
HorizontalFocalLength = ImageWidth / (2 * FastMath.tan(HorizontalView /2));
|
||||
VerticalFocalLength = ImageHeight / (2 * FastMath.tan(VerticalView /2));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.chameleonvision.vision.process;
|
||||
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.vision.CalibrationMode;
|
||||
import com.chameleonvision.vision.Orientation;
|
||||
import com.chameleonvision.vision.Pipeline;
|
||||
import com.chameleonvision.vision.camera.Camera;
|
||||
@@ -155,15 +156,24 @@ public class VisionProcess implements Runnable {
|
||||
groupedContours = cvProcess.groupTargets(deSpeckledContours, currentPipeline.targetIntersection, currentPipeline.targetGroup);
|
||||
if (groupedContours.size() > 0) {
|
||||
var finalRect = cvProcess.sortTargetsToOne(groupedContours, currentPipeline.sortMode);
|
||||
// System.out.printf("Largest Contour Area: %.2f\n", finalRect.size.area());
|
||||
pipelineResult.RawPoint = finalRect;
|
||||
pipelineResult.IsValid = true;
|
||||
if (!currentPipeline.isCalibrated) {
|
||||
pipelineResult.CalibratedX = camera.getCamVals().CenterX;
|
||||
pipelineResult.CalibratedY = camera.getCamVals().CenterY;
|
||||
} else {
|
||||
pipelineResult.CalibratedX = (finalRect.center.y - currentPipeline.b) / currentPipeline.m;
|
||||
pipelineResult.CalibratedY = (finalRect.center.x * currentPipeline.m) + currentPipeline.b;
|
||||
switch (currentPipeline.calibrationMode){
|
||||
case None:
|
||||
///use the center of the camera to find the pitch and yaw difference
|
||||
pipelineResult.CalibratedX = camera.getCamVals().CenterX;
|
||||
pipelineResult.CalibratedY = camera.getCamVals().CenterY;
|
||||
break;
|
||||
case Single:
|
||||
// use the static point as a calibration method instead of the center
|
||||
pipelineResult.CalibratedX = currentPipeline.point.get(0).doubleValue();
|
||||
pipelineResult.CalibratedY = currentPipeline.point.get(1).doubleValue();
|
||||
break;
|
||||
case Dual:
|
||||
// use the calculated line to find the difference in length between the point and the line
|
||||
pipelineResult.CalibratedX = (finalRect.center.y - currentPipeline.b) / currentPipeline.m;
|
||||
pipelineResult.CalibratedY = (finalRect.center.x * currentPipeline.m) + currentPipeline.b;
|
||||
break;
|
||||
}
|
||||
pipelineResult.Pitch = camera.getCamVals().CalculatePitch(finalRect.center.y, pipelineResult.CalibratedY);
|
||||
pipelineResult.Yaw = camera.getCamVals().CalculateYaw(finalRect.center.x, pipelineResult.CalibratedX);
|
||||
|
||||
@@ -52,6 +52,7 @@ public class ServerHandler {
|
||||
setField(SettingsManager.GeneralSettings, e.getKey(), e.getValue());
|
||||
}
|
||||
SettingsManager.saveSettings();
|
||||
sendFullSettings();
|
||||
break;
|
||||
}
|
||||
case "cameraSettings": {
|
||||
@@ -60,16 +61,19 @@ public class ServerHandler {
|
||||
CameraManager.getCurrentCamera().setStreamDivisor((Integer) camSettings.get("streamDivisor"));
|
||||
CameraManager.getCurrentCamera().setCamVideoMode((Integer) camSettings.get("resolution"), true);
|
||||
SettingsManager.saveSettings();
|
||||
sendFullSettings();
|
||||
break;
|
||||
}
|
||||
case "changeCameraName": {
|
||||
CameraManager.getCurrentCamera().setNickname((String) entry.getValue());
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
}
|
||||
case "changePipelineName": {
|
||||
CameraManager.getCurrentPipeline().nickname = (String) entry.getValue();
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
}
|
||||
case "duplicatePipeline": {
|
||||
@@ -84,6 +88,7 @@ public class ServerHandler {
|
||||
} else {
|
||||
CameraManager.getCurrentCamera().addPipeline(origPipeline);
|
||||
}
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
}
|
||||
case "command": {
|
||||
@@ -92,6 +97,7 @@ public class ServerHandler {
|
||||
case "addNewPipeline":
|
||||
cam.addPipeline();
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
case "deleteCurrentPipeline":
|
||||
int currentIndex = cam.getCurrentPipelineIndex();
|
||||
@@ -104,6 +110,10 @@ public class ServerHandler {
|
||||
cam.deletePipeline();
|
||||
cam.setCurrentPipelineIndex(nextIndex);
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
case "save":
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
}
|
||||
// used to define all incoming commands
|
||||
@@ -117,9 +127,7 @@ public class ServerHandler {
|
||||
case "currentPipeline": {
|
||||
var cam = CameraManager.getCurrentCamera();
|
||||
cam.setCurrentPipelineIndex((Integer) entry.getValue());
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
tmp.put("pipeline", getOrdinalPipeline());
|
||||
broadcastMessage(tmp);
|
||||
sendFullSettings();
|
||||
try {
|
||||
cam.setBrightness(cam.getCurrentPipeline().brightness);
|
||||
cam.setExposure(cam.getCurrentPipeline().exposure);
|
||||
|
||||
17
chameleon-client/package-lock.json
generated
17
chameleon-client/package-lock.json
generated
@@ -13493,7 +13493,8 @@
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
@@ -13502,7 +13503,8 @@
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -13605,7 +13607,8 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -13615,6 +13618,7 @@
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -13640,6 +13644,7 @@
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -13656,6 +13661,7 @@
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -13728,7 +13734,8 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -13738,6 +13745,7 @@
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -13843,6 +13851,7 @@
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
||||
@@ -1,95 +1,94 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<v-app-bar app dense clipped-left dark>
|
||||
<img class="imgClass" src="./assets/logo.png">
|
||||
<v-toolbar-title id="title">Chameleon Vision</v-toolbar-title>
|
||||
<div class="flex-grow-1"></div>
|
||||
<v-toolbar-items>
|
||||
<v-tabs dark height="48" slider-color="#4baf62">
|
||||
<v-tab to="vision">Vision</v-tab>
|
||||
<v-tab to="settings">Settings</v-tab>
|
||||
</v-tabs>
|
||||
</v-toolbar-items>
|
||||
</v-app-bar>
|
||||
<v-content>
|
||||
<v-container fluid fill-height>
|
||||
<v-layout>
|
||||
<v-flex>
|
||||
<router-view></router-view>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-content>
|
||||
</v-app>
|
||||
<v-app>
|
||||
<v-app-bar app dense clipped-left dark>
|
||||
<img class="imgClass" src="./assets/logo.png">
|
||||
<v-toolbar-title id="title">Chameleon Vision</v-toolbar-title>
|
||||
<div class="flex-grow-1"></div>
|
||||
<v-toolbar-items>
|
||||
<v-tabs dark height="48" slider-color="#4baf62">
|
||||
<v-tab to="vision">Vision</v-tab>
|
||||
<v-tab to="settings">Settings</v-tab>
|
||||
</v-tabs>
|
||||
</v-toolbar-items>
|
||||
</v-app-bar>
|
||||
<v-content>
|
||||
<v-container fluid fill-height>
|
||||
<v-layout>
|
||||
<v-flex>
|
||||
<router-view/>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-content>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
export default {
|
||||
name: 'App',
|
||||
|
||||
components: {
|
||||
components: {},
|
||||
methods: {
|
||||
handleMessage(key, value) {
|
||||
if (this.$store.state.hasOwnProperty(key)) {
|
||||
this.$store.commit(key, value);
|
||||
} else if (this.$store.state.pipeline.hasOwnProperty(key)) {
|
||||
this.$store.commit('setPipeValues', {[key]: value});
|
||||
} else {
|
||||
switch (key) {
|
||||
|
||||
},
|
||||
methods:{
|
||||
handleMessage(key,value){
|
||||
if(this.$store.state.hasOwnProperty(key)){
|
||||
this.$store.commit(key,value);
|
||||
} else if(this.$store.state.pipeline.hasOwnProperty(key)){
|
||||
this.$store.commit('setPipeValues',{[key]:value});
|
||||
}
|
||||
else{
|
||||
switch(key){
|
||||
|
||||
default:{
|
||||
console.log(key + " : " + value);
|
||||
}
|
||||
default: {
|
||||
console.log(key + " : " + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: () => ({}),
|
||||
created() {
|
||||
this.$options.sockets.onmessage = async (data) => {
|
||||
try {
|
||||
var buffer = await data.data.arrayBuffer();
|
||||
let message = this.$msgPack.decode(buffer);
|
||||
for (let prop in message) {
|
||||
if (message.hasOwnProperty(prop)) {
|
||||
this.handleMessage(prop, message[prop]);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('error: ' + data.data + " , " + error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
|
||||
}),
|
||||
created(){
|
||||
this.$options.sockets.onmessage = async (data) =>{
|
||||
try{
|
||||
var buffer = await data.data.arrayBuffer();
|
||||
let message = this.$msgPack.decode(buffer);
|
||||
for(let prop in message){
|
||||
if(message.hasOwnProperty(prop)){
|
||||
this.handleMessage(prop, message[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(error){
|
||||
console.error('error: ' + data.data+ " , "+ error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html{
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
.imgClass{
|
||||
width: auto;
|
||||
height: 45px;
|
||||
vertical-align: middle;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.tabClass{
|
||||
color: #4baf62;
|
||||
}
|
||||
.container{
|
||||
background-color: #212121;
|
||||
padding: 0!important;
|
||||
}
|
||||
#title{
|
||||
color:#4baf62;
|
||||
}
|
||||
span{
|
||||
color: white;
|
||||
}
|
||||
html {
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
|
||||
.imgClass {
|
||||
width: auto;
|
||||
height: 45px;
|
||||
vertical-align: middle;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.tabClass {
|
||||
color: #4baf62;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #212121;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
#title {
|
||||
color: #4baf62;
|
||||
}
|
||||
|
||||
span {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-row align="center" justify="start">
|
||||
<v-col style="padding-right:0" :cols="3">
|
||||
<v-btn small color="#4baf62" @click="takePointA">Take Point A</v-btn>
|
||||
</v-col>
|
||||
<v-col style="margin-left:0" :cols="3">
|
||||
<v-btn small color="#4baf62" @click="takePointB">Take Point B</v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn small @click="clearSlope" color="yellow darken-3">Clear All Points</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "DualCalibration",
|
||||
props: ['rawPoint'],
|
||||
data() {
|
||||
return {
|
||||
pointA: undefined,
|
||||
pointB: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
takePointA() {
|
||||
this.pointA = this.rawPoint;
|
||||
this.calcSlope();
|
||||
},
|
||||
takePointB() {
|
||||
this.pointB = this.rawPoint;
|
||||
this.calcSlope();
|
||||
},
|
||||
calcSlope() {
|
||||
if (this.pointA !== undefined && this.pointB !== undefined) {
|
||||
let m = (this.pointB[1] - this.pointA[1]) / (this.pointB[0] - this.pointA[0]);
|
||||
let b = this.pointA[1] - (m * this.pointA[0]);
|
||||
if (isNaN(m) === false && isNaN(b) === false) {
|
||||
this.sendSlope(m, b, true);
|
||||
} else {
|
||||
this.$emit('snackbar');
|
||||
}
|
||||
this.pointA = undefined;
|
||||
this.pointB = undefined;
|
||||
}
|
||||
},
|
||||
sendSlope(m, b, valid) {
|
||||
this.handleInput('m', m);
|
||||
this.handleInput('b', b);
|
||||
this.$emit('update');
|
||||
},
|
||||
clearSlope() {
|
||||
this.sendSlope(1, 0, false);
|
||||
this.pointA = undefined;
|
||||
this.pointB = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-row align="center" justify="start">
|
||||
<v-col style="padding-right:0" :cols="3">
|
||||
<v-btn small color="#4baf62" @click="takePoint">Take Point</v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn small @click="clearPoint" color="yellow darken-3">Clear Point</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SingleCalibration",
|
||||
props: ['rawPoint'],
|
||||
methods: {
|
||||
clearPoint() {
|
||||
this.handleInput('point', [0, 0]);
|
||||
this.$emit('update');
|
||||
},
|
||||
takePoint() {
|
||||
this.handleInput('point', this.rawPoint);
|
||||
this.$emit('update');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<v-tooltip :right="right" :bottom="!right" nudge-right="10">
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-icon :class="hoverClass" @click="handleClick" v-on="on" :color="color">{{text}}</v-icon>
|
||||
<v-icon :class="hoverClass" @click="handleClick" v-on="on" :color="color">{{text}}</v-icon>
|
||||
</template>
|
||||
<span>{{tooltip}}</span>
|
||||
</v-tooltip>
|
||||
@@ -12,20 +12,18 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Icon',
|
||||
props:['color','tooltip','text','right','hover'],
|
||||
props: ['color', 'tooltip', 'text', 'right', 'hover'],
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {}
|
||||
},
|
||||
methods:{
|
||||
handleClick(){
|
||||
methods: {
|
||||
handleClick() {
|
||||
this.$emit('click');
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
hoverClass(){
|
||||
if(this.hover !== undefined){
|
||||
computed: {
|
||||
hoverClass() {
|
||||
if (this.hover !== undefined) {
|
||||
return "hover";
|
||||
}
|
||||
}
|
||||
@@ -35,7 +33,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hover:hover{
|
||||
color: white !important;
|
||||
}
|
||||
.hover:hover {
|
||||
color: white !important;
|
||||
}
|
||||
</style>
|
||||
@@ -5,7 +5,8 @@
|
||||
<span>{{name}}</span>
|
||||
</v-col>
|
||||
<v-col :cols="9">
|
||||
<v-text-field @keydown="handleKeyboard" dark v-model="localValue" dense :disabled="disabled" :error-messages="errorMessage"></v-text-field>
|
||||
<v-text-field @keydown="handleKeyboard" dark v-model="localValue" dense :disabled="disabled"
|
||||
:error-messages="errorMessage"/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
@@ -14,26 +15,24 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Input',
|
||||
props:['name','value','disabled','errorMessage'],
|
||||
props: ['name', 'value', 'disabled', 'errorMessage'],
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {}
|
||||
},
|
||||
methods:{
|
||||
handleKeyboard(event){
|
||||
if(event.key == "Enter"){
|
||||
methods: {
|
||||
handleKeyboard(event) {
|
||||
if (event.key == "Enter") {
|
||||
this.$emit("Enter");
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
this.$emit('input',value);
|
||||
set(value) {
|
||||
this.$emit('input', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,5 +40,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -5,7 +5,8 @@
|
||||
<span>{{name}}</span>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field dark v-model="localValue" class="mt-0 pt-0" hide-details single-line type="number" style="width: 70px"></v-text-field>
|
||||
<v-text-field dark v-model="localValue" class="mt-0 pt-0" hide-details single-line type="number"
|
||||
style="width: 70px"/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
@@ -14,18 +15,16 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
props:['name','value'],
|
||||
props: ['name', 'value'],
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
set(value) {
|
||||
this.$emit('input', parseInt(value));
|
||||
}
|
||||
}
|
||||
@@ -34,5 +33,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-radio-group row v-model="localValue" dark :mandatory="true">
|
||||
<v-radio color="#4baf62" v-for="(name,index) in list" :label="name" v-bind:key="index" :value="index"></v-radio>
|
||||
<v-radio color="#4baf62" v-for="(name,index) in list" :label="name" v-bind:key="index" :value="index"/>
|
||||
</v-radio-group>
|
||||
</div>
|
||||
</template>
|
||||
@@ -9,19 +9,17 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Radio',
|
||||
props:['value','list'],
|
||||
props: ['value', 'list'],
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
this.$emit('input',value);
|
||||
set(value) {
|
||||
this.$emit('input', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,5 +27,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -5,13 +5,18 @@
|
||||
<span>{{name}}</span>
|
||||
</v-col>
|
||||
<v-col :cols="10">
|
||||
<v-range-slider :value="localValue" @input="handleInput" :max="max" :min="min" hide-details class="align-center" dark color="#4baf62" :step="step">
|
||||
<template v-slot:prepend>
|
||||
<v-text-field :value="localValue[0]" :max="max" :min="min" @input="handleChange" @focus="prependFocused = true" @blur="prependFocused = false" class="mt-0 pt-0" hide-details single-line type="number" style="width: 50px" :step="step"></v-text-field>
|
||||
<v-range-slider :value="localValue" @input="handleInput" :max="max" :min="min" hide-details
|
||||
class="align-center" dark color="#4baf62" :step="step">
|
||||
<template v-slot:prepend>
|
||||
<v-text-field :value="localValue[0]" :max="max" :min="min" @input="handleChange"
|
||||
@focus="prependFocused = true" @blur="prependFocused = false" class="mt-0 pt-0"
|
||||
hide-details single-line type="number" style="width: 50px" :step="step"/>
|
||||
</template>
|
||||
|
||||
<template v-slot:append>
|
||||
<v-text-field :value="localValue[1]" :max="max" :min="min" @input="handleChange" @focus="appendFocused = true" @blur="appendFocused = false" class="mt-0 pt-0" hide-details single-line type="number" style="width: 50px" :step="step"></v-text-field>
|
||||
<v-text-field :value="localValue[1]" :max="max" :min="min" @input="handleChange"
|
||||
@focus="appendFocused = true" @blur="appendFocused = false" class="mt-0 pt-0"
|
||||
hide-details single-line type="number" style="width: 50px" :step="step"/>
|
||||
</template>
|
||||
</v-range-slider>
|
||||
</v-col>
|
||||
@@ -22,43 +27,43 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'RangeSlider',
|
||||
props:['name','min','max','value','step'],
|
||||
props: ['name', 'min', 'max', 'value', 'step'],
|
||||
data() {
|
||||
return {
|
||||
prependFocused:false,
|
||||
appendFocused:false
|
||||
|
||||
prependFocused: false,
|
||||
appendFocused: false
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handleChange(val){
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
let i = 0;
|
||||
if(this.prependFocused === false && this.appendFocused === true){
|
||||
if (this.prependFocused === false && this.appendFocused === true) {
|
||||
i = 1;
|
||||
}
|
||||
if(this.prependFocused || this.appendFocused){
|
||||
this.$set(this.localValue,i,val);
|
||||
if (this.prependFocused || this.appendFocused) {
|
||||
this.$set(this.localValue, i, val);
|
||||
}
|
||||
},
|
||||
handleInput(val){
|
||||
if(!this.prependFocused || !this.appendFocused){
|
||||
this.localValue = val;
|
||||
handleInput(val) {
|
||||
if (!this.prependFocused || !this.appendFocused) {
|
||||
this.localValue = val;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
this.$emit('input',value)
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -5,7 +5,8 @@
|
||||
<span>{{name}}</span>
|
||||
</v-col>
|
||||
<v-col :cols="9">
|
||||
<v-select v-model="localValue" :items="indexList" item-text="name" item-value="index" dark color="#4baf62" item-color="green" :disabled="disabled"></v-select>
|
||||
<v-select v-model="localValue" :items="indexList" item-text="name" item-value="index" dark
|
||||
color="#4baf62" item-color="green" :disabled="disabled"/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
@@ -14,26 +15,26 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Select',
|
||||
props:['list','name','value','disabled'],
|
||||
props: ['list', 'name', 'value', 'disabled'],
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
return {}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
this.$emit('input',value)
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
},
|
||||
indexList(){
|
||||
indexList() {
|
||||
let list = []
|
||||
for(let i=0 ; i<this.list.length; i++){
|
||||
for (let i = 0; i < this.list.length; i++) {
|
||||
list.push({
|
||||
name:this.list[i],
|
||||
index:i});
|
||||
name: this.list[i],
|
||||
index: i
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
<span>{{name}}</span>
|
||||
</v-col>
|
||||
<v-col :cols="10">
|
||||
<v-slider :value="localValue" @input="handleInput" dark class="align-center" :max="max" :min="min" hide-details color="#4baf62" :step="step">
|
||||
<template v-slot:append>
|
||||
<v-text-field dark :max="max" :min="min" :value="localValue" @input="handleChange" @focus="isFocused = true" @blur="isFocused = false" class="mt-0 pt-0" hide-details single-line type="number" style="width: 50px" :step="step"></v-text-field>
|
||||
</template>
|
||||
</v-slider>
|
||||
<v-slider :value="localValue" @start="isClicked = true" @end="isClicked = false" @change="handleclick"
|
||||
@input="handleInput" dark class="align-center" :max="max" :min="min" hide-details
|
||||
color="#4baf62" :step="step">
|
||||
<template v-slot:append>
|
||||
<v-text-field dark :max="max" :min="min" :value="localValue" @input="handleChange"
|
||||
@focus="isFocused = true" @blur="isFocused = false" class="mt-0 pt-0" hide-details
|
||||
single-line type="number" style="width: 50px" :step="step"/>
|
||||
</template>
|
||||
</v-slider>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
@@ -18,31 +22,37 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Slider',
|
||||
props:['min','max','name','value','step'],
|
||||
props: ['min', 'max', 'name', 'value', 'step'],
|
||||
data() {
|
||||
return {
|
||||
isFocused:false
|
||||
isFocused: false,
|
||||
isClicked: false
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handleChange(val){
|
||||
if(this.isFocused){
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
if (this.isFocused) {
|
||||
this.localValue = parseFloat(val);
|
||||
}
|
||||
},
|
||||
handleInput(val){
|
||||
if(!this.isFocused){
|
||||
this.localValue = val;
|
||||
handleInput(val) {
|
||||
if (!this.isFocused && this.isClicked) {
|
||||
this.localValue = val;
|
||||
}
|
||||
},
|
||||
handleclick(val) {
|
||||
if (!this.isFocused) {
|
||||
this.localValue = val;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
this.$emit('input',value)
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,5 +60,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -5,7 +5,7 @@
|
||||
<span>{{name}}</span>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-switch v-model="localValue" color="#4baf62"></v-switch>
|
||||
<v-switch v-model="localValue" color="#4baf62"/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
@@ -14,19 +14,17 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'CVSwitch',
|
||||
props:['name','value'],
|
||||
props: ['name', 'value'],
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {}
|
||||
},
|
||||
computed:{
|
||||
localValue:{
|
||||
get(){
|
||||
computed: {
|
||||
localValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(value){
|
||||
this.$emit('input',value)
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,5 +32,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -8,19 +8,19 @@ import msgPack from 'msgpack5';
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
// Vue.use(VueNativeSock,'ws://' + location.host + '/websocket',{format: 'json'});
|
||||
Vue.use(VueNativeSock,'ws://'+location.hostname+':8888/websocket');
|
||||
Vue.use(VueNativeSock, 'ws://' + location.hostname + ':8888/websocket');
|
||||
Vue.prototype.$msgPack = msgPack(true)
|
||||
Vue.mixin({
|
||||
methods:{
|
||||
handleInput(key,value){
|
||||
let msg = this.$msgPack.encode({[key]:value})
|
||||
this.$socket.send(msg);
|
||||
methods: {
|
||||
handleInput(key, value) {
|
||||
let msg = this.$msgPack.encode({[key]: value})
|
||||
this.$socket.send(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
vuetify,
|
||||
render: h => h(App)
|
||||
router,
|
||||
store,
|
||||
vuetify,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
|
||||
import '@mdi/font/css/materialdesignicons.css';
|
||||
import 'material-design-icons-iconfont/dist/material-design-icons.css'
|
||||
import Vue from 'vue';
|
||||
import Vuetify from 'vuetify/lib';
|
||||
|
||||
Vue.use(Vuetify);
|
||||
|
||||
export default new Vuetify({
|
||||
icons: {
|
||||
|
||||
}
|
||||
|
||||
icons: {}
|
||||
|
||||
});
|
||||
|
||||
@@ -33,7 +33,8 @@ export default new Vuex.Store({
|
||||
targetGrouping:0,
|
||||
targetIntersection:0,
|
||||
sortMode:0,
|
||||
isBinary:0
|
||||
isBinary:0,
|
||||
calibrationMode:0
|
||||
},
|
||||
cameraSettings:{},
|
||||
resolutionList:[],
|
||||
@@ -54,7 +55,12 @@ export default new Vuex.Store({
|
||||
currentPipelineIndex: set('currentPipelineIndex'),
|
||||
cameraList: set('cameraList'),
|
||||
pipelineList: set('pipelineList'),
|
||||
point:set('point')
|
||||
point:set('point'),
|
||||
setPipeValues(state,obj){
|
||||
for(let i in obj){
|
||||
Vue.set(state.pipeline,i,obj[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
settings: state => state.settings,
|
||||
@@ -67,10 +73,5 @@ export default new Vuex.Store({
|
||||
cameraList: state =>state.cameraList,
|
||||
pipelineList: state =>state.pipelineList,
|
||||
point: state =>state.point,
|
||||
setPipeValues(state,obj){
|
||||
for(let i in obj){
|
||||
Vue.set(state.pipeline,i,obj[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,124 +4,154 @@
|
||||
<v-row align="center">
|
||||
<v-col :cols="3" class="colsClass">
|
||||
<div style="padding-left:30px">
|
||||
<CVselect v-if="isCameraNameEdit == false" name="Camera" v-model="currentCameraIndex" :list="cameraList" @input="handleInput('currentCamera',currentCameraIndex)"></CVselect>
|
||||
<CVinput v-else name="Camera" v-model="newCameraName" @Enter="saveCameraNameChange" :errorMessage="checkCameraName"></CVinput>
|
||||
<CVselect v-if="isCameraNameEdit === false" name="Camera" v-model="currentCameraIndex"
|
||||
:list="cameraList" @input="handleInput('currentCamera',currentCameraIndex)"/>
|
||||
<CVinput v-else name="Camera" v-model="newCameraName" @Enter="saveCameraNameChange"
|
||||
:errorMessage="checkCameraName"/>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col :cols="1">
|
||||
<CVicon color="#c5c5c5" v-if="isCameraNameEdit == false" hover text="edit" @click="toCameraNameChange" tooltip="Edit camera name"></CVicon>
|
||||
<CVicon color="#c5c5c5" v-if="isCameraNameEdit === false" hover text="edit"
|
||||
@click="toCameraNameChange" tooltip="Edit camera name"/>
|
||||
<div v-else>
|
||||
<CVicon color="#c5c5c5" style="display: inline-block;" hover text="save" @click="saveCameraNameChange" tooltip="Save Camera Name"></CVicon>
|
||||
<CVicon color="error" style="display: inline-block;" hover text="close" @click="discardCameraNameChange" tooltip="Discard Changes"></CVicon>
|
||||
<CVicon color="#c5c5c5" style="display: inline-block;" hover text="save"
|
||||
@click="saveCameraNameChange" tooltip="Save Camera Name"/>
|
||||
<CVicon color="error" style="display: inline-block;" hover text="close"
|
||||
@click="discardCameraNameChange" tooltip="Discard Changes"/>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col :cols="3" class="colsClass">
|
||||
<CVselect v-if="isPipelineEdit == false" name="Pipeline" :list="pipelineList" v-model="currentPipelineIndex" @input="handleInput('currentPipeline',currentPipelineIndex)"></CVselect>
|
||||
<CVinput v-else name="Pipeline" v-model="newPipelineName" @Enter="savePipelineNameChange"></CVinput>
|
||||
<CVselect v-if="isPipelineEdit === false" name="Pipeline" :list="pipelineList"
|
||||
v-model="currentPipelineIndex"
|
||||
@input="handleInput('currentPipeline',currentPipelineIndex)"/>
|
||||
<CVinput v-else name="Pipeline" v-model="newPipelineName" @Enter="savePipelineNameChange"/>
|
||||
</v-col>
|
||||
<v-col :cols="1" class="colsClass">
|
||||
<v-menu v-if="isPipelineEdit == false" offset-y dark auto>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-icon color="white" v-on="on">menu</v-icon>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<v-list-item @click="toPipelineNameChange">
|
||||
<v-list-item-title>
|
||||
<CVicon color="#c5c5c5" :right="true" text="edit" tooltip="Edit pipeline name"></CVicon>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="handleInput('command','addNewPipeline')">
|
||||
<v-list-item-title>
|
||||
<CVicon color="#c5c5c5" :right="true" text="add" tooltip="Add new pipeline"></CVicon>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteCurrentPipeline">
|
||||
<v-list-item-title>
|
||||
<CVicon color="red darken-2" :right="true" text="delete" tooltip="Delete pipeline"></CVicon>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="openDuplicateDialog">
|
||||
<v-list-item-title>
|
||||
<CVicon color="#c5c5c5" :right="true" text="mdi-content-copy" tooltip="Duplicate pipeline"></CVicon>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<div v-else>
|
||||
<CVicon color="#c5c5c5" style="display: inline-block;" hover text="save" @click="savePipelineNameChange" tooltip="Save Pipeline Name"></CVicon>
|
||||
<CVicon color="error" style="display: inline-block;" hover text="close" @click="discardPipelineNameChange" tooltip="Discard Changes"></CVicon>
|
||||
</div>
|
||||
<v-col :cols="1" class="colsClass" md="3">
|
||||
<v-menu v-if="isPipelineEdit === false" offset-y dark auto>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-icon color="white" v-on="on">menu</v-icon>
|
||||
</template>
|
||||
<v-list dense>
|
||||
<v-list-item @click="toPipelineNameChange">
|
||||
<v-list-item-title>
|
||||
<CVicon color="#c5c5c5" :right="true" text="edit" tooltip="Edit pipeline name"/>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="handleInput('command','addNewPipeline')">
|
||||
<v-list-item-title>
|
||||
<CVicon color="#c5c5c5" :right="true" text="add" tooltip="Add new pipeline"/>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="deleteCurrentPipeline">
|
||||
<v-list-item-title>
|
||||
<CVicon color="red darken-2" :right="true" text="delete"
|
||||
tooltip="Delete pipeline"/>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item @click="openDuplicateDialog">
|
||||
<v-list-item-title>
|
||||
<CVicon color="#c5c5c5" :right="true" text="mdi-content-copy"
|
||||
tooltip="Duplicate pipeline"/>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<div v-else>
|
||||
<CVicon color="#c5c5c5" style="display: inline-block;" hover text="save"
|
||||
@click="savePipelineNameChange" tooltip="Save Pipeline Name"/>
|
||||
<CVicon color="error" style="display: inline-block;" hover text="close"
|
||||
@click="discardPipelineNameChange" tooltip="Discard Changes"/>
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
|
||||
<v-btn style="position: absolute; top:5px;right: 0;" tile color="#4baf62"
|
||||
@click="handleInput('command','save')">
|
||||
<v-icon>save</v-icon>
|
||||
Save
|
||||
</v-btn>
|
||||
|
||||
</v-row>
|
||||
</div>
|
||||
<v-row>
|
||||
<!-- vision tabs -->
|
||||
<v-col cols="6" class="colsClass">
|
||||
<v-tabs fixed-tabs background-color="#212121" dark height="48" slider-color="#4baf62" v-model="selectedTab">
|
||||
<v-tabs fixed-tabs background-color="#212121" dark height="48" slider-color="#4baf62"
|
||||
v-model="selectedTab">
|
||||
<v-tab>Input</v-tab>
|
||||
<v-tab>Threshold</v-tab>
|
||||
<v-tab>Contours</v-tab>
|
||||
<v-tab>Output</v-tab>
|
||||
</v-tabs>
|
||||
<div style="padding-left:30px">
|
||||
<!-- vision component -->
|
||||
<component v-model="pipeline" :is="selectedComponent"></component>
|
||||
<keep-alive>
|
||||
<!-- vision component -->
|
||||
<component v-model="pipeline" :is="selectedComponent" @update="startTimer"/>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="6" class="colsClass">
|
||||
<div>
|
||||
<!-- camera image tabs -->
|
||||
<v-tabs background-color="#212121" dark height="48" slider-color="#4baf62" centered style="padding-bottom:10px" v-model="isBinaryNumber" @change="handleInput('isBinary',pipeline.isBinary)">
|
||||
<v-tabs background-color="#212121" dark height="48" slider-color="#4baf62" centered
|
||||
style="padding-bottom:10px" v-model="isBinaryNumber"
|
||||
@change="handleInput('isBinary',pipeline.isBinary)">
|
||||
<v-tab>Normal</v-tab>
|
||||
<v-tab>Threshold</v-tab>
|
||||
</v-tabs>
|
||||
<!-- camera image stream -->
|
||||
<div class="videoClass">
|
||||
<img v-if="cameraList.length > 0" :src="steamAdress">
|
||||
<img v-if="cameraList.length > 0" :src="streamAddress">
|
||||
<span v-else>No Cameras Are connected</span>
|
||||
<h5 id="Point">{{point}}</h5>
|
||||
</div>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<!-- pipeline duplicate dialog -->
|
||||
<v-dialog dark v-model="duplicateDialog" width="500" height="357" >
|
||||
<v-card dark>
|
||||
<v-card-title class="headline" primary-title>Duplicate Pipeline</v-card-title>
|
||||
</v-row>
|
||||
<!-- pipeline duplicate dialog -->
|
||||
<v-dialog dark v-model="duplicateDialog" width="500" height="357">
|
||||
<v-card dark>
|
||||
<v-card-title class="headline" primary-title>Duplicate Pipeline</v-card-title>
|
||||
<v-card-text>
|
||||
<CVselect name="Pipeline" :list="pipelineList" v-model="pipelineDuplicate.pipeline"></CVselect>
|
||||
<v-checkbox v-if="cameraList.length > 1" dark :label="'To another camera'" v-model="anotherCamera"></v-checkbox>
|
||||
<CVselect v-if="anotherCamera === true" name="Camera" v-model="pipelineDuplicate.camera" :list="cameraList"></CVselect>
|
||||
<CVselect name="Pipeline" :list="pipelineList" v-model="pipelineDuplicate.pipeline"/>
|
||||
<v-checkbox v-if="cameraList.length > 1" dark :label="'To another camera'" v-model="anotherCamera"/>
|
||||
<CVselect v-if="anotherCamera === true" name="Camera" v-model="pipelineDuplicate.camera"
|
||||
:list="cameraList"/>
|
||||
</v-card-text>
|
||||
<v-divider>
|
||||
</v-divider>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-spacer/>
|
||||
<v-btn color="#4baf62" text @click="duplicatePipeline">Duplicate</v-btn>
|
||||
<v-btn color="error" text @click="closeDuplicateDialog">Cancels</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<!-- snack bar -->
|
||||
<v-snackbar :timeout="3000" v-model="snackbar" top color="error">
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<!-- snack bar -->
|
||||
<v-snackbar :timeout="3000" v-model="snackbar" top color="error">
|
||||
<span style="color:#000">Can not remove the only pipeline!</span>
|
||||
<v-btn color="black" text @click="snackbar = false">Close</v-btn>
|
||||
</v-snackbar>
|
||||
</v-snackbar>
|
||||
<v-snackbar :timeout="1000" v-model="saveSnackbar" top color="#4baf62">
|
||||
<div style="text-align: center;width: 100%;">
|
||||
<h4>Saved All changes</h4>
|
||||
</div>
|
||||
|
||||
</v-snackbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import InputTab from './CameraViewes/InputTab'
|
||||
import ThresholdTab from './CameraViewes/ThresholdTab'
|
||||
import ContoursTab from './CameraViewes/ContoursTab'
|
||||
import OutputTab from './CameraViewes/OutputTab'
|
||||
import CVselect from '../components/cv-select'
|
||||
import CVicon from '../components/cv-icon'
|
||||
import CVinput from '../components/cv-input'
|
||||
import InputTab from './CameraViewes/InputTab'
|
||||
import ThresholdTab from './CameraViewes/ThresholdTab'
|
||||
import ContoursTab from './CameraViewes/ContoursTab'
|
||||
import OutputTab from './CameraViewes/OutputTab'
|
||||
import CVselect from '../components/cv-select'
|
||||
import CVicon from '../components/cv-icon'
|
||||
import CVinput from '../components/cv-input'
|
||||
|
||||
export default {
|
||||
name: 'CameraTab',
|
||||
components:{
|
||||
components: {
|
||||
InputTab,
|
||||
ThresholdTab,
|
||||
ContoursTab,
|
||||
@@ -130,107 +160,116 @@ import CVinput from '../components/cv-input'
|
||||
CVicon,
|
||||
CVinput
|
||||
},
|
||||
methods:{
|
||||
test(value){
|
||||
console.log(value)
|
||||
},
|
||||
toCameraNameChange(){
|
||||
methods: {
|
||||
toCameraNameChange() {
|
||||
this.newCameraName = this.cameraList[this.currentCameraIndex];
|
||||
this.isCameraNameEdit = true;
|
||||
},
|
||||
saveCameraNameChange(){
|
||||
if(this.cameraNameError === ""){
|
||||
this.handleInput("changeCameraName",this.newCameraName);
|
||||
this.discardCameraNameChange();
|
||||
saveCameraNameChange() {
|
||||
if (this.cameraNameError === "") {
|
||||
this.handleInput("changeCameraName", this.newCameraName);
|
||||
this.discardCameraNameChange();
|
||||
}
|
||||
},
|
||||
discardCameraNameChange(){
|
||||
discardCameraNameChange() {
|
||||
this.isCameraNameEdit = false;
|
||||
this.newCameraName = "";
|
||||
},
|
||||
toPipelineNameChange(){
|
||||
toPipelineNameChange() {
|
||||
this.newPipelineName = this.pipelineList[this.currentPipelineIndex];
|
||||
this.isPipelineEdit = true;
|
||||
},
|
||||
savePipelineNameChange(){
|
||||
this.handleInput("changePipelineName",this.newPipelineName);
|
||||
savePipelineNameChange() {
|
||||
this.handleInput("changePipelineName", this.newPipelineName);
|
||||
this.discardPipelineNameChange();
|
||||
},
|
||||
discardPipelineNameChange(){
|
||||
discardPipelineNameChange() {
|
||||
this.isPipelineEdit = false;
|
||||
this.newPipelineName = "";
|
||||
},
|
||||
duplicatePipeline(){
|
||||
if(!this.anotherCamera){
|
||||
duplicatePipeline() {
|
||||
if (!this.anotherCamera) {
|
||||
this.pipelineDuplicate.camera = -1
|
||||
}
|
||||
this.handleInput("duplicatePipeline",this.pipelineDuplicate);
|
||||
this.handleInput("duplicatePipeline", this.pipelineDuplicate);
|
||||
this.closeDuplicateDialog();
|
||||
},
|
||||
openDuplicateDialog(){
|
||||
openDuplicateDialog() {
|
||||
this.pipelineDuplicate = {
|
||||
pipeline:this.currentPipelineIndex,
|
||||
camera:-1
|
||||
pipeline: this.currentPipelineIndex,
|
||||
camera: -1
|
||||
}
|
||||
this.duplicateDialog = true;
|
||||
},
|
||||
closeDuplicateDialog(){
|
||||
closeDuplicateDialog() {
|
||||
this.duplicateDialog = false;
|
||||
this.pipelineDuplicate = {
|
||||
pipeline:undefined,
|
||||
camera:-1
|
||||
pipeline: undefined,
|
||||
camera: -1
|
||||
}
|
||||
},
|
||||
deleteCurrentPipeline(){
|
||||
deleteCurrentPipeline() {
|
||||
if (this.pipelineList.length > 1) {
|
||||
this.handleInput('command','deleteCurrentPipeline');
|
||||
this.handleInput('command', 'deleteCurrentPipeline');
|
||||
} else {
|
||||
this.snackbar = true;
|
||||
}
|
||||
},
|
||||
saveSettings() {
|
||||
clearInterval(this.timer);
|
||||
this.saveSnackbar = true;
|
||||
},
|
||||
startTimer() {
|
||||
if (this.timer !== undefined) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
this.timer = setInterval(this.saveSettings, 4000);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedTab:0,
|
||||
selectedTab: 1,
|
||||
// camera edit variables
|
||||
isCameraNameEdit:false,
|
||||
newCameraName:"",
|
||||
cameraNameError:"",
|
||||
isCameraNameEdit: false,
|
||||
newCameraName: "",
|
||||
cameraNameError: "",
|
||||
// pipeline edit variables
|
||||
isPipelineEdit:false,
|
||||
newPipelineName:"",
|
||||
duplicateDialog:false,
|
||||
anotherCamera:false,
|
||||
pipelineDuplicate:{
|
||||
pipeline:undefined,
|
||||
camera:-1
|
||||
isPipelineEdit: false,
|
||||
newPipelineName: "",
|
||||
duplicateDialog: false,
|
||||
anotherCamera: false,
|
||||
pipelineDuplicate: {
|
||||
pipeline: undefined,
|
||||
camera: -1
|
||||
},
|
||||
snackbar:false
|
||||
snackbar: false,
|
||||
saveSnackbar: false,
|
||||
timer: undefined
|
||||
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
checkCameraName(){
|
||||
if(this.newCameraName !== this.cameraList[this.currentCameraIndex]){
|
||||
for(let cam in this.cameraList){
|
||||
if(this.newCameraName == this.cameraList[cam]){
|
||||
computed: {
|
||||
checkCameraName() {
|
||||
if (this.newCameraName !== this.cameraList[this.currentCameraIndex]) {
|
||||
for (let cam in this.cameraList) {
|
||||
if (this.newCameraName === this.cameraList[cam]) {
|
||||
return "Camera by that name already Exists"
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
},
|
||||
isBinaryNumber:{
|
||||
get(){
|
||||
return this.pipeline.isBinary ? 1:0
|
||||
isBinaryNumber: {
|
||||
get() {
|
||||
return this.pipeline.isBinary ? 1 : 0
|
||||
},
|
||||
set(value){
|
||||
set(value) {
|
||||
this.pipeline.isBinary = !!value;
|
||||
}
|
||||
},
|
||||
selectedComponent:{
|
||||
get(){
|
||||
switch(this.selectedTab){
|
||||
selectedComponent: {
|
||||
get() {
|
||||
switch (this.selectedTab) {
|
||||
case 0:
|
||||
return "InputTab";
|
||||
case 1:
|
||||
@@ -243,51 +282,51 @@ import CVinput from '../components/cv-input'
|
||||
return "";
|
||||
}
|
||||
},
|
||||
point:{
|
||||
get:function(){
|
||||
point: {
|
||||
get: function () {
|
||||
let p = this.$store.state.point.calculated;
|
||||
let fps = this.$store.state.point.fps;
|
||||
if(p !== undefined){
|
||||
if (p !== undefined) {
|
||||
return ("Pitch: " + parseFloat(p['pitch']).toFixed(2) + " Yaw: " + parseFloat(p['yaw']).toFixed(2) + " FPS: " + fps.toFixed(2))
|
||||
} else{
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
currentCameraIndex:{
|
||||
get(){
|
||||
currentCameraIndex: {
|
||||
get() {
|
||||
return this.$store.state.currentCameraIndex;
|
||||
},
|
||||
set(value){
|
||||
this.$store.commit('currentCameraIndex',value);
|
||||
set(value) {
|
||||
this.$store.commit('currentCameraIndex', value);
|
||||
}
|
||||
},
|
||||
currentPipelineIndex:{
|
||||
get(){
|
||||
currentPipelineIndex: {
|
||||
get() {
|
||||
return this.$store.state.currentPipelineIndex;
|
||||
},
|
||||
set(value){
|
||||
this.$store.commit('currentPipelineIndex',value);
|
||||
set(value) {
|
||||
this.$store.commit('currentPipelineIndex', value);
|
||||
}
|
||||
},
|
||||
cameraList:{
|
||||
get(){
|
||||
cameraList: {
|
||||
get() {
|
||||
return this.$store.state.cameraList;
|
||||
}
|
||||
},
|
||||
pipelineList:{
|
||||
get(){
|
||||
pipelineList: {
|
||||
get() {
|
||||
return this.$store.state.pipelineList;
|
||||
}
|
||||
},
|
||||
pipeline:{
|
||||
get(){
|
||||
pipeline: {
|
||||
get() {
|
||||
return this.$store.state.pipeline;
|
||||
}
|
||||
},
|
||||
steamAdress: {
|
||||
get: function(){
|
||||
return "http://"+location.hostname + ":"+ this.$store.state.port +"/stream.mjpg";
|
||||
streamAddress: {
|
||||
get: function () {
|
||||
return "http://" + location.hostname + ":" + this.$store.state.port + "/stream.mjpg";
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -295,19 +334,22 @@ import CVinput from '../components/cv-input'
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.colsClass{
|
||||
.colsClass {
|
||||
padding: 0 !important;
|
||||
|
||||
|
||||
}
|
||||
.videoClass{
|
||||
|
||||
.videoClass {
|
||||
text-align: center;
|
||||
}
|
||||
.videoClass img{
|
||||
|
||||
.videoClass img {
|
||||
height: auto !important;
|
||||
width: 70%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#Point{
|
||||
|
||||
#Point {
|
||||
padding-top: 5px;
|
||||
text-align: center;
|
||||
color: #f4f4f4;
|
||||
|
||||
@@ -1,35 +1,47 @@
|
||||
<template>
|
||||
<div>
|
||||
<CVrangeSlider v-model="value.area" name="Area" :min="0" :max="100" :step="0.1" @input="handleInput('area',value.area)"></CVrangeSlider>
|
||||
<CVrangeSlider v-model="value.ratio" name="Ratio (W/H)" :min="0" :max="100" :step="0.1" @input="handleInput('ratio',value.ratio)"></CVrangeSlider>
|
||||
<CVrangeSlider v-model="value.extent" name="Extent" :min="0" :max="100" @input="handleInput('extent',value.extent)"></CVrangeSlider>
|
||||
<CVslider name="Speckle Rejection" :min="0" :max="100" v-model="value.speckle" @input="handleInput('speckle',value.speckle)"></CVslider>
|
||||
<CVselect name="Target Group" :list="['Single','Dual']" v-model="value.targetGroup" @input="handleInput('targetGroup',value.targetGroup)"></CVselect>
|
||||
<CVselect name="Target Intersection" :list="['None','Up','Down','Left','Right']" :disabled="isDisabled" v-model="value.targetIntersection" @input="handleInput('targetIntersection',value.targetIntersection)"></CVselect>
|
||||
<CVrangeSlider v-model="value.area" name="Area" :min="0" :max="100" :step="0.1"
|
||||
@input="handleData('area')"/>
|
||||
<CVrangeSlider v-model="value.ratio" name="Ratio (W/H)" :min="0" :max="100" :step="0.1"
|
||||
@input="handleData('ratio')"/>
|
||||
<CVrangeSlider v-model="value.extent" name="Extent" :min="0" :max="100"
|
||||
@input="handleData('extent')"/>
|
||||
<CVslider name="Speckle Rejection" :min="0" :max="100" v-model="value.speckle"
|
||||
@input="handleData('speckle')"/>
|
||||
<CVselect name="Target Group" :list="['Single','Dual']" v-model="value.targetGroup"
|
||||
@input="handleData('targetGroup')"/>
|
||||
<CVselect name="Target Intersection" :list="['None','Up','Down','Left','Right']" :disabled="isDisabled"
|
||||
v-model="value.targetIntersection" @input="handleData('targetIntersection')"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CVrangeSlider from '../../components/cv-range-slider'
|
||||
import CVselect from '../../components/cv-select'
|
||||
import CVslider from '../../components/cv-slider'
|
||||
import CVrangeSlider from '../../components/cv-range-slider'
|
||||
import CVselect from '../../components/cv-select'
|
||||
import CVslider from '../../components/cv-slider'
|
||||
|
||||
export default {
|
||||
name: 'Contours',
|
||||
props:['value'],
|
||||
components:{
|
||||
props: ['value'],
|
||||
components: {
|
||||
CVrangeSlider,
|
||||
CVselect,
|
||||
CVslider
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
methods: {
|
||||
handleData(val) {
|
||||
this.handleInput(val, this.value[val])
|
||||
this.$emit('update')
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
isDisabled(){
|
||||
if(this.value.targetGroup === 0){
|
||||
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
isDisabled() {
|
||||
if (this.value.targetGroup === 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -39,5 +51,5 @@ import CVslider from '../../components/cv-slider'
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,34 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<CVslider name="Exposure" v-model="value.exposure" :min="0" :max="100" @input="handleInput('exposure',value.exposure)"></CVslider>
|
||||
<CVslider name="Brightness" v-model="value.brightness" :min="0" :max="100" @input="handleInput('brightness',value.brightness)"></CVslider>
|
||||
<CVselect name="Orientation" v-model="value.orientation" :list="['Normal','Inverted']" @input="handleInput('orientation',value.orientation)"></CVselect>
|
||||
<CVslider name="Exposure" v-model="value.exposure" :min="0" :max="100" @input="handleData('exposure')"/>
|
||||
<CVslider name="Brightness" v-model="value.brightness" :min="0" :max="100" @input="handleData('brightness')"/>
|
||||
<CVselect name="Orientation" v-model="value.orientation" :list="['Normal','Inverted']"
|
||||
@input="handleData('orientation')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CVslider from '../../components/cv-slider'
|
||||
import CVselect from '../../components/cv-select'
|
||||
import CVslider from '../../components/cv-slider'
|
||||
import CVselect from '../../components/cv-select'
|
||||
|
||||
export default {
|
||||
name: 'Input',
|
||||
props:['value'],
|
||||
components:{
|
||||
props: ['value'],
|
||||
components: {
|
||||
CVslider,
|
||||
CVselect,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
t:0,
|
||||
a:1
|
||||
methods: {
|
||||
handleData(val) {
|
||||
this.handleInput(val, this.value[val])
|
||||
this.$emit('update')
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
data() {
|
||||
return {
|
||||
t: 0,
|
||||
a: 1
|
||||
}
|
||||
},
|
||||
computed:{}
|
||||
computed: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,19 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<CVselect name="SortMode" v-model="value.sortMode" :list="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Centermost']" @input="handleInput('sortMode',value.sortMode)"></CVselect>
|
||||
<span>Calibrate:</span><v-divider dark color="white"></v-divider>
|
||||
<v-row align="center" justify="start">
|
||||
<v-col style="padding-right:0px" :cols="3">
|
||||
<v-btn small color="#4baf62" @click="takePointA">Take Point A</v-btn>
|
||||
</v-col>
|
||||
<v-col style="margin-left:0px" :cols="3">
|
||||
<v-btn small color="#4baf62" @click="takePointB">Take Point B</v-btn>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn small @click="clearSlope" color="yellow darken-3">Clear All Points</v-btn>
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
<CVselect name="SortMode" v-model="value.sortMode"
|
||||
:list="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Closest']"
|
||||
@input="handleData('sortMode')"/>
|
||||
<span>Calibrate:</span>
|
||||
<v-divider dark color="white"/>
|
||||
<CVselect name="Calibration Mode" v-model="value.calibrationMode" :list="['None','Single point','Dual point']"
|
||||
@input="handleData('calibrationMode')"/>
|
||||
<component :raw-point="rawPoint" :is="selectedComponent" @update="doUpdate"/>
|
||||
<v-snackbar :timeout="3000" v-model="snackbar" top color="error">
|
||||
<span style="color:#000">Points are too close</span>
|
||||
<v-btn color="black" text @click="snackbar = false">Close</v-btn>
|
||||
@@ -22,57 +16,50 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CVselect from '../../components/cv-select'
|
||||
import CVselect from '../../components/cv-select'
|
||||
import DualCalibration from "../../components/OutputTab/DualCalibration";
|
||||
import SingleCalibration from "../../components/OutputTab/SingleCalibration";
|
||||
|
||||
export default {
|
||||
name: 'Output',
|
||||
props:['value'],
|
||||
components:{
|
||||
CVselect
|
||||
props: ['value'],
|
||||
components: {
|
||||
CVselect,
|
||||
SingleCalibration,
|
||||
DualCalibration,
|
||||
|
||||
},
|
||||
methods:{
|
||||
takePointA(){
|
||||
this.pointA = this.rawPoint;
|
||||
this.calcSlope();
|
||||
methods: {
|
||||
handleData(val) {
|
||||
this.handleInput(val, this.value[val])
|
||||
this.$emit('update')
|
||||
},
|
||||
takePointB(){
|
||||
this.pointB = this.rawPoint;
|
||||
this.calcSlope();
|
||||
},
|
||||
calcSlope(){
|
||||
if(this.pointA !== undefined && this.pointB !== undefined){
|
||||
let m = (this.pointB[1] - this.pointA[1]) / (this.pointB[0] - this.pointA[0]);
|
||||
let b = this.pointA[1] - (m * this.pointA[0]);
|
||||
if(isNaN(m) === false && isNaN(b) === false){
|
||||
this.sendSlope(m,b,true);
|
||||
} else {
|
||||
this.snackbar = true;
|
||||
}
|
||||
this.pointA = undefined;
|
||||
this.pointB = undefined;
|
||||
}
|
||||
},
|
||||
sendSlope(m,b,valid){
|
||||
this.handleInput('m',m);
|
||||
this.handleInput('b',b);
|
||||
this.handleInput('isCalibrated',valid);
|
||||
},
|
||||
clearSlope(){
|
||||
this.sendSlope(1,0,false);
|
||||
this.pointA = undefined;
|
||||
this.pointB = undefined;
|
||||
doUpdate() {
|
||||
this.$emit('update')
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
snackbar: false,
|
||||
pointA: undefined,
|
||||
pointB: undefined
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
rawPoint:{
|
||||
get(){
|
||||
computed: {
|
||||
selectedComponent: {
|
||||
get() {
|
||||
switch (this.value.calibrationMode) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return "SingleCalibration";
|
||||
case 2:
|
||||
return "DualCalibration"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
},
|
||||
rawPoint: {
|
||||
get() {
|
||||
return this.$store.state.point.rawPoint;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<CVrangeSlider v-model="value.hue" name="Hue" :min="0" :max="180" @input="handleInput('hue',value.hue)"></CVrangeSlider>
|
||||
<CVrangeSlider v-model="value.saturation" name="Saturation" :min="0" :max="255" @input="handleInput('saturation',value.saturation)"></CVrangeSlider>
|
||||
<CVrangeSlider v-model="value.value" name="Value" :min="0" :max="255" @input="handleInput('value',value.value)"></CVrangeSlider>
|
||||
<CVswitch v-model="value.erode" name="Erode" @input="handleInput('erode',value.erode)"></CVswitch>
|
||||
<CVswitch v-model="value.dilate" name="Dilate" @input="handleInput('dilate',value.dilate)"></CVswitch>
|
||||
<CVrangeSlider v-model="value.hue" name="Hue" :min="0" :max="180" @input="handleData('hue')"/>
|
||||
<CVrangeSlider v-model="value.saturation" name="Saturation" :min="0" :max="255"
|
||||
@input="handleData('saturation')"/>
|
||||
<CVrangeSlider v-model="value.value" name="Value" :min="0" :max="255" @input="handleData('value')"/>
|
||||
<CVswitch v-model="value.erode" name="Erode" @input="handleData('erode')"/>
|
||||
<CVswitch v-model="value.dilate" name="Dilate" @input="handleData('dilate')"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -25,6 +26,10 @@ import CVswitch from '../../components/cv-switch'
|
||||
computed:{
|
||||
},
|
||||
methods:{
|
||||
handleData(val){
|
||||
this.handleInput(val,this.value[val])
|
||||
this.$emit('update')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
<div>
|
||||
<v-row>
|
||||
<v-col cols="6" class="colsClass">
|
||||
<v-tabs fixed-tabs background-color="#212121" dark height="50" slider-color="#4baf62" v-model="selectedTab">
|
||||
<v-tabs fixed-tabs background-color="#212121" dark height="50" slider-color="#4baf62"
|
||||
v-model="selectedTab">
|
||||
<v-tab to="">General</v-tab>
|
||||
<v-tab to="">Cameras</v-tab>
|
||||
</v-tabs>
|
||||
<div style="padding-left:30px">
|
||||
<component :is="selectedComponent"></component>
|
||||
<component :is="selectedComponent"/>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col v-show="selectedTab === 1" class="colsClass">
|
||||
@@ -15,28 +16,28 @@
|
||||
<img :src="steamAdress">
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import General from './SettingsViewes/General'
|
||||
import Cameras from './SettingsViewes/Cameras'
|
||||
import General from './SettingsViewes/General'
|
||||
import Cameras from './SettingsViewes/Cameras'
|
||||
|
||||
export default {
|
||||
name: 'SettingsTab',
|
||||
components:{
|
||||
components: {
|
||||
General,
|
||||
Cameras,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedTab:0,
|
||||
selectedTab: 0,
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
selectedComponent(){
|
||||
switch(this.selectedTab){
|
||||
computed: {
|
||||
selectedComponent() {
|
||||
switch (this.selectedTab) {
|
||||
case 0:
|
||||
return "General";
|
||||
case 1:
|
||||
@@ -44,8 +45,8 @@ import Cameras from './SettingsViewes/Cameras'
|
||||
}
|
||||
},
|
||||
steamAdress: {
|
||||
get: function(){
|
||||
return "http://"+location.hostname + ":"+ this.$store.state.port +"/stream.mjpg";
|
||||
get: function () {
|
||||
return "http://" + location.hostname + ":" + this.$store.state.port + "/stream.mjpg";
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -53,16 +54,18 @@ import Cameras from './SettingsViewes/Cameras'
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.videoClass{
|
||||
.videoClass {
|
||||
text-align: center;
|
||||
}
|
||||
.videoClass img{
|
||||
|
||||
.videoClass img {
|
||||
padding-top: 10px;
|
||||
height: auto !important;
|
||||
width: 75%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.colsClass{
|
||||
|
||||
.colsClass {
|
||||
padding: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,69 +1,69 @@
|
||||
<template>
|
||||
<div>
|
||||
<CVselect name="Camera" :list="cameraList" v-model="currentCameraIndex"></CVselect>
|
||||
<CVselect name="Resolution" v-model="cameraSettings.resolution" :list="resolutionList"></CVselect>
|
||||
<CVselect name="Stream Resolution" v-model="cameraSettings.streamDivisor" :list="['1:1','1:2','1:4','1:6']"></CVselect>
|
||||
<CVnumberinput name="Diagonal FOV" v-model="cameraSettings.fov" ></CVnumberinput>
|
||||
<CVselect name="Camera" :list="cameraList" v-model="currentCameraIndex"/>
|
||||
<CVselect name="Resolution" v-model="cameraSettings.resolution" :list="resolutionList"/>
|
||||
<CVselect name="Stream Resolution" v-model="cameraSettings.streamDivisor"
|
||||
:list="['1:1','1:2','1:4','1:6']"/>
|
||||
<CVnumberinput name="Diagonal FOV" v-model="cameraSettings.fov"/>
|
||||
<v-btn style="margin-top:10px" small color="#4baf62" @click="sendCameraSettings">Save Camera Settings</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CVselect from '../../components/cv-select'
|
||||
import CVnumberinput from '../../components/cv-number-input'
|
||||
import CVselect from '../../components/cv-select'
|
||||
import CVnumberinput from '../../components/cv-number-input'
|
||||
|
||||
export default {
|
||||
name: 'CameraSettings',
|
||||
components:{
|
||||
components: {
|
||||
CVselect,
|
||||
CVnumberinput
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
return {}
|
||||
},
|
||||
methods:{
|
||||
sendCameraSettings(){
|
||||
this.handleInput('cameraSettings',this.cameraSettings);
|
||||
methods: {
|
||||
sendCameraSettings() {
|
||||
this.handleInput('cameraSettings', this.cameraSettings);
|
||||
},
|
||||
|
||||
},
|
||||
computed:{
|
||||
|
||||
currentCameraIndex:{
|
||||
get(){
|
||||
},
|
||||
computed: {
|
||||
|
||||
currentCameraIndex: {
|
||||
get() {
|
||||
return this.$store.state.currentCameraIndex;
|
||||
},
|
||||
set(value){
|
||||
this.$store.commit('currentCameraIndex',value);
|
||||
set(value) {
|
||||
this.$store.commit('currentCameraIndex', value);
|
||||
}
|
||||
},
|
||||
cameraList:{
|
||||
get(){
|
||||
cameraList: {
|
||||
get() {
|
||||
return this.$store.state.cameraList;
|
||||
},
|
||||
set(value){
|
||||
this.$store.commit('cameraList',value);
|
||||
set(value) {
|
||||
this.$store.commit('cameraList', value);
|
||||
}
|
||||
},
|
||||
resolutionList:{
|
||||
get(){
|
||||
resolutionList: {
|
||||
get() {
|
||||
return this.$store.state.resolutionList;
|
||||
}
|
||||
},
|
||||
cameraSettings:{
|
||||
get(){
|
||||
cameraSettings: {
|
||||
get() {
|
||||
return this.$store.state.cameraSettings;
|
||||
},
|
||||
set(value){
|
||||
this.$store.commit('cameraSettings',value);
|
||||
set(value) {
|
||||
this.$store.commit('cameraSettings', value);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,46 +1,46 @@
|
||||
<template>
|
||||
<div>
|
||||
<CVnumberinput v-model="settings.teamNumber" name="Team Number"></CVnumberinput>
|
||||
<CVradio v-model="settings.connectionType" :list="['DHCP','Static']"></CVradio>
|
||||
<v-divider color="white"></v-divider>
|
||||
<CVinput name="IP" v-model="settings.ip" :disabled="isDisabled"></CVinput>
|
||||
<CVinput name="NetMask" v-model="settings.netmask" :disabled="isDisabled"></CVinput>
|
||||
<CVinput name="Gateway" v-model="settings.gateway" :disabled="isDisabled"></CVinput>
|
||||
<v-divider color="white"></v-divider>
|
||||
<CVinput name="Hostname" v-model="settings.hostname"></CVinput>
|
||||
<CVnumberinput v-model="settings.teamNumber" name="Team Number"/>
|
||||
<CVradio v-model="settings.connectionType" :list="['DHCP','Static']"/>
|
||||
<v-divider color="white"/>
|
||||
<CVinput name="IP" v-model="settings.ip" :disabled="isDisabled"/>
|
||||
<CVinput name="NetMask" v-model="settings.netmask" :disabled="isDisabled"/>
|
||||
<CVinput name="Gateway" v-model="settings.gateway" :disabled="isDisabled"/>
|
||||
<v-divider color="white"/>
|
||||
<CVinput name="Hostname" v-model="settings.hostname"/>
|
||||
<v-btn style="margin-top:10px" small color="#4baf62" @click="sendGeneralSettings">Save General Settings</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CVnumberinput from '../../components/cv-number-input'
|
||||
import CVradio from '../../components/cv-radio'
|
||||
import CVinput from '../../components/cv-input'
|
||||
import CVnumberinput from '../../components/cv-number-input'
|
||||
import CVradio from '../../components/cv-radio'
|
||||
import CVinput from '../../components/cv-input'
|
||||
|
||||
export default {
|
||||
name: 'General',
|
||||
components:{
|
||||
components: {
|
||||
CVnumberinput,
|
||||
CVradio,
|
||||
CVinput
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
sendGeneralSettings() {
|
||||
this.handleInput('generalSettings', this.settings);
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
sendGeneralSettings(){
|
||||
this.handleInput('generalSettings',this.settings);
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
isDisabled(){
|
||||
if(this.settings.connectionType === 0){
|
||||
computed: {
|
||||
isDisabled() {
|
||||
if (this.settings.connectionType === 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
settings:{
|
||||
get(){
|
||||
settings: {
|
||||
get() {
|
||||
return this.$store.state.settings;
|
||||
}
|
||||
}
|
||||
@@ -49,5 +49,5 @@ import CVinput from '../../components/cv-input'
|
||||
</script>
|
||||
|
||||
<style lang="" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user