Стайлинг цифровых изображений с convolveop

Иногда изображений, полученных с Вашей цифровой камерой, не может быть точно, что вы хотите. Например, вы можете стирать их или конкретизировать их. Или вы можете скрасить им или тон их вниз. Java.awt.Image пакет содержит утилиты для принятия такого рода изменения в цифровых изображений. Использование этих утилит, можно добиться одних и тех же последствий, что вы найдете в High-End коммерческих пакетов изображений.

В этот совет, вы будете использовать ConvolveOp, класс в java.awt.Image пакет, чтобы изменить цифровое изображение. ConvolveOp реализующий свертки от источника к приемнику. Вы можете думать о свертке операция, которая заменяет каждый пиксель изображения в сочетании с некоторыми из оригинального пикселя и его соседей. Вы задаете комбинацию с помощью массива из поплавков. Поплавки кратных точек. Из этого массива вы создаете экземпляр ядра, и использовать его например для выполнения свертки.

Например, если массив состоит из трех по три массива следующим образом:

a b c
d e f
g h i

Тогда в результате свертки заменяющий в центре пикселя с суммой:

  • a times the value of the pixel above and to the left of center
  • b times the value of the pixel above the center
  • c times the pixel above and to the right of the center
  • and so on

Другими словами, вы умножения значения пиксела значение в ядре при соответствующем положении, и добавить их. Если сумма записей в массив 1, то полученное изображение будет иметь тот же динамический диапазон, что и исходное изображение.

Вот более конкретные. Рассмотрим следующие три по три массива:

0   0.2   0
0.2  0.2  0.2
0   0.2   0

Этот массив соответствует замене каждого пикселя при средней его стоимости вместе с пикселей вправо, влево, выше, и ниже. Эффект заключается в размытости картинки немного.

Теперь рассмотрим следующие три по три массива. Он соответствует личности операции. Применение его в качестве части ничего свертки изменения. Иными словами, он заменяет каждый пиксель со своим предыдущим значением.

0 0 0
0 1 0
0 0 0

Однако, если 1 в предыдущем массиве заменить 2, в результате изображение ярче и немного размытой. Замена с 1 .5 результатов в темных изображений.

Существует ничего магического три по три массива. Если вашей целью является выполнение свертки, которые симметричны относительно центра и которая зависит от центрального пиксела, необходимо квадратный массив с нечетной размерности. Пять на пять, семь по семь, и любой другой нечетной размерности массива будет работать так же, как три по три массива. Предыдущий пример может даже быть реализованы с помощью одного-By-один массив. Например, в следующий метод, вы создаете массив поплавков, содержащих один элемент. Затем вы можете создать новую поочередно по одной ядра объекта из этого элемента, и сдать объект в конструкторе ConvolveOp. Наконец, вы BufferedImageOp применить к исходному BufferedImage получить измененное изображение.


   private void setBrightnessFactor(float multiple) {

     float[] brightKernel = {multiple};

     BufferedImageOp bright

       new ConvolveOp(new Kernel(11, brightKernel));

     convolvedImage 

       = bright.filter(originalImage, null);

     repaint();



   }

Этот метод привел два требования. Одним из требований является то, что вам необходимо изменить paintComponent () для перерисовки новое изображение каждый раз он меняется.


   public void paintComponent(Graphics g) {

     g.drawImage(convolvedImage, 00this);

   }

Вторым требованием является то, что нужно сначала создать BufferedImage, к которым можно применить эти эффекты. В этом случае, читайте в test.jpg и создать изображение из него. Затем создайте BufferedImage с тем же размеры, как и исходное изображение. В качестве последнего шага, необходимо обратить изображение на BufferedImage.


   Image image = new ImageIcon("test.jpg").getImage();

   originalImage 

     new BufferedImage(image.getWidth(null),

       image.getHeight(null)

       BufferedImage.TYPE_INT_RGB);

   Graphics g = originalImage.createGraphics();

   g.drawImage(image, 00null);

   g.dispose();

Вместо одномерного ядра, вы также можете использовать три по три ядра на основе следующих версий setBrightnessFactor.


   private void setBrightnessFactor(float multiple) {

      float[] brightKernel = {0,    0,     0,

                              0, multiple, 0,

                              0,    0,     0};

      BufferedImageOp bright

        new ConvolveOp(new Kernel(33, brightKernel));

      convolvedImage 

        = bright.filter(originalImage, null);

      repaint();

   }

Вот пример программы, BrightnessChanger, что создает для просмотра изображений. Зритель включает ползунок, который можно использовать для управления яркостью, изменяя значения нескольких используются. Вам понадобится тестового изображения. В этом случае имя изображения установлен test.jpg. Изображение должно быть в каталоге, в котором Вы запускаете программу BrightnessChanger. Вы можете найти изображения весело образцом для использования.


    import javax.swing.JFrame;

    import javax.swing.JPanel;

    import javax.swing.ImageIcon;

    import javax.swing.JSlider;

    import javax.swing.event.ChangeListener;

    import javax.swing.event.ChangeEvent;

    import java.awt.Graphics;

    import java.awt.Image;

    import java.awt.BorderLayout;

    import java.awt.image.Kernel;

    import java.awt.image.ConvolveOp;

    import java.awt.image.BufferedImageOp;

    import java.awt.image.BufferedImage;



    public class BrightnessChanger extends JPanel {



       private BufferedImage originalImage;

       private BufferedImage convolvedImage;

       private JSlider slide = new JSlider(1,50,10);



       BrightnessChanger() {

         createBufferedImages();

         setUpJFrame();

       }



       private void createBufferedImages() {

         Image image

           new ImageIcon("test.jpg").getImage();

         originalImage

           new BufferedImage(image.getWidth(null),

             image.getHeight(null),

             BufferedImage.TYPE_INT_RGB);

         convolvedImage

           new BufferedImage(image.getWidth(null),

             image.getHeight(null),

             BufferedImage.TYPE_INT_RGB);

         Graphics g = originalImage.createGraphics();

         g.drawImage(image, 00null);

         g.dispose();

         setBrightnessFactor(1);

       }



       private void setUpJFrame() {

         JFrame myFrame = new JFrame("Image Brightness");

         myFrame.setSize(convolvedImage.getWidth(),

                         convolvedImage.getHeight());

         myFrame.getContentPane().setLayout(

           new BorderLayout());

         myFrame.getContentPane().add(

           this, BorderLayout.CENTER);

         slide.addChangeListener(

           new BrightnessListener());

         myFrame.getContentPane().add(

           slide,BorderLayout.SOUTH);

         myFrame.setDefaultCloseOperation(

           JFrame.EXIT_ON_CLOSE);

         myFrame.setVisible(true);

       }



       private void setBrightnessFactor(float multiple) {

         float[] brightKernel = {multiple};

         BufferedImageOp bright

           new ConvolveOp(

               new Kernel(11, brightKernel));

         bright.filter(originalImage, convolvedImage);

         repaint();



       }



        public void paintComponent(Graphics g) {

         g.drawImage(convolvedImage, 00this);

       }



       class BrightnessListener implements ChangeListener{

         public void stateChanged(

           ChangeEvent changeEvent) {

             setBrightnessFactor(

               (float)(slide.getValue())/10);

         }

       }



       public static void main(String[] args) {

           new BrightnessChanger();

         }



    }

java.awt.image

BrightnessChanger примером служит введением в свертках, а не как рекомендуемый способ управления яркостью изображения. В будущем Tech отзыв, вы увидите, как использовать некоторые элементы управления ориентирована на цвета и яркости.

В дополнение к использованию площади, нечетной массивы для ядра свертки, вам нужно использовать (по большей части) симметрична массивов. Следующий пример использует три-By-трех массивов, которые построены из трех компонентов:

0  0  0         0  1  0              1  0  1
IDENTITY  0  1  0   EDGE  1  0  1      CORNER  0  0  0
0  0  0         0  1  0              1  0  1

В результате массив построен из линейных комбинаций этих строительных блоков. Пока сумма записей не равна нулю, то нормализовать ядра путем деления этой суммы. Таким образом, вы получаете изображение, которое имеет такой же интенсивностью, как исходное изображение. Например, если вы добавите EDGE и личности вы получите следующее:

0  1  0
1  1  1
0  1  0

Сумма записей 5. Затем нормализации путем деления каждой записи от 5 до получим следующие "массив Blur":

0  0.2  0
.2  0.2 0.2
0  0.2  0

