Skip to content

Commit

Permalink
- Improved disparity GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
lessthanoptimal committed May 11, 2012
1 parent 72367bc commit 35d3c41
Show file tree
Hide file tree
Showing 9 changed files with 478 additions and 123 deletions.
Expand Up @@ -43,6 +43,7 @@ public class DisparityDisplayPanel extends StandardAlgConfigPanel


JSpinner minDisparitySpinner; JSpinner minDisparitySpinner;
JSpinner maxDisparitySpinner; JSpinner maxDisparitySpinner;
JCheckBox subpixelToggle;
JSpinner radiusSpinner; JSpinner radiusSpinner;
JSpinner errorSpinner; JSpinner errorSpinner;
JSpinner reverseSpinner; JSpinner reverseSpinner;
Expand All @@ -52,6 +53,7 @@ public class DisparityDisplayPanel extends StandardAlgConfigPanel
int selectedView; int selectedView;


boolean colorInvalid = false; boolean colorInvalid = false;
boolean useSubpixel = true;


// minimum disparity to calculate // minimum disparity to calculate
int minDisparity = 0; int minDisparity = 0;
Expand All @@ -74,6 +76,7 @@ public DisparityDisplayPanel() {
viewSelector.addItem("Disparity"); viewSelector.addItem("Disparity");
viewSelector.addItem("Left"); viewSelector.addItem("Left");
viewSelector.addItem("Right"); viewSelector.addItem("Right");
viewSelector.addItem("Top View");
viewSelector.addItemListener(this); viewSelector.addItemListener(this);
viewSelector.setMaximumSize(viewSelector.getPreferredSize()); viewSelector.setMaximumSize(viewSelector.getPreferredSize());


Expand All @@ -90,6 +93,11 @@ public DisparityDisplayPanel() {
maxDisparitySpinner.addChangeListener(this); maxDisparitySpinner.addChangeListener(this);
maxDisparitySpinner.setMaximumSize(maxDisparitySpinner.getPreferredSize()); 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 = new JSpinner(new SpinnerNumberModel(regionRadius,1, 30, 1));
radiusSpinner.addChangeListener(this); radiusSpinner.addChangeListener(this);
radiusSpinner.setMaximumSize(radiusSpinner.getPreferredSize()); radiusSpinner.setMaximumSize(radiusSpinner.getPreferredSize());
Expand All @@ -112,6 +120,7 @@ public DisparityDisplayPanel() {
addSeparator(100); addSeparator(100);
addLabeled(minDisparitySpinner, "Min Disparity", this); addLabeled(minDisparitySpinner, "Min Disparity", this);
addLabeled(maxDisparitySpinner, "Max Disparity", this); addLabeled(maxDisparitySpinner, "Max Disparity", this);
addAlignLeft(subpixelToggle,this);
addLabeled(radiusSpinner, "Region Radius", this); addLabeled(radiusSpinner, "Region Radius", this);
addLabeled(errorSpinner, "Max Error", this); addLabeled(errorSpinner, "Max Error", this);
addLabeled(textureSpinner, "Texture", this); addLabeled(textureSpinner, "Texture", this);
Expand Down Expand Up @@ -157,14 +166,17 @@ public void itemStateChanged(ItemEvent e) {
} else if( e.getSource() == invalidToggle) { } else if( e.getSource() == invalidToggle) {
colorInvalid = invalidToggle.isSelected(); colorInvalid = invalidToggle.isSelected();
listener.disparityRender(); listener.disparityRender();
} else if( e.getSource() == subpixelToggle ) {
useSubpixel = subpixelToggle.isSelected();
listener.disparitySettingChange();
} }
} }


public void setActiveGui( boolean error , boolean reverse ) { public void setActiveGui( boolean error , boolean reverse ) {
setEnabled(7,error); setEnabled(8,error);
setEnabled(8,reverse); setEnabled(9,reverse);
setEnabled(9,error); setEnabled(10,error);
setEnabled(10,reverse); setEnabled(11,reverse);
} }


