Commit a3c6831f authored by lafabregue's avatar lafabregue

Add masks in data sampling

parent f7d1e6a3
This software have been developped by SDC team from iCube Laboratory.
For installation refer to the "Install Guide MultiCube.pdf"
......@@ -32,6 +32,12 @@ import jcl.learning.methods.monostrategy.SingleClassification;
import jcl.weights.ClassificationWeights;
import jsl.Segmentation;
import mustic.gui.dialog.*;
import mustic.gui.dialog.arff.ArffLoadDialog;
import mustic.gui.dialog.arff.ArffToDataDialog;
import mustic.gui.dialog.arff.ArffToImageDialog;
import mustic.gui.dialog.arff.DataToArffDialog;
import mustic.gui.dialog.arff.ImageToArffDialog;
import mustic.gui.dialog.arff.RawImageToArffDialog;
import mustic.gui.dialog.classifier.ConstraintsSelectionDialog;
import mustic.gui.dialog.consoleHandler.ConsoleFrame;
import mustic.gui.panels.*;
......@@ -1359,7 +1365,7 @@ public class MainFrame extends JFrame {
JSplitPane pane3 = Factory.createStrippedSplitPane(JSplitPane.VERTICAL_SPLIT,
pane2, sif_birdPanel, 0.5f);
pane2, sif_infosPanel, 0.5f);
pane3.setOpaque(false);
JSplitPane pane4 = Factory.createStrippedSplitPane(JSplitPane.VERTICAL_SPLIT,
......@@ -3450,6 +3456,7 @@ public class MainFrame extends JFrame {
try {
this.currentImageSession.mask();
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, Messages.getString("MainFrame.250"), Messages.getString("MainFrame.251"), //$NON-NLS-1$ //$NON-NLS-2$
JOptionPane.WARNING_MESSAGE);
}
......@@ -3458,7 +3465,7 @@ public class MainFrame extends JFrame {
private void toolsMenuROI() {
try {
this.desktop.setSelectedFrame(this.currentImageSession.associatedFrame);
this.desktop.getActiveFrame().addROITools();
((ImageDesktopFrame) this.desktop.getActiveFrame()).addROITools();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, Messages.getString("MainFrame.252"), Messages.getString("MainFrame.253"), //$NON-NLS-1$ //$NON-NLS-2$
JOptionPane.WARNING_MESSAGE);
......
package mustic.gui.dialog;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import jcl.data.mask.IntArrayMask;
import jcl.data.mask.Mask;
import jcl.data.mask.MultiIDIntArrayMask;
import jcl.utils.Images.StreamedImageReaderWrapper;
import mustic.gui.dialog.Messages;
import mustic.gui.panels.data.DataConstructPanel;
import mustic.io.RawImage;
import mustic.utils.io.CSVUtils;
/**
* Dialog that allow the user to import a Mask from an Image file
* It can be used to associate the mask to a RawImage or a DataConstructPanel
*
* @author Baptiste LAFABREGUE
*
*/
public class MaskImportDialog extends JDialog {
private static final long serialVersionUID = 1L;
// private JTextField textFileTextField = new JTextField();
private JRadioButton maskedRadioButton = new JRadioButton(
Messages.getString("MaskImportDialog.5")); //$NON-NLS-1$
private JRadioButton unmaskedRadioButton = new JRadioButton(
Messages.getString("MaskImportDialog.6")); //$NON-NLS-1$
private JTextField idListTextFied = new JTextField();
private RawImage rawImage = null;
private DataConstructPanel dataConstructPanel = null;
private String path = null;
/**
* Constructor for a RawImage parent
*
* @param rawImage
* the RawImage to link the mask to
* @param path
* the mask file path
*/
public MaskImportDialog(RawImage rawImage, String path) {
this(path);
this.rawImage = rawImage;
}
/**
* Constructor for a DataConstructPanel parent
*
* @param panel
* the DataConstructPanel to link the mask to
* @param path
* the mask file path
*/
public MaskImportDialog(DataConstructPanel panel, String path) {
this(path);
this.dataConstructPanel = panel;
}
/**
* Common constructor between RawImage and DataConstructPanel constructors
*
* @param path
* the mask file path
*/
private MaskImportDialog(String path) {
super();
this.path = path;
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel panel = new JPanel(new GridLayout(0, 1));
// JPanel pInput = new JPanel(new BorderLayout());
// panel.add(new JLabel(Messages.getString("MaskImportDialog.1"))); //$NON-NLS-1$
// pInput.add(this.textFileTextField, BorderLayout.CENTER);
//
// JButton buttonBrowse = new JButton("..."); //$NON-NLS-1$
// buttonBrowse.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// JFileChooser fileChooser = new JFileChooser();
// int returnVal = fileChooser
// .showOpenDialog(MaskImportDialog.this);
// if (returnVal == JFileChooser.APPROVE_OPTION) {
// MaskImportDialog.this.textFileTextField.setText(fileChooser
// .getSelectedFile().getPath());
// }
// }
// });
// pInput.add(buttonBrowse, BorderLayout.EAST);
// panel.add(pInput);
panel.add(new JLabel(Messages.getString("MaskImportDialog.4"))); //$NON-NLS-1$
panel.add(idListTextFied);
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(maskedRadioButton);
buttonGroup.add(unmaskedRadioButton);
maskedRadioButton.setSelected(true);
panel.add(maskedRadioButton);
panel.add(unmaskedRadioButton);
JPanel panelButton = new JPanel();
JButton buttonOk = new JButton(Messages.getString("MaskImportDialog.7")); //$NON-NLS-1$
panelButton.add(buttonOk);
buttonOk.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
buttonOk_actionPerformed();
}
});
mainPanel.add(panel, BorderLayout.NORTH);
mainPanel.add(panelButton, BorderLayout.SOUTH);
this.setContentPane(mainPanel);
this.setTitle(Messages.getString("MaskImportDialog.0")); //$NON-NLS-1$
this.setSize(470, 250);
this.setResizable(true);
this.setModal(true);
// this.setVisible(true);
}
protected void buttonOk_actionPerformed() {
// get the ignored parameter
boolean ignore = maskedRadioButton.isSelected();
// get the id parameter
int[] idList = null;
try {
List<String> parsing = CSVUtils.parseLine(idListTextFied.getText(), ';');
idList = new int[parsing.size()];
for (int i = 0 ; i < parsing.size() ; i++) {
idList[i] = Integer.parseInt(parsing.get(i));
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this,
Messages.getString("ArffToDataDialog.94"), //$NON-NLS-1$
Messages.getString("ArffToDataDialog.93"), //$NON-NLS-1$
JOptionPane.WARNING_MESSAGE);
e.printStackTrace();
}
// get the mask itself
int[] content = null;
try {
StreamedImageReaderWrapper reader = new StreamedImageReaderWrapper(path);
content = new int[reader.getImageWidth()*reader.getImageHeight()];
int index = 0;
for(int y = 0 ; y < reader.getImageHeight() ; y++) {
for(int x = 0 ; x < reader.getImageWidth() ; x++) {
content[index] = (int) reader.getPixel(x, y)[0];
index++;
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this,
Messages.getString("ArffToDataDialog.41"), //$NON-NLS-1$
Messages.getString("ArffToDataDialog.4"), //$NON-NLS-1$
JOptionPane.WARNING_MESSAGE);
e.printStackTrace();
}
//generate the mask and apply it the rawImage
Mask mask = null;
if (idList.length > 1) {
mask = new MultiIDIntArrayMask(content, idList, ignore);
} else {
mask = new IntArrayMask(content, idList[0], ignore);
}
if (rawImage != null) {
rawImage.setMask(mask);
} else if (dataConstructPanel != null) {
dataConstructPanel.setSampleMask(mask);
}
this.dispose();
}
}
package mustic.gui.dialog;
package mustic.gui.dialog.arff;
import java.awt.BorderLayout;
import java.awt.Color;
......@@ -29,6 +29,8 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import mustic.gui.dialog.Messages;
/**
* Fenetre permettant de lire les fichiers arff et de creer les images résultats
*
......
package mustic.gui.dialog;
package mustic.gui.dialog.arff;
import java.awt.BorderLayout;
import java.awt.Dialog;
......@@ -25,6 +25,8 @@ import jcl.data.SimpleData;
import jcl.data.attribute.AttributeMultiDimSequence;
import jcl.data.sampling.ImportedImageSampler;
import mustic.gui.MainFrame;
import mustic.gui.dialog.Messages;
import mustic.gui.dialog.SequenceDialog;
import mustic.io.ImageData;
import mustic.io.RawImage;
import mustic.utils.documentFilter.ToUpdateObject;
......@@ -135,7 +137,7 @@ public class ArffToDataDialog extends JInternalFrame implements ToUpdateObject {
}
}
@SuppressWarnings({ "unused", "unchecked", "deprecation" })
@SuppressWarnings({ "unchecked", "deprecation" })
protected void buttonOk_actionPerformed() {
try {
Object[] result = DataArffExchange.arffToData(this.textFile.getText());
......
package mustic.gui.dialog;
package mustic.gui.dialog.arff;
import java.awt.BorderLayout;
import java.awt.Dimension;
......@@ -19,6 +19,8 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import mustic.gui.dialog.Messages;
//import mustic.io.geotiff.GEOTiffImage;
/**
......
package mustic.gui.dialog;
package mustic.gui.dialog.arff;
import java.awt.BorderLayout;
import java.awt.Dimension;
......@@ -22,6 +22,7 @@ import javax.swing.JTextField;
import jcl.data.Data;
import mustic.gui.DataDesktopFrame;
import mustic.gui.MainFrame;
import mustic.gui.dialog.Messages;
import mustic.utils.io.dataExchange.DataArffExchange;
/**
......
package mustic.gui.dialog;
package mustic.gui.dialog.arff;
import java.awt.BorderLayout;
import java.awt.Dimension;
......@@ -25,9 +25,9 @@ import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import mustic.gui.DesktopFrame;
import mustic.gui.ImageDesktopFrame;
import mustic.gui.MainFrame;
import mustic.gui.dialog.Messages;
import mustic.io.RawImage;
/**
......@@ -39,7 +39,7 @@ public class ImageToArffDialog extends JInternalFrame {
private static final long serialVersionUID = 1L;
/** liste des images ouvertes */
private JComboBox comboImage = new JComboBox();
private JComboBox<String> comboImage = new JComboBox<String>();
/** nombre de divisions */
private JSpinner spinner = new JSpinner();
......
package mustic.gui.dialog;
package mustic.gui.dialog.arff;
import java.awt.BorderLayout;
import java.awt.Dimension;
......@@ -20,9 +20,9 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import mustic.gui.DesktopFrame;
import mustic.gui.ImageDesktopFrame;
import mustic.gui.MainFrame;
import mustic.gui.dialog.Messages;
import mustic.io.RawImage;
/**
......@@ -34,7 +34,7 @@ public class RawImageToArffDialog extends JInternalFrame {
private static final long serialVersionUID = 1L;
/** liste des images ouvertes */
private JComboBox comboImage = new JComboBox();
private JComboBox<String> comboImage = new JComboBox<String>();
/** nombre de divisions */
......
......@@ -201,17 +201,28 @@ ImageToArffDialog.45=Successful
ImageToArffDialog.5=other...
ImageToArffDialog.6=ImageToArffDialog \=> Nr. sesiune 1 \=
ImageToArffDialog.7=ImageToArffDialog \=> Nr. sesiune 2 \=
MaskImportDialog.0=Import Mask
MaskImportDialog.1=Select an image file to import as a mask :
MaskImportDialog.2=...
MaskImportDialog.4=Take in consideration the following values (integers separated by ';')
MaskImportDialog.5=consider them as masked pixels
MaskImportDialog.6=consider them as unmasked pixels
MaskImportDialog.7=OK
MaskImportDialog.91=Warning
MaskImportDialog.92=File selected isn't supported
MaskImportDialog.93=Error
MaskImportDialog.94=Entered values are not well formated
RgbBandChooserInternalFrame.0=Choose RBG
RgbBandChooserInternalFrame.10=Display level of grey
RgbBandChooserInternalFrame.11=NG
RgbBandChooserInternalFrame.12=Ok
RgbBandChooserInternalFrame.15=Pour supprimer des bandes voir le
RgbBandChooserInternalFrame.16=menu "Clustering" ou le menu
RgbBandChooserInternalFrame.17="Crop".
RgbBandChooserInternalFrame.2=band
RgbBandChooserInternalFrame.3=band
RgbBandChooserInternalFrame.4=band
RgbBandChooserInternalFrame.5=band
RgbBandChooserInternalFrame.15=To delete some channels look at
RgbBandChooserInternalFrame.16="Clustering" menu or
RgbBandChooserInternalFrame.17="Crop" menu.
RgbBandChooserInternalFrame.2=channel
RgbBandChooserInternalFrame.3=channel
RgbBandChooserInternalFrame.4=channel
RgbBandChooserInternalFrame.5=channel
RgbBandChooserInternalFrame.6=Color display
RgbBandChooserInternalFrame.7=R
RgbBandChooserInternalFrame.8=G
......
......@@ -8,8 +8,9 @@ import java.util.Vector;
import javax.swing.*;
import jcl.data.mask.Mask;
import mustic.gui.*;
import mustic.io.Mask;
import mustic.io.MusticImageMask;
import mustic.io.RawImage;
import mustic.io.roi.RegionOfInterest;
import mustic.utils.filters.ZipFileFilter;
......@@ -72,6 +73,8 @@ public class ImagePanel extends JPanel {
/** contrast step */
private float scaleFactorStep = 0.1f;
private RawImage rawImage = null;
/**
* Create a new ImagePanel from a BufferedImage.
......@@ -93,7 +96,7 @@ public class ImagePanel extends JPanel {
* @param infoPanel acces to the information panel
*/
public ImagePanel(RawImage aImage) {
this.rawImage = aImage;
this.mImageLabel = new JLabel();
this.mImageLabel.setHorizontalAlignment(SwingConstants.CENTER);
setLayout(new BorderLayout());
......@@ -238,13 +241,25 @@ public class ImagePanel extends JPanel {
}
public void applyMask(Mask mask) {
Rectangle rect = MainFrame.getInstance().getCurrentImageSession().getBirdViewPanel().getSelArea();// birdViewPanel.getSelArea();
int xorig = rect.x;
int yorig = rect.y;
for (int x = 0; x < this.mScreenImage.getWidth(); x++) {
for (int y = 0; y < this.mScreenImage.getHeight(); y++) {
if (mask.isMasked(x + xorig, y + yorig))
if(rawImage == null) {
return;
}
int xorig = MainFrame.getInstance().getCurrentImageSession().getBirdViewPanel().xxsave;
int yorig = MainFrame.getInstance().getCurrentImageSession().getBirdViewPanel().yysave;
// double x2 = e.getX() - ((mImageLabel.getWidth() - mImageLabel.getIcon().getIconWidth()) / 2.0);
// double y2 = e.getY() - ((mImageLabel.getHeight() - mImageLabel.getIcon().getIconHeight()) / 2.0);
// x2 = x2 / mZoomRate;
// y2 = y2 / mZoomRate;
// int x = (int) x2 + MainFrame.getInstance().getCurrentImageSession().getBirdViewPanel().xxsave;
// // birdViewPanel.xxsave;
// int y = (int) y2 + MainFrame.getInstance().getCurrentImageSession().getBirdViewPanel().yysave;
for (int y = 0; y < this.mScreenImage.getHeight(); y++) {
int y_offset = (y+yorig) * this.rawImage.getWidth();
for (int x = 0; x < this.mScreenImage.getWidth(); x++) {
if (mask.isMasked(x + xorig + y_offset))
this.mScreenImage.setRGB(x, y, 0);
}
}
......
......@@ -23,6 +23,7 @@ import jcl.data.DataObject;
import jcl.data.SimpleData;
import jcl.data.attribute.AttributeMultiDimSequence;
import jcl.data.attribute.AttributeNumerical;
import jcl.data.mask.Mask;
import jcl.evaluation.clustering.ResultsComparison;
import jcl.learning.*;
import jcl.learning.methods.monostrategy.SingleClassification;
......@@ -430,7 +431,7 @@ public class ImageResultPanel extends ResultPanel implements TreeSelectionListen
Mask mask = this.imgData.getRawImages().get(0).getMask();
int nbObjects = width;
if (mask != null)
nbObjects -= mask.getNbMaskedPixelsInRow(y);
nbObjects -= mask.getCardinalityInInterval(y*width, (y+1)*width -1);
Data dataPart = new SimpleData(nbObjects);
for (int x2 = 0, cur = 0; x2 < buffer[0].length; x2++) {
......
......@@ -13,6 +13,7 @@ import javax.swing.JScrollPane;
import com.l2fprod.common.swing.JTaskPane;
import com.l2fprod.common.swing.JTaskPaneGroup;
import jcl.data.mask.Mask;
import jcl.data.sampling.Sampler;
import mustic.gui.ImageDesktopFrame;
import mustic.gui.MainFrame;
......@@ -50,7 +51,6 @@ public class DataConstructPanel extends JPanel implements ToUpdateObject {
private Sampler sample = null;
/**
* Constructor
*/
......@@ -118,6 +118,7 @@ public class DataConstructPanel extends JPanel implements ToUpdateObject {
private void generateData() {
ImageData data = null;
if (filesPaths.size() > 1) {
data = new ImageData(sample, filesPaths);
} else {
......@@ -203,7 +204,30 @@ public class DataConstructPanel extends JPanel implements ToUpdateObject {
this.sample = sample;
updateSamplingSelectionPanel();
}
/**
* The mask that will be applied to the sample construction
*
* @return the mask
*/
public Mask getSampleMask() {
return sample.getMask();
}
/**
* Apply a mask to the sample construction
*
* @param sampleMask
* the mask, null to disable the mask application
*/
public void setSampleMask(Mask sampleMask) {
this.sample.setMask(sampleMask);
updateSamplingSelectionPanel();
}
/**
* Initialize the source selection section of the panel
*/
public void initializeSourceSelectionPanel() {
sourcePanel.initialize();
}
......
......@@ -183,11 +183,15 @@ public class SamplingSelectionPanel extends JPanel implements ToUpdateObject {
private void setCountLabel() {
String totalCountCaption = "/_";
if(fatherContainer.getSample() != null) {
totalCountCaption = "/"+fatherContainer.getSample().getDataSize();
totalCountCaption = "/"+fatherContainer.getSample().getUnmaskedDataSize();
}
byCountLabel.setText(totalCountCaption);
}
/**
* Set the maximum number possible for the "by count" parameter
* @param max
*/
private void setCountFormatter(int max) {
// NumberFormat format = NumberFormat.getInstance();
// countFormatter = new NumberFormatter(format);
......@@ -296,7 +300,8 @@ public class SamplingSelectionPanel extends JPanel implements ToUpdateObject {
if (fatherContainer.getSample() != null) {
fatherContainer.getSample().setSizeByPercent(getPercentage(byPercentTextField.getText()));
byCountTextField.setText(""+fatherContainer.getSample().getSizeByCount());
setCountFormatter(fatherContainer.getSample().getDataSize());
setCountFormatter(fatherContainer.getSample().getUnmaskedDataSize());
} else {
byCountTextField.setText("0");
// we don't change the percentage
......
......@@ -2,14 +2,19 @@ package mustic.gui.panels.data.components;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
......@@ -18,8 +23,10 @@ import jcl.data.sampling.ImageSampler;
import loci.formats.FormatException;
import mustic.gui.ImageDesktopFrame;
import mustic.gui.MainFrame;
import mustic.gui.dialog.MaskImportDialog;
import mustic.gui.panels.data.DataConstructPanel;
import mustic.gui.panels.data.Messages;
import mustic.io.MusticImageMask;
import mustic.io.RawImage;
/**
......@@ -43,7 +50,7 @@ public class SourceSelectionPanel extends JPanel {
private ButtonGroup sourceModeSelection = new ButtonGroup();
private JRadioButton imageFilesButton = new JRadioButton(
Messages.getString("source.02"), true);
Messages.getString("source.02"), true); //$NON-NLS-1$
private JRadioButton monoDateRadioButton = null;
......@@ -52,11 +59,17 @@ public class SourceSelectionPanel extends JPanel {
private JRadioButton multiDateRadioButton = null;
private JButton multiDateButton = null;
private JCheckBox sequenceMaskCheckBox = null;
private JLabel maskLabel = new JLabel("_"); //$NON-NLS-1$
private JPanel parameterContainer = null;
/** store the sessions used to build the combobox, the order might change
* in the MusticDesktop, so we use it to search by index */
private ImageDesktopFrame[] allImageDesktopFrames = null;
/**
* Constructor
*
......@@ -71,24 +84,83 @@ public class SourceSelectionPanel extends JPanel {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel currentPanel = new JPanel();
currentPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel filePanel = new JPanel();
filePanel.setLayout(new FlowLayout(FlowLayout.LEFT));