Вот код для создания этих ядер от параметров для кратных трех массивах базы.


   private Kernel getKernel(

     int corner, int edge, int identity) {

      float[] kernel = new float[9];

      int sum = corner * + edge * + identity;

      if (sum == 0sum = 1;

      for (int i = 0; i < 9; i++) {

        kernel[i(corner * CORNER[i]

          + edge * EDGE[i]

          + identity * IDENTITY[i]) / sum;

    }

    return new Kernel(33, kernel);

 }



After you have the kernel, you perform the convolution much as before.



   void convolveImage(Kernel kernel) {

      BufferedImageOp convolve

        new ConvolveOp(kernel);

      buffImage = convolve.filter(buffImage, null);

      repaint();

   }

Теперь давайте запустим программу тестирования, названный Размывание. При запуске Размывание, вам нужно ввести трех параметров командной строки. Они являются Int значений, соответствующих кратны углу, EDGE, и самобытность. Например, если ввести:

java Convolve 1 0 0

Вы должны увидеть несколько размытым изображением. Опять же, нужно изображение с именем test.jpg.


   import javax.swing.ImageIcon;

   import javax.swing.JFrame;

   import javax.swing.JPanel;

   import java.awt.image.BufferedImage;

   import java.awt.image.BufferedImageOp;

   import java.awt.image.ConvolveOp;

   import java.awt.image.Kernel;

   import java.awt.Image;

   import java.awt.Graphics;



   public class Convolve extends JPanel {

      private BufferedImage buffImage;



      private final float[] IDENTITY = {000,

                                        010,

                                        000};



      private final float[] EDGE = {010,

                                    101,

                                    010};



      private final float[] CORNER = {101,

                                      000,

                                      101};





      Convolve(int corner, int edge, int identity) {

        createBufferedImages();

        setUpJFrame();

        convolveImage(getKernel(corner, edge, identity));

      }



      private void createBufferedImages() {

        Image image 

          new ImageIcon("test.jpg").getImage();

        buffImage 

          new BufferedImage(image.getWidth(null),

            image.getHeight(null)

            BufferedImage.TYPE_INT_RGB);

        Graphics g = buffImage.createGraphics();

        g.drawImage(image, 00null);

        g.dispose();

      }



      private void setUpJFrame() {

        JFrame myFrame = new JFrame("Image Brightness");

        myFrame.setSize(buffImage.getWidth(),

          buffImage.getHeight());

        myFrame.getContentPane().add(this);

        myFrame.setDefaultCloseOperation(

          JFrame.EXIT_ON_CLOSE);

        myFrame.setVisible(true);

      }



      void convolveImage(Kernel kernel) {

        BufferedImageOp convolve

          new ConvolveOp(kernel);

        buffImage = convolve.filter(buffImage, null);

        repaint();



      }



      private Kernel getKernel(

        int corner, int edge, int identity) {

         float[] kernel = new float[9];

         int sum = corner * + edge * + identity;

         if (sum == 0sum = 1;

         for (int i = 0; i < 9; i++) {

           kernel[i(corner * CORNER[i]

             + edge * EDGE[i]

             + identity * IDENTITY[i]) / sum;

         }

        return new Kernel(33, kernel);

      }



      public void paintComponent(Graphics g) {

        g.drawImage(buffImage, 00this);

      }





      public static void main(String[] args) {

        if (args.length != 3) {

          System.out.println("Usage: java Convolve" +

                             " corner edge identity");

          System.out.println("where corner, edge, " +

                             "and identity are ints");

          System.exit(0);

        }

        int corner = Integer.parseInt(args[0]);

        int edge = Integer.parseInt(args[1]);

        int identity = Integer.parseInt(args[2]);

        new Convolve(corner, edge, identity);



      }



   }

java.awt.image

Попробуйте другой комбинации из трех параметров командной строки. Например, введите -1 -1 8 см. Основные контуры объектов. Это не может быть нормализована как сумма равна нулю. Или введите 0 -1 5 для острее ввиду исходное изображение. Вы можете легко расширить этот пример, чтобы пять на пять массивов и выше, с другой симметричной примитивов.

Для получения дополнительной информации об использовании ConvoleOp, см. главу 5: "Imaging" в Руководстве программиста Java 2D API.

Copyright (C) 2004-2005 Sun Microsystems, Inc
Все права защищены.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>