Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package net.ahinrichs.htw.bv.ue04;
- import javax.swing.*;
- import javax.swing.event.ChangeEvent;
- import javax.swing.event.ChangeListener;
- import javax.swing.filechooser.FileNameExtensionFilter;
- import java.awt.event.*;
- import java.awt.*;
- import java.io.File;
- import java.util.Arrays;
- import java.util.Map;
- import java.util.TreeMap;
- public class BinaryMorphoFilter extends JPanel {
- private static final long serialVersionUID = 1L;
- private static final String author = "Alexander Hinrichs; Markus Bausdorf"; // type
- // in
- // your
- // name
- // here
- private static final String initialFilename = "rhino_part.png";
- private static final int border = 10;
- private static final int maxWidth = 900;
- private static final int maxHeight = 900;
- private static final double limitStepSize = 5.0; // size used for angle
- // increment and
- // decrement
- private static JFrame frame;
- private ImageView srcView = null; // source image view
- private ImageView dstView = null; // rotated image view
- private JComboBox methodList; // the selected rotation method
- private JSlider limitSlider; // the selected rotation angle
- private JLabel statusLine; // to print some status text
- private double limit = 128.0; // current rotation angle in degrees
- private JSlider radiusSlider; // the selected rotation angle
- private double filterRadius = 0.0; // current rotation angle in degrees
- private int filterCoreDim = 11;
- private double[][] filterCore;
- /**
- * Constructor. Constructs the layout of the GUI components and loads the
- * initial image.
- */
- public BinaryMorphoFilter() {
- super(new BorderLayout(border, border));
- // load the default image
- File input = new File(initialFilename);
- if (!input.canRead())
- input = openFile(); // file not found, choose another image
- // configure both viewscreens
- srcView = new ImageView(input);
- srcView.setMaxSize(new Dimension(maxWidth, maxHeight));
- dstView = new ImageView(input);
- dstView.setMaxSize(new Dimension(maxWidth, maxHeight));
- // load image button
- JButton load = new JButton("Open Image");
- load.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- File input = openFile();
- if (input != null) {
- srcView.loadImage(input);
- srcView.setMaxSize(new Dimension(maxWidth, maxHeight));
- dstView.loadImage(input);
- dstView.setMaxSize(new Dimension(maxWidth, maxHeight));
- }
- }
- });
- // method names for the filter selection
- String[] methodNames = { "Original", "Binary picture",
- "Erosion/Dilation" };
- // filter selector combobox
- methodList = new JComboBox(methodNames);
- methodList.setSelectedIndex(0); // set initial method
- methodList.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- filterSelector(methodList.getSelectedIndex());
- }
- });
- // Slider to adjust the threshold for binary filtering
- limitSlider = new JSlider(0, 255, (int) limit);
- limitSlider.addChangeListener(new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- limit = limitSlider.getValue();
- filterSelector(methodList.getSelectedIndex());
- }
- });
- // Slider to adjust the radius for erosion/dilation
- radiusSlider = new JSlider(-50, +50, (int) filterRadius);
- radiusSlider.addChangeListener(new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- filterRadius = radiusSlider.getValue() / 10d;
- filterSelector(methodList.getSelectedIndex());
- }
- });
- // some status text
- statusLine = new JLabel(" ");
- // arrange all controls
- JPanel controls = new JPanel(new GridBagLayout());
- GridBagConstraints c = new GridBagConstraints();
- c.insets = new Insets(0, border, 0, 0);
- controls.add(load, c);
- controls.add(methodList, c);
- controls.add(new JLabel("Treshold:"), c);
- controls.add(limitSlider, c);
- controls.add(new JLabel("r:"), c);
- controls.add(radiusSlider, c);
- // arrange images
- JPanel images = new JPanel();
- images.add(srcView);
- images.add(dstView);
- // add to main panel
- add(controls, BorderLayout.NORTH);
- add(images, BorderLayout.CENTER);
- add(statusLine, BorderLayout.SOUTH);
- // add border to main panel
- setBorder(BorderFactory.createEmptyBorder(border, border, border,
- border));
- // precalculate filter core
- filterCore = makeFilterCore();
- }
- /**
- * Set up and show the main frame.
- */
- private static void createAndShowGUI() {
- // create and setup the window
- frame = new JFrame("BinaryMorphoFilter - " + author);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- JComponent contentPane = new BinaryMorphoFilter();
- contentPane.setOpaque(true); // content panes must be opaque
- frame.setContentPane(contentPane);
- // display the window
- frame.pack();
- Toolkit toolkit = Toolkit.getDefaultToolkit();
- Dimension screenSize = toolkit.getScreenSize();
- frame.setLocation((screenSize.width - frame.getWidth()) / 2,
- (screenSize.height - frame.getHeight()) / 2);
- frame.setVisible(true);
- }
- /**
- * Main method.
- *
- * @param args
- * - ignored. No arguments are used by this application.
- */
- public static void main(String[] args) {
- // schedule a job for the event-dispatching thread:
- // creating and showing this application's GUI.
- javax.swing.SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- createAndShowGUI();
- }
- });
- }
- /**
- * Open file dialog used to select a new image.
- *
- * @return The selected file object or null on cancel.
- */
- private File openFile() {
- // file open dialog
- JFileChooser chooser = new JFileChooser();
- FileNameExtensionFilter filter = new FileNameExtensionFilter(
- "Images (*.jpg, *.png, *.gif)", "jpg", "png", "gif");
- chooser.setFileFilter(filter);
- int ret = chooser.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION)
- return chooser.getSelectedFile();
- return null;
- }
- /**
- * Method to execute the selected filtering on the given image
- *
- * @param method
- * ComboBox selected method index
- */
- private void filterSelector(int method) {
- switch (method) {
- case 0:
- dstView.setPixels(srcView.getPixels());
- break;
- case 1:
- makeBinaryImage();
- break;
- case 2:
- makeErosionDilation();
- break;
- default:
- break;
- }
- }
- /**
- * Convert image to binary, using a variable threshold
- */
- private void makeBinaryImage() {
- int[] org_pix = srcView.getPixels(); // Pixels of the original image
- int[] new_pix = new int[srcView.getImgHeight() * srcView.getImgWidth()]; // new
- // int[]
- // for
- // dstView
- int pos = 0; // current position inside the pixel-array
- int argb; // colour-value of the current pixel
- for (int y = 0; y < srcView.getImgHeight(); y++) {
- for (int x = 0; x < srcView.getImgWidth(); x++) {
- pos = y * srcView.getImgWidth() + x; // calculate position in
- // pixel-array
- argb = org_pix[pos]; // read original colour-values
- int r = (argb >> 16) & 0xff; //
- int g = (argb >> 8) & 0xff; // get RGB values via bitshifting
- int b = argb & 0xff; //
- double Y = 0.299 * r + 0.587 * g + 0.114 * b; // calculate
- // luminance of
- // the pixel
- // (convert to
- // grayscale)
- int newY = 255; //
- if (Y <= limit) { // makin' it binary, bro
- newY = 0; //
- }
- new_pix[pos] = (0xFF << 24) | (newY << 16) | (newY << 8) | newY; // set
- // new
- // pixel
- // value
- // into
- // the
- // new
- // array
- }
- }
- dstView.setPixels(new_pix); // add new array to dstView to display the
- // new image
- statusLine.setText("Threshold: " + Double.toString(limit) + " Radius: "
- + Double.toString(filterRadius)); // update status line with
- // current threshold and
- // current radius
- }
- private void makeErosionDilation() {
- makeBinaryImage(); // just in case ;)
- float filterSize = Math.abs((int) (2 * filterRadius + 1));
- if (filterRadius < 0) {
- // zwai ma filtan
- erosion();
- // erosion(filterSize);
- } else {
- // zwai ma filtan
- dilation();
- // dilation(filterSize);
- }
- statusLine
- .setText("Threshold: " + Double.toString(limit) + " Radius: "
- + Double.toString(filterRadius) + " Filter Size: "
- + filterSize);
- }
- private void dilation() {
- if(filterRadius>1){
- int[] orgPix = dstView.getPixels();
- int offset = (int) filterCoreDim/2;
- int width = srcView.getImgWidth();
- int height = srcView.getImgHeight();
- int[] newPix = new int[height * width];
- Arrays.fill(newPix, 0xffffffff);
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- int pos = y * width + x;
- outer: if(isWhite(orgPix[pos])){
- for (int yCore = 0; yCore < filterCoreDim; yCore++) {
- for (int xCore = 0; xCore < filterCoreDim; xCore++) {
- int xLoc = x + (xCore - offset);
- int yLoc = y + (yCore - offset);
- if(xLoc < 0 || yLoc < 0 || xLoc > width || yLoc > height) {
- continue;
- }
- int filteredPos = yLoc * width + xLoc;
- if(!(filteredPos >= orgPix.length)){
- if(filterCore[xCore][yCore] <= Math.abs(filterRadius) && isBlack(orgPix[filteredPos])){
- newPix[pos] = setBlack();
- break outer;
- }
- }
- }
- }
- } else { newPix[pos] = orgPix[pos]; }
- }
- }
- dstView.setPixels(newPix);
- dstView.applyChanges();
- }
- }
- private void erosion() {
- if(filterRadius<-1){
- int[] orgPix = dstView.getPixels();
- int offset = (int) filterCoreDim/2;
- int width = srcView.getImgWidth();
- int height = srcView.getImgHeight();
- int[] newPix = dstView.getPixels();
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- int pos = y * width + x;
- outer: if(isBlack(orgPix[pos])){
- for (int yCore = 0; yCore < filterCoreDim; yCore++) {
- for (int xCore = 0; xCore < filterCoreDim; xCore++) {
- int xLoc = x + (xCore - offset);
- int yLoc = y + (yCore - offset);
- if(xLoc < 0 || yLoc < 0 || xLoc > width || yLoc > height) {
- continue;
- }
- int filteredPos = yLoc * width + xLoc;
- if(!(filteredPos >= orgPix.length)){
- if(filterCore[xCore][yCore] <= -filterRadius && isWhite(orgPix[filteredPos])){
- newPix[pos] = setWhite();
- break outer;
- }
- }
- }
- }
- } else newPix[pos] = orgPix[pos];
- }
- }
- dstView.setPixels(newPix);
- dstView.applyChanges();
- }
- }
- private int setBlack() {
- return (0xFF << 24) | (0 << 16) | (0 << 8) | 0; // Black
- }
- private int setWhite() {
- return (0xFF << 24) | (255 << 16) | (255 << 8) | 255; // Black
- }
- private boolean isBlack(int pixel) {
- int r = (pixel >> 16) & 0xff; // We only need one pixel, cause if it is
- // black all are black ;)
- if (r == 0) {
- return true;
- }
- return false;
- }
- private boolean isWhite(int pixel) {
- int r = (pixel >> 16) & 0xff; // We only need one pixel, cause if it is
- // black all are black ;)
- if (r == 255) {
- return true;
- }
- return false;
- }
- private double[][] makeFilterCore() {
- double[][] core = new double[filterCoreDim][filterCoreDim];
- for (int yCore = 0; yCore < filterCoreDim; yCore++) {
- for (int xCore = 0; xCore < filterCoreDim; xCore++) {
- int xLoc = xCore - (int)(filterCoreDim/2);
- int yLoc = yCore - (int)(filterCoreDim/2);
- double distance = Math.sqrt(Math.pow(xLoc, 2)+ Math.pow(yLoc, 2));
- core[xCore][yCore] = distance;
- }
- }
- return core;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement