Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2013
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.91 KB | None | 0 0
  1. package net.ahinrichs.htw.bv.ue04;
  2.  
  3. import javax.swing.*;
  4. import javax.swing.event.ChangeEvent;
  5. import javax.swing.event.ChangeListener;
  6. import javax.swing.filechooser.FileNameExtensionFilter;
  7. import java.awt.event.*;
  8. import java.awt.*;
  9. import java.io.File;
  10. import java.util.Arrays;
  11. import java.util.Map;
  12. import java.util.TreeMap;
  13.  
  14. public class BinaryMorphoFilter extends JPanel {
  15.  
  16.     private static final long serialVersionUID = 1L;
  17.     private static final String author = "Alexander Hinrichs; Markus Bausdorf"; // type
  18.                                                                                 // in
  19.                                                                                 // your
  20.                                                                                 // name
  21.                                                                                 // here
  22.     private static final String initialFilename = "rhino_part.png";
  23.     private static final int border = 10;
  24.     private static final int maxWidth = 900;
  25.     private static final int maxHeight = 900;
  26.     private static final double limitStepSize = 5.0; // size used for angle
  27.                                                         // increment and
  28.                                                         // decrement
  29.  
  30.     private static JFrame frame;
  31.  
  32.     private ImageView srcView = null; // source image view
  33.     private ImageView dstView = null; // rotated image view
  34.  
  35.     private JComboBox methodList; // the selected rotation method
  36.     private JSlider limitSlider; // the selected rotation angle
  37.     private JLabel statusLine; // to print some status text
  38.     private double limit = 128.0; // current rotation angle in degrees
  39.     private JSlider radiusSlider; // the selected rotation angle
  40.     private double filterRadius = 0.0; // current rotation angle in degrees
  41.     private int filterCoreDim = 11;
  42.     private double[][] filterCore;
  43.  
  44.     /**
  45.      * Constructor. Constructs the layout of the GUI components and loads the
  46.      * initial image.
  47.      */
  48.     public BinaryMorphoFilter() {
  49.         super(new BorderLayout(border, border));
  50.  
  51.         // load the default image
  52.         File input = new File(initialFilename);
  53.  
  54.         if (!input.canRead())
  55.             input = openFile(); // file not found, choose another image
  56.  
  57.         // configure both viewscreens
  58.         srcView = new ImageView(input);
  59.         srcView.setMaxSize(new Dimension(maxWidth, maxHeight));
  60.         dstView = new ImageView(input);
  61.         dstView.setMaxSize(new Dimension(maxWidth, maxHeight));
  62.  
  63.         // load image button
  64.         JButton load = new JButton("Open Image");
  65.         load.addActionListener(new ActionListener() {
  66.             public void actionPerformed(ActionEvent e) {
  67.                 File input = openFile();
  68.                 if (input != null) {
  69.                     srcView.loadImage(input);
  70.                     srcView.setMaxSize(new Dimension(maxWidth, maxHeight));
  71.                     dstView.loadImage(input);
  72.                     dstView.setMaxSize(new Dimension(maxWidth, maxHeight));
  73.                 }
  74.             }
  75.         });
  76.  
  77.         // method names for the filter selection
  78.         String[] methodNames = { "Original", "Binary picture",
  79.                 "Erosion/Dilation" };
  80.  
  81.         // filter selector combobox
  82.         methodList = new JComboBox(methodNames);
  83.         methodList.setSelectedIndex(0); // set initial method
  84.         methodList.addActionListener(new ActionListener() {
  85.             public void actionPerformed(ActionEvent e) {
  86.                 filterSelector(methodList.getSelectedIndex());
  87.             }
  88.         });
  89.  
  90.         // Slider to adjust the threshold for binary filtering
  91.         limitSlider = new JSlider(0, 255, (int) limit);
  92.         limitSlider.addChangeListener(new ChangeListener() {
  93.             public void stateChanged(ChangeEvent e) {
  94.                 limit = limitSlider.getValue();
  95.                 filterSelector(methodList.getSelectedIndex());
  96.             }
  97.         });
  98.  
  99.         // Slider to adjust the radius for erosion/dilation
  100.         radiusSlider = new JSlider(-50, +50, (int) filterRadius);
  101.         radiusSlider.addChangeListener(new ChangeListener() {
  102.             public void stateChanged(ChangeEvent e) {
  103.                 filterRadius = radiusSlider.getValue() / 10d;
  104.                 filterSelector(methodList.getSelectedIndex());
  105.             }
  106.         });
  107.  
  108.         // some status text
  109.         statusLine = new JLabel(" ");
  110.  
  111.         // arrange all controls
  112.         JPanel controls = new JPanel(new GridBagLayout());
  113.         GridBagConstraints c = new GridBagConstraints();
  114.         c.insets = new Insets(0, border, 0, 0);
  115.         controls.add(load, c);
  116.         controls.add(methodList, c);
  117.         controls.add(new JLabel("Treshold:"), c);
  118.         controls.add(limitSlider, c);
  119.         controls.add(new JLabel("r:"), c);
  120.         controls.add(radiusSlider, c);
  121.  
  122.         // arrange images
  123.         JPanel images = new JPanel();
  124.         images.add(srcView);
  125.         images.add(dstView);
  126.  
  127.         // add to main panel
  128.         add(controls, BorderLayout.NORTH);
  129.         add(images, BorderLayout.CENTER);
  130.         add(statusLine, BorderLayout.SOUTH);
  131.  
  132.         // add border to main panel
  133.         setBorder(BorderFactory.createEmptyBorder(border, border, border,
  134.                 border));
  135.        
  136.         // precalculate filter core
  137.         filterCore = makeFilterCore();
  138.     }
  139.  
  140.     /**
  141.      * Set up and show the main frame.
  142.      */
  143.     private static void createAndShowGUI() {
  144.         // create and setup the window
  145.         frame = new JFrame("BinaryMorphoFilter - " + author);
  146.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  147.  
  148.         JComponent contentPane = new BinaryMorphoFilter();
  149.         contentPane.setOpaque(true); // content panes must be opaque
  150.         frame.setContentPane(contentPane);
  151.  
  152.         // display the window
  153.         frame.pack();
  154.         Toolkit toolkit = Toolkit.getDefaultToolkit();
  155.         Dimension screenSize = toolkit.getScreenSize();
  156.         frame.setLocation((screenSize.width - frame.getWidth()) / 2,
  157.                 (screenSize.height - frame.getHeight()) / 2);
  158.         frame.setVisible(true);
  159.     }
  160.  
  161.     /**
  162.      * Main method.
  163.      *
  164.      * @param args
  165.      *            - ignored. No arguments are used by this application.
  166.      */
  167.     public static void main(String[] args) {
  168.         // schedule a job for the event-dispatching thread:
  169.         // creating and showing this application's GUI.
  170.         javax.swing.SwingUtilities.invokeLater(new Runnable() {
  171.             public void run() {
  172.                 createAndShowGUI();
  173.             }
  174.         });
  175.     }
  176.  
  177.     /**
  178.      * Open file dialog used to select a new image.
  179.      *
  180.      * @return The selected file object or null on cancel.
  181.      */
  182.     private File openFile() {
  183.         // file open dialog
  184.         JFileChooser chooser = new JFileChooser();
  185.         FileNameExtensionFilter filter = new FileNameExtensionFilter(
  186.                 "Images (*.jpg, *.png, *.gif)", "jpg", "png", "gif");
  187.         chooser.setFileFilter(filter);
  188.         int ret = chooser.showOpenDialog(this);
  189.         if (ret == JFileChooser.APPROVE_OPTION)
  190.             return chooser.getSelectedFile();
  191.         return null;
  192.     }
  193.  
  194.     /**
  195.      * Method to execute the selected filtering on the given image
  196.      *
  197.      * @param method
  198.      *            ComboBox selected method index
  199.      */
  200.     private void filterSelector(int method) {
  201.         switch (method) {
  202.         case 0:
  203.             dstView.setPixels(srcView.getPixels());
  204.             break;
  205.         case 1:
  206.             makeBinaryImage();
  207.             break;
  208.         case 2:
  209.             makeErosionDilation();
  210.             break;
  211.         default:
  212.             break;
  213.         }
  214.     }
  215.  
  216.     /**
  217.      * Convert image to binary, using a variable threshold
  218.      */
  219.     private void makeBinaryImage() {
  220.         int[] org_pix = srcView.getPixels(); // Pixels of the original image
  221.         int[] new_pix = new int[srcView.getImgHeight() * srcView.getImgWidth()]; // new
  222.                                                                                     // int[]
  223.                                                                                     // for
  224.                                                                                     // dstView
  225.         int pos = 0; // current position inside the pixel-array
  226.         int argb; // colour-value of the current pixel
  227.         for (int y = 0; y < srcView.getImgHeight(); y++) {
  228.             for (int x = 0; x < srcView.getImgWidth(); x++) {
  229.                 pos = y * srcView.getImgWidth() + x; // calculate position in
  230.                                                         // pixel-array
  231.  
  232.                 argb = org_pix[pos]; // read original colour-values
  233.  
  234.                 int r = (argb >> 16) & 0xff; //
  235.                 int g = (argb >> 8) & 0xff; // get RGB values via bitshifting
  236.                 int b = argb & 0xff; //
  237.  
  238.                 double Y = 0.299 * r + 0.587 * g + 0.114 * b; // calculate
  239.                                                                 // luminance of
  240.                                                                 // the pixel
  241.                                                                 // (convert to
  242.                                                                 // grayscale)
  243.  
  244.                 int newY = 255; //
  245.                 if (Y <= limit) { // makin' it binary, bro
  246.                     newY = 0; //
  247.                 }
  248.                 new_pix[pos] = (0xFF << 24) | (newY << 16) | (newY << 8) | newY; // set
  249.                                                                                     // new
  250.                                                                                     // pixel
  251.                                                                                     // value
  252.                                                                                     // into
  253.                                                                                     // the
  254.                                                                                     // new
  255.                                                                                     // array
  256.             }
  257.         }
  258.         dstView.setPixels(new_pix); // add new array to dstView to display the
  259.                                     // new image
  260.         statusLine.setText("Threshold: " + Double.toString(limit) + " Radius: "
  261.                 + Double.toString(filterRadius)); // update status line with
  262.                                                     // current threshold and
  263.                                                     // current radius
  264.     }
  265.  
  266.     private void makeErosionDilation() {
  267.         makeBinaryImage(); // just in case ;)
  268.         float filterSize = Math.abs((int) (2 * filterRadius + 1));
  269.  
  270.         if (filterRadius < 0) {
  271.             // zwai ma filtan
  272.             erosion();
  273. //          erosion(filterSize);
  274.         } else {
  275.  
  276.             // zwai ma filtan
  277.             dilation();
  278. //          dilation(filterSize);
  279.         }
  280.  
  281.         statusLine
  282.                 .setText("Threshold: " + Double.toString(limit) + " Radius: "
  283.                         + Double.toString(filterRadius) + " Filter Size: "
  284.                         + filterSize);
  285.     }
  286.  
  287.     private void dilation() {
  288.         if(filterRadius>1){
  289.         int[] orgPix = dstView.getPixels();
  290.         int offset = (int) filterCoreDim/2;
  291.         int width = srcView.getImgWidth();
  292.         int height = srcView.getImgHeight();
  293.         int[] newPix = new int[height * width];
  294.         Arrays.fill(newPix, 0xffffffff);
  295.        
  296.         for (int y = 0; y < height; y++) {
  297.             for (int x = 0; x < width; x++) {
  298.                 int pos = y * width + x;
  299.                
  300.                 outer: if(isWhite(orgPix[pos])){
  301.                     for (int yCore = 0; yCore < filterCoreDim; yCore++) {
  302.                         for (int xCore = 0; xCore < filterCoreDim; xCore++) {
  303.                             int xLoc = x + (xCore - offset);
  304.                             int yLoc = y + (yCore - offset);
  305.                             if(xLoc < 0 || yLoc < 0 || xLoc > width || yLoc > height) {
  306.                                 continue;
  307.                             }
  308.                             int filteredPos = yLoc * width + xLoc;
  309.                             if(!(filteredPos >= orgPix.length)){
  310.                             if(filterCore[xCore][yCore] <= Math.abs(filterRadius) && isBlack(orgPix[filteredPos])){
  311.                                 newPix[pos] = setBlack();
  312.                                 break outer;
  313.                             }
  314.                             }
  315.                         }
  316.                     }
  317.                 } else { newPix[pos] = orgPix[pos]; }
  318.                
  319.             }
  320.         }
  321.         dstView.setPixels(newPix);
  322.         dstView.applyChanges();
  323.         }
  324.     }
  325.  
  326.     private void erosion() {
  327.         if(filterRadius<-1){
  328.             int[] orgPix = dstView.getPixels();
  329.             int offset = (int) filterCoreDim/2;
  330.             int width = srcView.getImgWidth();
  331.             int height = srcView.getImgHeight();
  332.             int[] newPix = dstView.getPixels();
  333.            
  334.             for (int y = 0; y < height; y++) {
  335.                 for (int x = 0; x < width; x++) {
  336.                     int pos = y * width + x;
  337.                    
  338.                     outer: if(isBlack(orgPix[pos])){
  339.                         for (int yCore = 0; yCore < filterCoreDim; yCore++) {
  340.                             for (int xCore = 0; xCore < filterCoreDim; xCore++) {
  341.                                 int xLoc = x + (xCore - offset);
  342.                                 int yLoc = y + (yCore - offset);
  343.                                 if(xLoc < 0 || yLoc < 0 || xLoc > width || yLoc > height) {
  344.                                     continue;
  345.                                 }
  346.                                 int filteredPos = yLoc * width + xLoc;
  347.                                 if(!(filteredPos >= orgPix.length)){
  348.                                 if(filterCore[xCore][yCore] <= -filterRadius && isWhite(orgPix[filteredPos])){
  349.                                     newPix[pos] = setWhite();
  350.                                     break outer;
  351.                                 }
  352.                                 }
  353.                             }
  354.                         }
  355.                     } else newPix[pos] = orgPix[pos];
  356.                    
  357.                 }
  358.             }
  359.             dstView.setPixels(newPix);
  360.             dstView.applyChanges();
  361.             }
  362.         }
  363.  
  364.     private int setBlack() {
  365.         return (0xFF << 24) | (0 << 16) | (0 << 8) | 0; // Black
  366.     }
  367.  
  368.     private int setWhite() {
  369.         return (0xFF << 24) | (255 << 16) | (255 << 8) | 255; // Black
  370.     }
  371.  
  372.     private boolean isBlack(int pixel) {
  373.         int r = (pixel >> 16) & 0xff; // We only need one pixel, cause if it is
  374.                                         // black all are black ;)
  375.         if (r == 0) {
  376.             return true;
  377.         }
  378.         return false;
  379.     }
  380.    
  381.     private boolean isWhite(int pixel) {
  382.         int r = (pixel >> 16) & 0xff; // We only need one pixel, cause if it is
  383.                                         // black all are black ;)
  384.         if (r == 255) {
  385.             return true;
  386.         }
  387.         return false;
  388.     }
  389.  
  390.     private double[][] makeFilterCore() {
  391.         double[][] core = new double[filterCoreDim][filterCoreDim];
  392.         for (int yCore = 0; yCore < filterCoreDim; yCore++) {
  393.             for (int xCore = 0; xCore < filterCoreDim; xCore++) {
  394.                 int xLoc = xCore - (int)(filterCoreDim/2);
  395.                 int yLoc = yCore - (int)(filterCoreDim/2);
  396.                 double distance = Math.sqrt(Math.pow(xLoc, 2)+ Math.pow(yLoc, 2));
  397.                 core[xCore][yCore] = distance;
  398.             }
  399.         }
  400.         return core;
  401.     }
  402.  
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement