/*
 * SOMImageTester.java
 * This sample application uses some code written by Jeff Heaton took by the article
 * "Programming Neural Networks in Java" at http://www.jeffheaton.com/ai/index.shtml
 */

package org.joone.samples.editor.som;

import java.io.*;

/**
 *
 * @author  Julien Norman
 */
public class SOMImageTester extends javax.swing.JFrame {
    
    private int DrawSizeX = 81;
    private int DrawSizeY = 81;
    private int ScaleSizeX = 9;
    private int ScaleSizeY = 9;
    private java.util.Vector imageHolder = new java.util.Vector();
    private java.awt.Image downsamplePreviewImage = null;
    private java.awt.image.BufferedImage downSample = new java.awt.image.BufferedImage(getScaleSizeX(),getScaleSizeY(),java.awt.image.BufferedImage.TYPE_INT_RGB);
    private java.awt.image.BufferedImage drawImage = new java.awt.image.BufferedImage(getDrawSizeX(),getDrawSizeY(),java.awt.image.BufferedImage.TYPE_INT_RGB);
    private java.util.Vector idHolder = new java.util.Vector();
    private int currentImage = 0;
    private boolean alone; // true if launched from the command prompt
    /**
     * Specifies the left boundary of the cropping
     * rectangle.
     */
    protected int downSampleLeft;
    
    /**
     * Specifies the right boundary of the cropping
     * rectangle.
     */
    protected int downSampleRight;
    
    /**
     * Specifies the top boundary of the cropping
     * rectangle.
     */
    protected int downSampleTop;
    
    /**
     * Specifies the bottom boundary of the cropping
     * rectangle.
     */
    protected int downSampleBottom;
    
    /**
     * The downsample ratio for x.
     */
    protected double ratioX;
    
    /**
     * The downsample ratio for y
     */
    protected double ratioY;
    
    /**
     * The pixel map of what the user has drawn.
     * Used to downsample it.
     */
    protected int pixelMap[];
    
    /** Creates new form SOMImageTester */
    public SOMImageTester() {
        this(false);
    }
    