public void setListener(Listener listener ) { public void setListener(Listener listener ) {
Expand Down
Expand Up @@ -29,6 +29,7 @@
import boofcv.factory.feature.disparity.DisparityAlgorithms; import boofcv.factory.feature.disparity.DisparityAlgorithms;
import boofcv.factory.feature.disparity.FactoryStereoDisparity; import boofcv.factory.feature.disparity.FactoryStereoDisparity;
import boofcv.gui.SelectAlgorithmAndInputPanel; import boofcv.gui.SelectAlgorithmAndInputPanel;
import boofcv.gui.d3.PointCloudSideViewer;
import boofcv.gui.image.ImagePanel; import boofcv.gui.image.ImagePanel;
import boofcv.gui.image.ShowImages; import boofcv.gui.image.ShowImages;
import boofcv.gui.image.VisualizeImageData; import boofcv.gui.image.VisualizeImageData;
Expand All @@ -48,6 +49,8 @@
import java.util.List; import java.util.List;


/** /**
* TODO comment
*
* @author Peter Abeles * @author Peter Abeles
*/ */
public class VisualizeStereoDisparity <T extends ImageSingleBand, D extends ImageSingleBand> public class VisualizeStereoDisparity <T extends ImageSingleBand, D extends ImageSingleBand>
Expand All @@ -68,7 +71,10 @@ public class VisualizeStereoDisparity <T extends ImageSingleBand, D extends Imag
RectifyCalibrated rectifyAlg = RectifyImageOps.createCalibrated(); RectifyCalibrated rectifyAlg = RectifyImageOps.createCalibrated();


DisparityDisplayPanel control = new DisparityDisplayPanel(); DisparityDisplayPanel control = new DisparityDisplayPanel();
JPanel panel = new JPanel();
ImagePanel gui = new ImagePanel(); ImagePanel gui = new ImagePanel();
PointCloudSideViewer cloudGui = new PointCloudSideViewer();
boolean computedCloud;


int selectedAlg; int selectedAlg;
StereoDisparity<T,D> activeAlg; StereoDisparity<T,D> activeAlg;
Expand All @@ -90,7 +96,6 @@ public VisualizeStereoDisparity() {


control.setListener(this); control.setListener(this);


JPanel panel = new JPanel();
panel.setLayout(new BorderLayout()); panel.setLayout(new BorderLayout());
panel.add(control, BorderLayout.WEST); panel.add(control, BorderLayout.WEST);
panel.add(gui,BorderLayout.CENTER); panel.add(gui,BorderLayout.CENTER);
Expand All @@ -102,6 +107,7 @@ public synchronized void process() {
if( !rectifiedImages ) if( !rectifiedImages )
return; return;


computedCloud = false;
activeAlg.process(rectLeft, rectRight); activeAlg.process(rectLeft, rectRight);


disparityRender(); disparityRender();
Expand All @@ -113,28 +119,46 @@ public synchronized void process() {
private void changeImageView() { private void changeImageView() {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
BufferedImage img; JComponent comp;

if( control.selectedView < 3 ) {
switch (control.selectedView) { BufferedImage img;
case 0:
img = disparityOut; switch (control.selectedView) {
break; case 0:

img = disparityOut;
case 1: break;
img = colorLeft;
break; case 1:

img = colorLeft;
case 2: break;
img = colorRight;
break; case 2:

img = colorRight;
default: break;
throw new RuntimeException("Unknown option");
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;
} }

panel.getLayout();
gui.setBufferedImage(img); panel.remove(gui);
gui.setPreferredSize(new Dimension(img.getWidth(), img.getHeight())); panel.remove(cloudGui);
gui.repaint(); panel.add(comp,BorderLayout.CENTER);
panel.validate();
comp.repaint();
processedImage = true; processedImage = true;
} }
}); });
Expand Down Expand Up @@ -258,27 +282,52 @@ public StereoDisparity<T,D> createAlg() {


int r = control.regionRadius; int r = control.regionRadius;


switch( selectedAlg ) { if( control.useSubpixel ) {
case 0: switch( selectedAlg ) {
changeGuiActive(false,false); case 0:
return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT,control.minDisparity, changeGuiActive(false,false);
control.maxDisparity, r, r, -1, -1, -1, ImageUInt8.class); return (StereoDisparity)FactoryStereoDisparity.regionSubpixelWta(DisparityAlgorithms.RECT,control.minDisparity,

control.maxDisparity, r, r, -1, -1, -1, ImageUInt8.class);
case 1:
changeGuiActive(true,true); case 1:
return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT,control.minDisparity, changeGuiActive(true,true);
control.maxDisparity, r, r, control.pixelError, control.reverseTol, control.texture, return (StereoDisparity)FactoryStereoDisparity.regionSubpixelWta(DisparityAlgorithms.RECT,control.minDisparity,
ImageUInt8.class); control.maxDisparity, r, r, control.pixelError, control.reverseTol, control.texture,

ImageUInt8.class);
case 2:
changeGuiActive(true,true); case 2:
return (StereoDisparity)FactoryStereoDisparity.regionWta(DisparityAlgorithms.RECT_FIVE, changeGuiActive(true,true);
control.minDisparity, control.maxDisparity, r, r, return (StereoDisparity)FactoryStereoDisparity.regionSubpixelWta(DisparityAlgorithms.RECT_FIVE,
control.pixelError, control.reverseTol, control.texture, control.minDisparity, control.maxDisparity, r, r,
ImageUInt8.class); control.pixelError, control.reverseTol, control.texture,

ImageUInt8.class);
default:
throw new RuntimeException("Unknown selection"); 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");
}
} }


} }
Expand All @@ -298,7 +347,7 @@ public static void main( String args[] ) {


VisualizeStereoDisparity app = new VisualizeStereoDisparity(); 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/"; String dirImgs = "../data/applet/stereo/";


StereoParameters calib = BoofMiscOps.loadXML(dirCalib+"stereo.xml"); StereoParameters calib = BoofMiscOps.loadXML(dirCalib+"stereo.xml");
Expand All @@ -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("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("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("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.setCalib(calib);
app.setInputList(inputs); app.setInputList(inputs);
Expand Down
91 changes: 91 additions & 0 deletions main/geo/src/boofcv/alg/feature/disparity/DisparityPointCloud.java
@@ -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();
}
}
2 changes: 1 addition & 1 deletion main/ip/src/boofcv/struct/image/ImageFloat32.java
Expand Up @@ -59,7 +59,7 @@ public float get(int x, int y) {
return unsafe_get(x,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)]; return data[getIndex(x, y)];
} }


Expand Down
Expand Up @@ -16,10 +16,11 @@
* limitations under the License. * limitations under the License.
*/ */


package boofcv.alg.feature.disparity; package boofcv.gui.d3;


/** /**
* @author Peter Abeles * @author Peter Abeles
*/ */
public class DisparityPointCloud { // todo menu bar - home, scale, offset (x,y), max height? tilt?
public class PointCloudSidePanel {
} }

0 comments on commit 35d3c41

Please sign in to comment.