mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-29 02:21:41 +00:00
Separate AWB gain slider (#410)
Makes gain adjust digital gain, adds sliders for red/blue on picam Co-authored-by: Chris Gerth <chrisgerth010592@gmail.com>
This commit is contained in:
@@ -55,7 +55,8 @@ export default new Vuex.Store({
|
||||
// Settings that apply to all pipeline types
|
||||
cameraExposure: 1,
|
||||
cameraBrightness: 2,
|
||||
cameraGain: 3,
|
||||
cameraRedGain: 3,
|
||||
cameraBlueGain: 4,
|
||||
inputImageRotationMode: 0,
|
||||
cameraVideoModeIndex: 0,
|
||||
streamingFrameDivisor: 0,
|
||||
|
||||
@@ -196,13 +196,24 @@
|
||||
@input="e => handlePipelineUpdate('cameraBrightness', e)"
|
||||
/>
|
||||
<CVslider
|
||||
v-if="$store.getters.currentPipelineSettings.cameraGain !== -1"
|
||||
v-model="$store.getters.currentPipelineSettings.cameraGain"
|
||||
name="Gain"
|
||||
:min="0"
|
||||
:max="100"
|
||||
slider-cols="8"
|
||||
@input="e => handlePipelineUpdate('cameraGain', e)"
|
||||
v-if="$store.getters.currentPipelineSettings.cameraRedGain !== -1"
|
||||
v-model="$store.getters.currentPipelineSettings.cameraRedGain"
|
||||
name="Red AWB Gain"
|
||||
min="0"
|
||||
max="100"
|
||||
tooltip="Controls red automatic white balance gain, which affects how the camera captures colors in different conditions"
|
||||
:slider-cols="8"
|
||||
@input="e => handlePipelineData('cameraRedGain', e)"
|
||||
/>
|
||||
<CVslider
|
||||
v-if="$store.getters.currentPipelineSettings.cameraBlueGain !== -1"
|
||||
v-model="$store.getters.currentPipelineSettings.cameraBlueGain"
|
||||
name="Blue AWB Gain"
|
||||
min="0"
|
||||
max="100"
|
||||
tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
|
||||
:slider-cols="8"
|
||||
@input="e => handlePipelineData('cameraBlueGain', e)"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
@@ -22,15 +22,26 @@
|
||||
@rollback="e => rollback('cameraBrightness', e)"
|
||||
/>
|
||||
<CVslider
|
||||
v-if="cameraGain !== -1"
|
||||
v-model="cameraGain"
|
||||
name="Gain"
|
||||
v-if="cameraRedGain !== -1"
|
||||
v-model="cameraRedGain"
|
||||
name="Red AWB Gain"
|
||||
min="0"
|
||||
max="100"
|
||||
tooltip="Controls automatic white balance gain, which affects how the camera captures colors in different conditions"
|
||||
tooltip="Controls red automatic white balance gain, which affects how the camera captures colors in different conditions"
|
||||
:slider-cols="largeBox"
|
||||
@input="handlePipelineData('cameraGain')"
|
||||
@rollback="e => rollback('cameraGain', e)"
|
||||
@input="handlePipelineData('cameraRedGain')"
|
||||
@rollback="e => rollback('cameraRedGain', e)"
|
||||
/>
|
||||
<CVslider
|
||||
v-if="cameraBlueGain !== -1"
|
||||
v-model="cameraBlueGain"
|
||||
name="Blue AWB Gain"
|
||||
min="0"
|
||||
max="100"
|
||||
tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
|
||||
:slider-cols="largeBox"
|
||||
@input="handlePipelineData('cameraBlueGain')"
|
||||
@rollback="e => rollback('cameraBlueGain', e)"
|
||||
/>
|
||||
<CVselect
|
||||
v-model="inputImageRotationMode"
|
||||
@@ -105,12 +116,20 @@
|
||||
this.$store.commit("mutatePipeline", {"cameraBrightness": parseInt(val)});
|
||||
}
|
||||
},
|
||||
cameraGain: {
|
||||
cameraRedGain: {
|
||||
get() {
|
||||
return parseInt(this.$store.getters.currentPipelineSettings.cameraGain)
|
||||
return parseInt(this.$store.getters.currentPipelineSettings.cameraRedGain)
|
||||
},
|
||||
set(val) {
|
||||
this.$store.commit("mutatePipeline", {"cameraGain": parseInt(val)});
|
||||
this.$store.commit("mutatePipeline", {"cameraRedGain": parseInt(val)});
|
||||
}
|
||||
},
|
||||
cameraBlueGain: {
|
||||
get() {
|
||||
return parseInt(this.$store.getters.currentPipelineSettings.cameraBlueGain)
|
||||
},
|
||||
set(val) {
|
||||
this.$store.commit("mutatePipeline", {"cameraBlueGain": parseInt(val)});
|
||||
}
|
||||
},
|
||||
inputImageRotationMode: {
|
||||
|
||||
@@ -140,8 +140,12 @@ public class PicamJNI {
|
||||
|
||||
public static native boolean setBrightness(int brightness);
|
||||
|
||||
// This adjusts the analog gain (normalized to 0-100); ignores the digital gain
|
||||
public static native boolean setGain(int gain);
|
||||
|
||||
// Adjusts the auto white balance gains, which are normalized 0-100 in the native code
|
||||
public static native boolean setAwbGain(int red, int blue);
|
||||
|
||||
public static native boolean setRotation(int rotation);
|
||||
|
||||
public static native void setShouldCopyColor(boolean shouldCopyColor);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.photonvision.vision.camera;
|
||||
|
||||
import edu.wpi.first.cscore.VideoMode;
|
||||
import edu.wpi.first.math.Pair;
|
||||
import java.util.HashMap;
|
||||
import org.photonvision.common.configuration.CameraConfiguration;
|
||||
import org.photonvision.common.configuration.ConfigManager;
|
||||
@@ -84,9 +85,10 @@ public class ZeroCopyPicamSource extends VisionSource {
|
||||
|
||||
public static class PicamSettables extends VisionSourceSettables {
|
||||
private FPSRatedVideoMode currentVideoMode;
|
||||
private double lastExposure;
|
||||
private int lastBrightness;
|
||||
private int lastGain;
|
||||
private double lastExposure = 50;
|
||||
private int lastBrightness = 50;
|
||||
private int lastGain = 50;
|
||||
private Pair<Integer, Integer> lastAwbGains = new Pair(18, 18);
|
||||
|
||||
public PicamSettables(CameraConfiguration configuration) {
|
||||
super(configuration);
|
||||
@@ -137,21 +139,38 @@ public class ZeroCopyPicamSource extends VisionSource {
|
||||
public void setExposure(double exposure) {
|
||||
lastExposure = exposure;
|
||||
var failure = PicamJNI.setExposure((int) Math.round(exposure));
|
||||
if (failure) logger.warn("Couldn't set Pi camera exposure");
|
||||
if (failure) logger.warn("Couldn't set Pi Camera exposure");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightness(int brightness) {
|
||||
lastBrightness = brightness;
|
||||
var failure = PicamJNI.setBrightness(brightness);
|
||||
if (failure) logger.warn("Couldn't set Pi camera brightness");
|
||||
if (failure) logger.warn("Couldn't set Pi Camera brightness");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGain(int gain) {
|
||||
lastGain = gain;
|
||||
var failure = PicamJNI.setGain(gain);
|
||||
if (failure) logger.warn("Couldn't set Pi camera gain");
|
||||
if (failure) logger.warn("Couldn't set Pi Camera gain");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedGain(int red) {
|
||||
lastAwbGains = Pair.of(red, lastAwbGains.getSecond());
|
||||
setAwbGain(lastAwbGains.getFirst(), lastAwbGains.getSecond());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlueGain(int blue) {
|
||||
lastAwbGains = Pair.of(lastAwbGains.getFirst(), blue);
|
||||
setAwbGain(lastAwbGains.getFirst(), lastAwbGains.getSecond());
|
||||
}
|
||||
|
||||
public void setAwbGain(int red, int blue) {
|
||||
var failure = PicamJNI.setAwbGain(red, blue);
|
||||
if (failure) logger.warn("Couldn't set Pi Camera AWB gains");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,17 +184,18 @@ public class ZeroCopyPicamSource extends VisionSource {
|
||||
var failure = PicamJNI.destroyCamera();
|
||||
if (failure)
|
||||
throw new RuntimeException(
|
||||
"Couldn't destroy a zero copy Pi camera while switching video modes");
|
||||
"Couldn't destroy a zero copy Pi Camera while switching video modes");
|
||||
failure = PicamJNI.createCamera(mode.width, mode.height, mode.fpsActual);
|
||||
if (failure)
|
||||
throw new RuntimeException(
|
||||
"Couldn't create a zero copy Pi camera while switching video modes");
|
||||
"Couldn't create a zero copy Pi Camera while switching video modes");
|
||||
|
||||
// We don't store last settings on the native side, and when you change video mode these get
|
||||
// reset on MMAL's end
|
||||
setExposure(lastExposure);
|
||||
setBrightness(lastBrightness);
|
||||
setGain(lastGain);
|
||||
setAwbGain(lastAwbGains.getFirst(), lastAwbGains.getSecond());
|
||||
|
||||
currentVideoMode = mode;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,12 @@ public class CVPipelineSettings implements Cloneable {
|
||||
public String pipelineNickname = "New Pipeline";
|
||||
public double cameraExposure = 50;
|
||||
public int cameraBrightness = 50;
|
||||
// Currently only used by a few cameras (notably the zero-copy Pi Camera driver) with the Gain
|
||||
// quirk
|
||||
public int cameraGain = 50;
|
||||
// Currently only used by the zero-copy Pi Camera driver
|
||||
public int cameraRedGain = 50;
|
||||
public int cameraBlueGain = 50;
|
||||
public int cameraVideoModeIndex = 0;
|
||||
public FrameDivisor streamingFrameDivisor = FrameDivisor.NONE;
|
||||
public boolean ledMode = false;
|
||||
@@ -57,6 +62,8 @@ public class CVPipelineSettings implements Cloneable {
|
||||
&& Double.compare(that.cameraExposure, cameraExposure) == 0
|
||||
&& Double.compare(that.cameraBrightness, cameraBrightness) == 0
|
||||
&& Double.compare(that.cameraGain, cameraGain) == 0
|
||||
&& Double.compare(that.cameraRedGain, cameraRedGain) == 0
|
||||
&& Double.compare(that.cameraBlueGain, cameraBlueGain) == 0
|
||||
&& cameraVideoModeIndex == that.cameraVideoModeIndex
|
||||
&& ledMode == that.ledMode
|
||||
&& pipelineType == that.pipelineType
|
||||
@@ -79,6 +86,8 @@ public class CVPipelineSettings implements Cloneable {
|
||||
cameraExposure,
|
||||
cameraBrightness,
|
||||
cameraGain,
|
||||
cameraRedGain,
|
||||
cameraBlueGain,
|
||||
cameraVideoModeIndex,
|
||||
streamingFrameDivisor,
|
||||
ledMode,
|
||||
|
||||
@@ -107,6 +107,13 @@ public class VisionModule {
|
||||
if (it.cameraGain == -1) it.cameraGain = 20; // Sane default
|
||||
});
|
||||
}
|
||||
if (cameraQuirks.hasQuirk(CameraQuirk.PiCam)) {
|
||||
pipelineManager.userPipelineSettings.forEach(
|
||||
it -> {
|
||||
if (it.cameraRedGain == -1) it.cameraRedGain = 16; // Sane defaults
|
||||
if (it.cameraBlueGain == -1) it.cameraBlueGain = 16;
|
||||
});
|
||||
}
|
||||
|
||||
this.pipelineManager = pipelineManager;
|
||||
this.visionSource = visionSource;
|
||||
@@ -345,6 +352,10 @@ public class VisionModule {
|
||||
if (!cameraQuirks.hasQuirk(CameraQuirk.Gain)) {
|
||||
settings.cameraGain = -1;
|
||||
}
|
||||
if (!cameraQuirks.hasQuirk(CameraQuirk.PiCam)) {
|
||||
settings.cameraRedGain = -1;
|
||||
settings.cameraBlueGain = -1;
|
||||
}
|
||||
|
||||
setPipeline(PipelineManager.CAL_3D_INDEX);
|
||||
}
|
||||
@@ -391,6 +402,16 @@ public class VisionModule {
|
||||
} else {
|
||||
config.cameraGain = -1;
|
||||
}
|
||||
if (cameraQuirks.hasQuirk(CameraQuirk.PiCam)) {
|
||||
// If the AWB gains are disabled for some reason, re-enable it
|
||||
if (config.cameraRedGain == -1) config.cameraRedGain = 16;
|
||||
if (config.cameraBlueGain == -1) config.cameraBlueGain = 16;
|
||||
visionSource.getSettables().setRedGain(Math.max(0, config.cameraRedGain));
|
||||
visionSource.getSettables().setBlueGain(Math.max(0, config.cameraBlueGain));
|
||||
} else {
|
||||
config.cameraRedGain = -1;
|
||||
config.cameraBlueGain = -1;
|
||||
}
|
||||
|
||||
setVisionLEDs(config.ledMode);
|
||||
|
||||
|
||||
@@ -48,6 +48,11 @@ public abstract class VisionSourceSettables {
|
||||
public abstract void setBrightness(int brightness);
|
||||
|
||||
public abstract void setGain(int gain);
|
||||
// Pretty uncommon so instead of abstract this is just a no-op by default
|
||||
// Overriden by cameras with AWB gain support
|
||||
public void setRedGain(int red) {}
|
||||
|
||||
public void setBlueGain(int blue) {}
|
||||
|
||||
public abstract VideoMode getCurrentVideoMode();
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user