package edu.stanford.rsl.apps.gui.blobdetection;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.JTextPane;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import edu.stanford.rsl.conrad.utils.CONRAD;
import edu.stanford.rsl.conrad.utils.XmlUtils;
/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class MarkerDetection extends JFrame implements ActionListener, ChangeListener, DocumentListener {
/**
*
*/
private static final long serialVersionUID = -5274899502815414214L;
private JButton jButtonRun;
private MarkerDetectionWorker pWorker;
private JSpinner jSpinnerGradientThreshold;
private JTextPane jTextPane4;
private JTextPane jTextPane3;
private JTextPane jTextPane2;
private JTextPane jTextPane1;
private JTextPane jTextPaneBlobRadii;
private JSpinner jSpinnerDistance;
private JCheckBox jCheckBoxRefineAutoDetection;
private JSpinner jSpinnerNumberOfBeadsToDetect;
private JButton jButtonSaveResults;
private JTextPane jTextPane6;
private JSpinner jSpinnerNrOfIterations;
private JCheckBox jCheckBoxAutomaticDetection;
private JTextPane jTextPane5;
private JSpinner jSpinnerCircularity;
private JSpinner jSpinnerBinarizationThreshold;
private boolean AutoDetectioncheckBoxChecked = false;
private boolean RefinementcheckBoxChecked = false;
public MarkerDetection () {
initGUI();
pWorker = new MarkerDetectionWorker();
updateParameters();
}
private void initGUI(){
{
GridBagLayout thisLayout = new GridBagLayout();
thisLayout.rowWeights = new double[] {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
thisLayout.rowHeights = new int[] {20, 7, 20, 20, 7, 7, 7};
thisLayout.columnWeights = new double[] {0.0, 0.1, 0.0, 0.0, 0.1, 0.1};
thisLayout.columnWidths = new int[] {154, 20, 185, 29, 20, 7};
getContentPane().setLayout(thisLayout);
{
jButtonRun = new JButton();
getContentPane().add(jButtonRun, new GridBagConstraints(4, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jButtonRun.setText("Run Detection");
jButtonRun.addActionListener(this);
}
{
SpinnerModel jSpinnerBinarizationThresholdModel =
new SpinnerNumberModel(0.5, 0, 15, 0.1);
jSpinnerBinarizationThreshold = new JSpinner();
getContentPane().add(jSpinnerBinarizationThreshold, new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jSpinnerBinarizationThreshold.setModel(jSpinnerBinarizationThresholdModel);
jSpinnerBinarizationThreshold.setPreferredSize(new java.awt.Dimension(61, 28));
jSpinnerBinarizationThreshold.addChangeListener(this);
}
{
SpinnerModel jSpinnerGradientThresholdModel =
new SpinnerNumberModel(0,0,1,0.01);
jSpinnerGradientThreshold = new JSpinner();
getContentPane().add(jSpinnerGradientThreshold, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jSpinnerGradientThreshold.setModel(jSpinnerGradientThresholdModel);
jSpinnerGradientThreshold.setPreferredSize(new java.awt.Dimension(61, 28));
jSpinnerGradientThreshold.addChangeListener(this);
}
{
SpinnerModel jSpinnerCircularityModel =
new SpinnerNumberModel(3,1,5,1);
jSpinnerCircularity = new JSpinner();
getContentPane().add(jSpinnerCircularity, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jSpinnerCircularity.setModel(jSpinnerCircularityModel);
jSpinnerCircularity.setPreferredSize(new java.awt.Dimension(61,28));
jSpinnerCircularity.addChangeListener(this);
}
{
jTextPane1 = new JTextPane();
getContentPane().add(jTextPane1, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jTextPane1.setText("Binarization Threshold");
}
{
jTextPane2 = new JTextPane();
getContentPane().add(jTextPane2, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jTextPane2.setText("Low Gradient Threshold");
}
{
jTextPane3 = new JTextPane();
getContentPane().add(jTextPane3, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jTextPane3.setText("Blob radii");
}
{
jTextPane4 = new JTextPane();
getContentPane().add(jTextPane4, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jTextPane4.setText("Circularity Measure");
}
{
jTextPaneBlobRadii = new JTextPane();
getContentPane().add(jTextPaneBlobRadii, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jTextPaneBlobRadii.setText("[3.0]");
jTextPaneBlobRadii.setPreferredSize(new java.awt.Dimension(61,28));
jTextPaneBlobRadii.getDocument().addDocumentListener(this);
}
{
jTextPane5 = new JTextPane();
getContentPane().add(jTextPane5, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jTextPane5.setText("Distance to Reference");
}
{
SpinnerModel jSpinnerDistanceModel =
new SpinnerNumberModel(15,1,200,10);
jSpinnerDistance = new JSpinner();
getContentPane().add(jSpinnerDistance, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jSpinnerDistance.setModel(jSpinnerDistanceModel);
jSpinnerDistance.setPreferredSize(new java.awt.Dimension(61, 28));
jSpinnerDistance.addChangeListener(this);
}
{
jCheckBoxAutomaticDetection = new JCheckBox();
getContentPane().add(jCheckBoxAutomaticDetection, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jCheckBoxAutomaticDetection.setText("Use Automatic Marker Detection");
jCheckBoxAutomaticDetection.addChangeListener(this);
}
{
jCheckBoxRefineAutoDetection = new JCheckBox();
getContentPane().add(jCheckBoxRefineAutoDetection, new GridBagConstraints(4, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
jCheckBoxRefineAutoDetection.setText("Refine results / Set no. of beads");
jCheckBoxRefineAutoDetection.setVisible(false);
jCheckBoxRefineAutoDetection.addChangeListener(this);
}
{
SpinnerModel jSpinnerNumberOfBeadsModel =
new SpinnerNumberModel(10,1,1000,1);
jSpinnerNumberOfBeadsToDetect = new JSpinner();
getContentPane().add(jSpinnerNumberOfBeadsToDetect, new GridBagConstraints(5, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jSpinnerNumberOfBeadsToDetect.setModel(jSpinnerNumberOfBeadsModel);
jSpinnerNumberOfBeadsToDetect.setPreferredSize(new java.awt.Dimension(61,28));
jSpinnerNumberOfBeadsToDetect.setEnabled(false);
jSpinnerNumberOfBeadsToDetect.setVisible(false);
jSpinnerNumberOfBeadsToDetect.addChangeListener(this);
}
{
SpinnerModel jSpinnerNumberOfIterationsModel =
new SpinnerNumberModel(1,1,250,1);
jSpinnerNrOfIterations = new JSpinner();
getContentPane().add(jSpinnerNrOfIterations, new GridBagConstraints(1, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jSpinnerNrOfIterations.setModel(jSpinnerNumberOfIterationsModel);
jSpinnerNrOfIterations.setPreferredSize(new java.awt.Dimension(61,28));
jSpinnerNrOfIterations.addChangeListener(this);
}
{
jTextPane6 = new JTextPane();
getContentPane().add(jTextPane6, new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jTextPane6.setText("No of Iterations");
}
{
jButtonSaveResults = new JButton();
getContentPane().add(jButtonSaveResults, new GridBagConstraints(4, 5, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
jButtonSaveResults.setText("Save Results");
jButtonSaveResults.addActionListener(this);
jButtonSaveResults.setVisible(false);
}
}
{
this.setSize(757, 386);
}
}
@Override
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource().equals(jButtonRun)){
Thread test = new Thread(){
@Override
public void run() {
boolean[] wasEnabled = new boolean[getContentPane().getComponents().length];
for (int i = 0; i < getContentPane().getComponents().length; i++) {
wasEnabled[i]=getContentPane().getComponents()[i].isEnabled();
getContentPane().getComponents()[i].setEnabled(false);
}
try {
updateParameters();
// save states
for (int j = 0; j < ((SpinnerNumberModel)jSpinnerNrOfIterations.getModel()).getNumber().intValue(); j++) {
runDetection();
}
jButtonSaveResults.setVisible(true);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < getContentPane().getComponents().length; i++) {
if (wasEnabled[i])
getContentPane().getComponents()[i].setEnabled(true);
}
}
};
test.start();
}
if (arg0.getSource().equals(jButtonSaveResults)){
Thread test = new Thread(){
@Override
public void run() {
if (pWorker != null){
try {
XmlUtils.exportToXML(pWorker.getMeasuredTwoDPoints());
XmlUtils.exportToXML(pWorker.getMergedTwoDPositions());
XmlUtils.exportToXML(pWorker.getReferenceThreeDPoints());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
test.start();
}
}
@Override
public void stateChanged(ChangeEvent arg0) {
if (arg0.getSource().equals(jSpinnerBinarizationThreshold) || arg0.getSource().equals(jSpinnerGradientThreshold)
|| arg0.getSource().equals(jTextPaneBlobRadii) || arg0.getSource().equals(jSpinnerCircularity) ||
arg0.getSource().equals(jSpinnerNumberOfBeadsToDetect) || arg0.getSource().equals(jSpinnerNrOfIterations)){
Thread test = new Thread(){
@Override
public void run() {
updateParameters();
}
};
test.start();
}
if (arg0.getSource().equals(jCheckBoxAutomaticDetection)){
if (AutoDetectioncheckBoxChecked != jCheckBoxAutomaticDetection.isSelected()){
AutoDetectioncheckBoxChecked = jCheckBoxAutomaticDetection.isSelected();
if (AutoDetectioncheckBoxChecked){
pWorker = new AutomaticMarkerDetectionWorker();
jCheckBoxRefineAutoDetection.setVisible(true);
jSpinnerNumberOfBeadsToDetect.setVisible(true);
}
else{
pWorker = new MarkerDetectionWorker();
jCheckBoxRefineAutoDetection.setVisible(false);
jSpinnerNumberOfBeadsToDetect.setVisible(false);
}
jButtonSaveResults.setVisible(false);
}
}
if (arg0.getSource().equals(jCheckBoxRefineAutoDetection)){
if (RefinementcheckBoxChecked != jCheckBoxRefineAutoDetection.isSelected()){
RefinementcheckBoxChecked = jCheckBoxRefineAutoDetection.isSelected();
if (RefinementcheckBoxChecked){
pWorker = new AutomaticMarkerDetectionWorker();
jSpinnerNumberOfBeadsToDetect.setEnabled(true);
}
else{
jSpinnerNumberOfBeadsToDetect.setEnabled(false);
}
updateParameters();
}
}
}
private void updateParameters(){
if (pWorker instanceof AutomaticMarkerDetectionWorker){
((AutomaticMarkerDetectionWorker)pWorker).setParameters(((SpinnerNumberModel)jSpinnerBinarizationThreshold.getModel()).getNumber().doubleValue(),
((SpinnerNumberModel)jSpinnerCircularity.getModel()).getNumber().doubleValue(),
((SpinnerNumberModel)jSpinnerGradientThreshold.getModel()).getNumber().doubleValue(),
((SpinnerNumberModel)jSpinnerDistance.getModel()).getNumber().doubleValue(),
jTextPaneBlobRadii.getText(),
RefinementcheckBoxChecked,
((SpinnerNumberModel)jSpinnerNumberOfBeadsToDetect.getModel()).getNumber().intValue());
}
else{
pWorker.setParameters(((SpinnerNumberModel)jSpinnerBinarizationThreshold.getModel()).getNumber().doubleValue(),
((SpinnerNumberModel)jSpinnerCircularity.getModel()).getNumber().doubleValue(),
((SpinnerNumberModel)jSpinnerGradientThreshold.getModel()).getNumber().doubleValue(),
((SpinnerNumberModel)jSpinnerDistance.getModel()).getNumber().doubleValue(),
jTextPaneBlobRadii.getText());
}
}
private void runDetection(){
pWorker.run();
}
@Override
public void changedUpdate(DocumentEvent arg0) {
Thread test = new Thread(){
@Override
public void run() {
updateParameters();
}
};
test.start();
}
@Override
public void insertUpdate(DocumentEvent arg0) {
Thread test = new Thread(){
@Override
public void run() {
updateParameters();
}
};
test.start();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
Thread test = new Thread(){
@Override
public void run() {
updateParameters();
}
};
test.start();
}
/**
* @param args
*/
public static void main(String[] args) {
CONRAD.setup();
MarkerDetection md = new MarkerDetection();
md.setVisible(true);
//Opener op = new Opener();
//op.openImage("C:\\Users\\berger\\Desktop\\Result of WEIGHT-BEARING.XA._.9.Standing_Straight_2Legs244LbsTotal_248views_70kV_0.54uGy-2.tif").show("Result of WEIGHT-BEARING.XA._.9.Standing_Straight_2Legs244LbsTotal_248views_70kV_0.54uGy-2.tif");
//op.openImage("D:\\Data\\WeightBearing\\stanford_knee_data_jang_2013_07_08\\Weight-bearing_NO6_IR1\\Projection\\AfterPreCorrection\\WEIGHT-BEARING.XA._.9.Standing_Straight_2Legs244LbsTotal_248views_70kV_0.54uGy.tif").show();
}
}
/*
* Copyright (C) 2010-2014 - Martin Berger
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/