Permalink
Browse files

- Improved disparity GUI

  • Loading branch information...
1 parent 72367bc commit 35d3c41ed33a6088b08a092329c2786fc045b3bf @lessthanoptimal committed May 11, 2012
@@ -43,6 +43,7 @@
JSpinner minDisparitySpinner;
JSpinner maxDisparitySpinner;
+ JCheckBox subpixelToggle;
JSpinner radiusSpinner;
JSpinner errorSpinner;
JSpinner reverseSpinner;
@@ -52,6 +53,7 @@
int selectedView;
boolean colorInvalid = false;
+ boolean useSubpixel = true;
// minimum disparity to calculate
int minDisparity = 0;
@@ -74,6 +76,7 @@ public DisparityDisplayPanel() {
viewSelector.addItem("Disparity");
viewSelector.addItem("Left");
viewSelector.addItem("Right");
+ viewSelector.addItem("Top View");
viewSelector.addItemListener(this);
viewSelector.setMaximumSize(viewSelector.getPreferredSize());
@@ -90,6 +93,11 @@ public DisparityDisplayPanel() {
maxDisparitySpinner.addChangeListener(this);
maxDisparitySpinner.setMaximumSize(maxDisparitySpinner.getPreferredSize());
+ subpixelToggle = new JCheckBox("Subpixel");
+ subpixelToggle.setSelected(useSubpixel);
+ subpixelToggle.addItemListener(this);
+ subpixelToggle.setMaximumSize(invalidToggle.getPreferredSize());
+
radiusSpinner = new JSpinner(new SpinnerNumberModel(regionRadius,1, 30, 1));
radiusSpinner.addChangeListener(this);
radiusSpinner.setMaximumSize(radiusSpinner.getPreferredSize());
@@ -112,6 +120,7 @@ public DisparityDisplayPanel() {
addSeparator(100);
addLabeled(minDisparitySpinner, "Min Disparity", this);
addLabeled(maxDisparitySpinner, "Max Disparity", this);
+ addAlignLeft(subpixelToggle,this);
addLabeled(radiusSpinner, "Region Radius", this);
addLabeled(errorSpinner, "Max Error", this);
addLabeled(textureSpinner, "Texture", this);
@@ -157,14 +166,17 @@ public void itemStateChanged(ItemEvent e) {
} else if( e.getSource() == invalidToggle) {
colorInvalid = invalidToggle.isSelected();
listener.disparityRender();
+ } else if( e.getSource() == subpixelToggle ) {
+ useSubpixel = subpixelToggle.isSelected();
+ listener.disparitySettingChange();
}
}
public void setActiveGui( boolean error , boolean reverse ) {
- setEnabled(7,error);
- setEnabled(8,reverse);
- setEnabled(9,error);
- setEnabled(10,reverse);
+ setEnabled(8,error);
+ setEnabled(9,reverse);
+ setEnabled(10,error);
+ setEnabled(11,reverse);
}
public void setListener(Listener listener ) {
@@ -29,6 +29,7 @@
import boofcv.factory.feature.disparity.DisparityAlgorithms;
import boofcv.factory.feature.disparity.FactoryStereoDisparity;
import boofcv.gui.SelectAlgorithmAndInputPanel;
+import boofcv.gui.d3.PointCloudSideViewer;
import boofcv.gui.image.ImagePanel;
import boofcv.gui.image.ShowImages;
import boofcv.gui.image.VisualizeImageData;
@@ -48,6 +49,8 @@
import java.util.List;
/**
+ * TODO comment
+ *
* @author Peter Abeles
*/
public class VisualizeStereoDisparity <T extends ImageSingleBand, D extends ImageSingleBand>
@@ -68,7 +71,10 @@
RectifyCalibrated rectifyAlg = RectifyImageOps.createCalibrated();
DisparityDisplayPanel control = new DisparityDisplayPanel();
+ JPanel panel = new JPanel();
ImagePanel gui = new ImagePanel();
+ PointCloudSideViewer cloudGui = new PointCloudSideViewer();
+ boolean computedCloud;
int selectedAlg;
StereoDisparity<T,D> activeAlg;
@@ -90,7 +96,6 @@ public VisualizeStereoDisparity() {
control.setListener(this);
- JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(control, BorderLayout.WEST);
panel.add(gui,BorderLayout.CENTER);
@@ -102,6 +107,7 @@ public synchronized void process() {
if( !rectifiedImages )
return;
+ computedCloud = false;
activeAlg.process(rectLeft, rectRight);
disparityRender();
@@ -113,28 +119,46 @@ public synchronized void process() {
private void changeImageView() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
- BufferedImage img;
-
- switch (control.selectedView) {
- case 0:
- img = disparityOut;
- break;
-
- case 1:
- img = colorLeft;
- break;
-
- case 2:
- img = colorRight;
- break;
-
- default:
- throw new RuntimeException("Unknown option");
+ JComponent comp;
+ if( control.selectedView < 3 ) {
+ BufferedImage img;
+
+ switch (control.selectedView) {
+ case 0:
+ img = disparityOut;
+ break;
+
+ case 1:
+ img = colorLeft;
+ break;
+
+ case 2:
+ img = colorRight;
+ break;
+
+ default:
+ throw new RuntimeException("Unknown option");
+ }
+
+ gui.setBufferedImage(img);
+ gui.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
+ comp = gui;
+ } else {
+ if( !computedCloud ) {
+ computedCloud = true;
+ double baseline = calib.getRightToLeft().getT().norm();
+ cloudGui.configure(baseline,rectK.get(0,0),rectK.get(1,1),rectK.get(0,2),rectK.get(1,2),
+ control.minDisparity,control.maxDisparity);
+ cloudGui.process(activeAlg.getDisparity(),colorLeft);
+ }
+ comp = cloudGui;
}
-
- gui.setBufferedImage(img);
- gui.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
- gui.repaint();
+ panel.getLayout();
+ panel.remove(gui);
+ panel.remove(cloudGui);
+ panel.add(comp,BorderLayout.CENTER);
+ panel.validate();
+ comp.repaint();
processedImage = true;
}
});
@@ -258,27 +282,52 @@ public void setCalib(StereoParameters calib) {
int r = control.regionRadius;
- switch( selectedAlg ) {
- case 0:
- changeGuiActive(false,false);
- return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT,control.minDisparity,
- control.maxDisparity, r, r, -1, -1, -1, ImageUInt8.class);
-
- case 1:
- changeGuiActive(true,true);
- return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT,control.minDisparity,
- control.maxDisparity, r, r, control.pixelError, control.reverseTol, control.texture,
- ImageUInt8.class);
-
- case 2:
- changeGuiActive(true,true);
- return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT_FIVE,
- control.minDisparity, control.maxDisparity, r, r,
- control.pixelError, control.reverseTol, control.texture,
- ImageUInt8.class);
-
- default:
- throw new RuntimeException("Unknown selection");
+ if( control.useSubpixel ) {
+ switch( selectedAlg ) {
+ case 0:
+ changeGuiActive(false,false);
+ return (StereoDisparity)FactoryStereoDisparity.regionSubpixelWta(DisparityAlgorithms.RECT,control.minDisparity,
+ control.maxDisparity, r, r, -1, -1, -1, ImageUInt8.class);
+
+ case 1:
+ changeGuiActive(true,true);
+ return (StereoDisparity)FactoryStereoDisparity.regionSubpixelWta(DisparityAlgorithms.RECT,control.minDisparity,
+ control.maxDisparity, r, r, control.pixelError, control.reverseTol, control.texture,
+ ImageUInt8.class);
+
+ case 2:
+ changeGuiActive(true,true);
+ return (StereoDisparity)FactoryStereoDisparity.regionSubpixelWta(DisparityAlgorithms.RECT_FIVE,
+ control.minDisparity, control.maxDisparity, r, r,
+ control.pixelError, control.reverseTol, control.texture,
+ ImageUInt8.class);
+
+ default:
+ throw new RuntimeException("Unknown selection");
+ }
+ } else {
+ switch( selectedAlg ) {
+ case 0:
+ changeGuiActive(false,false);
+ return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT,control.minDisparity,
+ control.maxDisparity, r, r, -1, -1, -1, ImageUInt8.class);
+
+ case 1:
+ changeGuiActive(true,true);
+ return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT,control.minDisparity,
+ control.maxDisparity, r, r, control.pixelError, control.reverseTol, control.texture,
+ ImageUInt8.class);
+
+ case 2:
+ changeGuiActive(true,true);
+ return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT_FIVE,
+ control.minDisparity, control.maxDisparity, r, r,
+ control.pixelError, control.reverseTol, control.texture,
+ ImageUInt8.class);
+
+ default:
+ throw new RuntimeException("Unknown selection");
+ }
}
}
@@ -298,7 +347,7 @@ public static void main( String args[] ) {
VisualizeStereoDisparity app = new VisualizeStereoDisparity();
- String dirCalib = "../data/evaluation/calibration/stereo/Bumblebee2_Chess/";
+ String dirCalib = "../data/applet/calibration/stereo/Bumblebee2_Chess/";
String dirImgs = "../data/applet/stereo/";
StereoParameters calib = BoofMiscOps.loadXML(dirCalib+"stereo.xml");
@@ -309,6 +358,8 @@ public static void main( String args[] ) {
inputs.add(new PathLabel("Stones 1",dirImgs+"stones01_left.jpg",dirImgs+"stones01_right.jpg"));
inputs.add(new PathLabel("Thing 1",dirImgs+"thing01_left.jpg",dirImgs+"thing01_right.jpg"));
inputs.add(new PathLabel("Wall 1",dirImgs+"wall01_left.jpg",dirImgs+"wall01_right.jpg"));
+ inputs.add(new PathLabel("Garden 1",dirImgs+"garden01_left.jpg",dirImgs+"garden01_right.jpg"));
+ inputs.add(new PathLabel("Garden 2",dirImgs+"garden02_left.jpg",dirImgs+"garden02_right.jpg"));
app.setCalib(calib);
app.setInputList(inputs);
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011-2012, Peter Abeles. All Rights Reserved.
+ *
+ * This file is part of BoofCV (http://boofcv.org).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package boofcv.alg.feature.disparity;
+
+import boofcv.struct.FastQueue;
+import boofcv.struct.calib.IntrinsicParameters;
+import boofcv.struct.image.ImageUInt8;
+import georegression.struct.point.Point3D_F64;
+
+import java.util.List;
+
+/**
+ * @author Peter Abeles
+ */
+public class DisparityPointCloud {
+ FastQueue<Point3D_F64> cloud = new FastQueue<Point3D_F64>(200,Point3D_F64.class,true);
+
+ // distance between the two camera centers
+ double baseline;
+
+ double focalLengthX;
+ double focalLengthY;
+ double centerX;
+ double centerY;
+
+ // minimum disparity
+ int minDisparity;
+ // maximum minus minimum disparity
+ int rangeDisparity;
+
+ public void configure(double baseline,
+ double focalLengthX, double focalLengthY,
+ double centerX, double centerY,
+ int minDisparity, int maxDisparity) {
+ this.baseline = baseline;
+ this.focalLengthX = focalLengthX;
+ this.focalLengthY = focalLengthY;
+ this.centerX = centerX;
+ this.centerY = centerY;
+ this.minDisparity = minDisparity;
+
+ this.rangeDisparity = maxDisparity-minDisparity;
+ }
+
+ public void process( ImageUInt8 disparity ) {
+
+ cloud.reset();
+
+ for( int y = 0; y < disparity.height; y++ ) {
+ int index = disparity.startIndex + disparity.stride*y;
+
+ for( int x = 0; x < disparity.width; x++ ) {
+ int value = disparity.data[index++] & 0xFF;
+
+ if( value >= rangeDisparity )
+ continue;
+
+ value += minDisparity;
+
+ if( value == 0 )
+ continue;
+
+ Point3D_F64 p = cloud.pop();
+
+ p.z = baseline*focalLengthX/value;
+ p.x = p.z*(x - centerX)/focalLengthX;
+ p.y = p.z*(y - centerY)/focalLengthY;
+ }
+ }
+ }
+
+ public List<Point3D_F64> getCloud() {
+ return cloud.toList();
+ }
+}
@@ -59,7 +59,7 @@ public float get(int x, int y) {
return unsafe_get(x,y);
}
- protected float unsafe_get(int x, int y) {
+ public float unsafe_get(int x, int y) {
return data[getIndex(x, y)];
}
@@ -16,10 +16,11 @@
* limitations under the License.
*/
-package boofcv.alg.feature.disparity;
+package boofcv.gui.d3;
/**
* @author Peter Abeles
*/
-public class DisparityPointCloud {
+// todo menu bar - home, scale, offset (x,y), max height? tilt?
+public class PointCloudSidePanel {
}
Oops, something went wrong.

0 comments on commit 35d3c41

Please sign in to comment.