    /** Creates new form SOMImageTester */
    public SOMImageTester(boolean main) {
        alone = main;
        initComponents();
        setup();
        setSize(300,350);
        setResizable(false);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        ImageHolderPanel = new javax.swing.JPanel();
        PainterPanel = new ImagePainter();
        DownsamplePanel = new ImageDrawer();
        InfoPanel = new javax.swing.JPanel();
        ImageIDLabel = new javax.swing.JLabel();
        IDInputTextField = new javax.swing.JTextField();
        ImageNoLabel = new javax.swing.JLabel();
        DownSampleButton = new javax.swing.JButton();
        ImageScrollBar = new javax.swing.JScrollBar();
        ControlPanel = new javax.swing.JPanel();
        HelpButton = new javax.swing.JButton();
        NewImageButton = new javax.swing.JButton();
        ClearImageButton = new javax.swing.JButton();
        SaveImagesButton = new javax.swing.JButton();
        QuitButton = new javax.swing.JButton();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        ImageHolderPanel.setLayout(new java.awt.GridLayout(1, 2));

        PainterPanel.setToolTipText("You can draw on this image.");
        ImageHolderPanel.add(PainterPanel);

        DownsamplePanel.setToolTipText("This contains the down sampled image.");
        ImageHolderPanel.add(DownsamplePanel);

        getContentPane().add(ImageHolderPanel, java.awt.BorderLayout.CENTER);

        InfoPanel.setLayout(new java.awt.GridLayout(2, 2));

        ImageIDLabel.setText("Image ID");
        InfoPanel.add(ImageIDLabel);

        IDInputTextField.setText("1");
        InfoPanel.add(IDInputTextField);

        ImageNoLabel.setFont(new java.awt.Font("Dialog", 1, 14));
        ImageNoLabel.setText("Image 1 of 1");
        ImageNoLabel.setToolTipText("The current image number.");
        InfoPanel.add(ImageNoLabel);

        DownSampleButton.setText("Down Sample");
        DownSampleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DownSampleButtonActionPerformed(evt);
            }
        });

        InfoPanel.add(DownSampleButton);

        getContentPane().add(InfoPanel, java.awt.BorderLayout.NORTH);

        ImageScrollBar.setMaximum(1);
        ImageScrollBar.setMinimum(1);
        ImageScrollBar.setToolTipText("Use scroll bar to scroll through images.");
        ImageScrollBar.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                OnScrolled(evt);
            }
        });

        getContentPane().add(ImageScrollBar, java.awt.BorderLayout.EAST);

        ControlPanel.setLayout(new java.awt.GridLayout(5, 2));

        ControlPanel.setBorder(new javax.swing.border.TitledBorder("Controls"));
        HelpButton.setText("Help");
        HelpButton.setToolTipText("Help on this application.");
        HelpButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                HelpButtonActionPerformed(evt);
            }
        });

        ControlPanel.add(HelpButton);

        NewImageButton.setText("New Image");
        NewImageButton.setToolTipText("Create a new image.");
        NewImageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NewImageButtonActionPerformed(evt);
            }
        });

        ControlPanel.add(NewImageButton);

        ClearImageButton.setText("Clear Image");
        ClearImageButton.setToolTipText("Clear the drawing from this image.");
        ClearImageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ClearImageButtonActionPerformed(evt);
            }
        });

        ControlPanel.add(ClearImageButton);

        SaveImagesButton.setText("Save Images");
        SaveImagesButton.setToolTipText("Save the images out to Joone format.");
        SaveImagesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SaveImagesButtonActionPerformed(evt);
            }
        });

        ControlPanel.add(SaveImagesButton);

        QuitButton.setText("Quit");
        QuitButton.setToolTipText("Quit this application.");
        QuitButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                QuitButtonActionPerformed(evt);
            }
        });

        ControlPanel.add(QuitButton);

        getContentPane().add(ControlPanel, java.awt.BorderLayout.SOUTH);

        pack();
    }//GEN-END:initComponents
    
    private void HelpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_HelpButtonActionPerformed
        // Add your handling code here:
        // Produce a quick help box
        String help1 = new String("This application allows the user to draw characters or images for recognition by a Joone neural network.");
        String help2 = new String("It is intended to test a SOM or Kohonen Network by providing an image recognition example.");
        String help3 = new String("The drawing image grid is 81 X 81 but the images saved in the file are 9x9 down sampled images.");
        String help4 = new String("The saved file has 81 inputs and an id.  The id can be used to identify the character.");
        String help5 = new String("Read the Editor's help pages to learn how to use this example.");
        
        javax.swing.JOptionPane.showMessageDialog(this,help1+"\n"+help2+"\n"+help3+"\n"+help4+"\n"+help5);
        
    }//GEN-LAST:event_HelpButtonActionPerformed
    
    private void QuitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_QuitButtonActionPerformed
        // Add your handling code here:
        this.exitTester();
    }//GEN-LAST:event_QuitButtonActionPerformed
    
    private void SaveImagesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveImagesButtonActionPerformed
        // Add your handling code here:
        SaveImagesOut();
    }//GEN-LAST:event_SaveImagesButtonActionPerformed
    
    private void NewImageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NewImageButtonActionPerformed
        // Add your handling code here:
        NewImage();
    }//GEN-LAST:event_NewImageButtonActionPerformed
    
    private void ClearImageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ClearImageButtonActionPerformed
        // Add your handling code here:
        clearCurrentImage();
    }//GEN-LAST:event_ClearImageButtonActionPerformed
    
    private void DownSampleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DownSampleButtonActionPerformed
        // Add your handling code here:
        downSample();
        repaint();
    }//GEN-LAST:event_DownSampleButtonActionPerformed
    
    private void OnScrolled(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_OnScrolled
        // Add your handling code here:
        Integer id = null;
        if ( evt.getAdjustmentType() == java.awt.event.AdjustmentEvent.TRACK ) {
            if ( evt.getValue() <= imageHolder.size() ) {
                try {
                    id = new Integer(IDInputTextField.getText());
                }
                catch(java.lang.NumberFormatException ex) {
                    ImageScrollBar.setValue(ImageScrollBar.getValue()-ImageScrollBar.getUnitIncrement());
                    javax.swing.JOptionPane.showMessageDialog(this,"ID must be an integer value.");
                    return;
                }
                idHolder.set(currentImage-1, id);
                currentImage = evt.getValue();
                IDInputTextField.setText(""+((Integer)idHolder.get(currentImage-1)).intValue());
                drawImage = (java.awt.image.BufferedImage)imageHolder.get(currentImage-1);
                ((ImagePainter)PainterPanel).setImageToEdit(drawImage);
                downSample();
                ImageNoLabel.setText("Image 1 of "+currentImage);
                repaint();
                //PainterPanel.repaint();
                //DownsamplePanel.repaint();
            }
        }
    }//GEN-LAST:event_OnScrolled
    
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
        this.exitTester();
    }//GEN-LAST:event_exitForm
    
    private void exitTester() {
        if (alone)
            System.exit(0);
        else
            this.dispose();
    }
    
    /**
     *
     */
    public void setup() {
        if ( imageHolder != null ) {
            drawImage.getGraphics().setColor(new java.awt.Color(255,255,255));
            drawImage.getGraphics().fillRect(0,0, drawImage.getWidth(),drawImage.getHeight());
            imageHolder.add(drawImage);
            ((ImagePainter)PainterPanel).setImageToEdit(drawImage);
            
            if ( downsamplePreviewImage!= null) {
                downsamplePreviewImage.getGraphics().setColor(java.awt.Color.WHITE);
                downsamplePreviewImage.getGraphics().fillRect(0,0, downsamplePreviewImage.getWidth(this),downsamplePreviewImage.getHeight(this));
                ((ImageDrawer)DownsamplePanel).setImageToDraw(downsamplePreviewImage);
            }
            idHolder.add(new Integer(1));
            currentImage = 1;
        }
        repaint();
    }
    
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new SOMImageTester().show();
    }
    
    /** Getter for property DrawSizeX.
     * @return Value of property DrawSizeX.
     *
     */
    public int getDrawSizeX() {
        return DrawSizeX;
    }
    
    /** Setter for property DrawSizeX.
     * @param DrawSizeX New value of property DrawSizeX.
     *
     */
    public void setDrawSizeX(int DrawSizeX) {
        this.DrawSizeX = DrawSizeX;
    }
    
    /** Getter for property DrawSizeY.
     * @return Value of property DrawSizeY.
     *
     */
    public int getDrawSizeY() {
        return DrawSizeY;
    }
    
    /** Setter for property DrawSizeY.
     * @param DrawSizeY New value of property DrawSizeY.
     *
     */
    public void setDrawSizeY(int DrawSizeY) {
        this.DrawSizeY = DrawSizeY;
    }
    
    /** Getter for property ScaleSizeX.
     * @return Value of property ScaleSizeX.
     *
     */
    public int getScaleSizeX() {
        return ScaleSizeX;
    }
    
    /** Setter for property ScaleSizeX.
     * @param ScaleSizeX New value of property ScaleSizeX.
     *
     */
    public void setScaleSizeX(int ScaleSizeX) {
        this.ScaleSizeX = ScaleSizeX;
    }
    
    /** Getter for property ScaleSizeY.
     * @return Value of property ScaleSizeY.
     *
     */
    public int getScaleSizeY() {
        return ScaleSizeY;
    }
    
    /** Setter for property ScaleSizeY.
     * @param ScaleSizeY New value of property ScaleSizeY.
     *
     */
    public void setScaleSizeY(int ScaleSizeY) {
        this.ScaleSizeY = ScaleSizeY;
    }
    
    /**
     * Clears the current image to white.
     */
    public void clearCurrentImage() {
        drawImage.getGraphics().setColor(java.awt.Color.WHITE);
        drawImage.getGraphics().fillRect(0,0, drawImage.getWidth(),drawImage.getHeight());
        downSample();
        repaint();
    }
    
    /**
     * Creates a new image and updates the scroll bar values.
     */
    public void NewImage() {
        if ( imageHolder != null) {
            if ( idHolder != null ) {
                downSample = new java.awt.image.BufferedImage(getScaleSizeX(),getScaleSizeY(),java.awt.image.BufferedImage.TYPE_INT_RGB);
                drawImage = new java.awt.image.BufferedImage(getDrawSizeX(),getDrawSizeY(),java.awt.image.BufferedImage.TYPE_INT_RGB);
                clearCurrentImage();
                Integer cur_id = (Integer)idHolder.get(currentImage-1);
                currentImage++;
                imageHolder.add(drawImage);
                idHolder.add(cur_id);
                IDInputTextField.setText(""+cur_id.intValue());
                ImageScrollBar.setMaximum(currentImage);
                ImageScrollBar.setValue(currentImage);
                ((ImagePainter)PainterPanel).setImageToEdit(drawImage);
                ((ImageDrawer)DownsamplePanel).setImageToDraw(downsamplePreviewImage);
                ImageNoLabel.setText("Image 1 of "+currentImage);
                repaint();
            }
        }
    }
    
    /**
     * This method is called internally to
     * see if there are any pixels in the given
     * scan line. This method is used to perform
     * autocropping.
     *
     * @param y The horizontal line to scan.
     * @return True if there were any pixels in this
     * horizontal line.
     */
    protected boolean hLineClear(int y) {
        int w = drawImage.getWidth(this);
        for ( int i=0;i=0;y-- ) {
            if ( !hLineClear(y) ) {
                downSampleBottom=y;
                break;
            }
        }
        // left line
        for ( int x=0;x=0;x-- ) {
            if ( !vLineClear(x) ) {
                downSampleRight = x;
                break;
            }
        }
    }
    
    
    /**
     * Called to downsample a quadrant of the image.
     *
     * @param x The x coordinate of the resulting
     * downsample.
     * @param y The y coordinate of the resulting
     * downsample.
     * @return Returns true if there were ANY pixels
     * in the specified quadrant.
     */
    protected boolean downSampleQuadrant(int x,int y) {
        int w = drawImage.getWidth(this);
        int startX = (int)(downSampleLeft+(x*ratioX));
        int startY = (int)(downSampleTop+(y*ratioY));
        int endX = (int)(startX + ratioX);
        int endY = (int)(startY + ratioY);
        
        for ( int yy=startY;yy<=endY;yy++ ) {
            for ( int xx=startX;xx<=endX;xx++ ) {
                int loc = xx+(yy*w);
                
                if ( pixelMap[ loc  ]!= -1 )
                    return true;
            }
        }
        
        return false;
    }
    
    
    /**
     * Called to downsample the image and store
     * it in the down sample component.
     */
    public void downSample() {
        int w = drawImage.getWidth(this);
        int h = drawImage.getHeight(this);
        
        java.awt.image.PixelGrabber grabber = new java.awt.image.PixelGrabber(drawImage,0,0,w,h,true);
        
        try {
            
            grabber.grabPixels();
            pixelMap = (int[])grabber.getPixels();
            findBounds(w,h);
            
            // now downsample
            ratioX = (double)(downSampleRight - downSampleLeft)/(double)downSample.getWidth();
            ratioY = (double)(downSampleBottom - downSampleTop)/(double)downSample.getHeight();
            
            for ( int y=0;y 

Ads help maintain this website.