Применить медиану к изображению с несколькими нитями - PullRequest
0 голосов
/ 25 мая 2018

Для школьного задания мы должны применить медианный фильтр к шумному PNG-изображению.У меня есть следующее:

public static void main(String[] a) throws Throwable {
    final String extension = "png";
    final String input = "input1.png";
    final String output = "output1.png";

    final int threadsAmount = 4;

    long startTime = System.currentTimeMillis();
    final Image image = new Image(input, output, extension);

    image.applyMedian(threadsAmount);
    long duration = System.currentTimeMillis() - startTime;
    System.out.println("duration: " + duration);
}

Метод применения медианного фильтра к изображению, создание буферизованного изображения, считывание его, вычисление средних значений и помещение их в новый bufferedImage, который экспортируется в новыйimage.

public void applyMedian(int threadAmount) throws IOException, Exception {
    File imageFile = new File(this.input);
    BufferedImage bufferedImage = ImageIO.read(imageFile);

    int imageHeight = bufferedImage.getHeight();
    int imageWidth = bufferedImage.getWidth();

    BufferedImage finalImage = new BufferedImage(imageWidth, imageHeight, bufferedImage.getType());
    int heightPerThread = imageHeight / threadAmount;
    Color[] surroundedPixel = new Color[9];
    int[] R = new int[9];
    int[] B = new int[9];
    int[] G = new int[9];

    for (int j = 1; j < bufferedImage.getHeight() - 1; j++) {
        for (int i = 1; i < bufferedImage.getWidth() - 1; i++) {
            surroundedPixel[0] = new Color(bufferedImage.getRGB(i - 1, j - 1));
            surroundedPixel[1] = new Color(bufferedImage.getRGB(i - 1, j));
            surroundedPixel[2] = new Color(bufferedImage.getRGB(i - 1, j + 1));
            surroundedPixel[3] = new Color(bufferedImage.getRGB(i, j + 1));
            surroundedPixel[4] = new Color(bufferedImage.getRGB(i + 1, j + 1));
            surroundedPixel[5] = new Color(bufferedImage.getRGB(i + 1, j));
            surroundedPixel[6] = new Color(bufferedImage.getRGB(i + 1, j - 1));
            surroundedPixel[7] = new Color(bufferedImage.getRGB(i, j - 1));
            surroundedPixel[8] = new Color(bufferedImage.getRGB(i, j));
            for (int k = 0; k < 9; k++) {
                R[k] = surroundedPixel[k].getRed();
                B[k] = surroundedPixel[k].getBlue();
                G[k] = surroundedPixel[k].getGreen();
            }
            Arrays.sort(R);
            Arrays.sort(G);
            Arrays.sort(B);
            finalImage.setRGB(i, j, new Color(R[4], B[4], G[4]).getRGB());
        }
    }
    ImageIO.write(finalImage, this.getExtension(), new File(this.output));
}

В нашем main у нас есть целое число, которое определяет количество потоков, которые у нас есть.Наша идея и назначение заключается в том, что мы разделяем высоту всего изображения на части и позволяем нескольким потокам вычислять нашу медиану.

int heightPerThread = imageHeight / threadAmount;

Однако мы узнали, как создавать потоки, но мы просто не знаем, как применить все эти потоки к описанному выше методу, и позволить всем потокам обрабатывать свою собственную часть изображения.

Надеюсь, кто-нибудь может помочь.

1 Ответ

0 голосов
/ 25 мая 2018

Я думаю, что для этого потребуется добавить дополнительную функцию, которую можно вызывать с applyMedian.Дополнительная функция может принимать позицию пикселя в верхнем левом углу (i, j), а также высоту и ширину, которые должна обрабатывать нить.Вы можете сделать так, чтобы это выглядело примерно так:

public static void main(String[] a) throws Throwable {
    final String extension = "png";
    final String input = "input1.png";
    final String output = "output1.png";

    final int threadsAmount = 4;

    long startTime = System.currentTimeMillis();
    final Image image = new Image(input, output, extension);

    image.applyMedian(threadsAmount);
    long duration = System.currentTimeMillis() - startTime;
    System.out.println("duration: " + duration);
}

И ваш applyMedian должен быть изменен следующим образом:

public void applyMedian(int threadAmount) throws IOException, Exception {
    File imageFile = new File(this.input);
    BufferedImage bufferedImage = ImageIO.read(imageFile);

    int imageHeight = bufferedImage.getHeight();
    int imageWidth = bufferedImage.getWidth();

    int heightPerThread = imageHeight / threadAmount;
    int widthPerThread = imageWidth / threadAmount

    BufferedImage finalImage = new BufferedImage(imageWidth, imageHeight, bufferedImage.getType());

    // create threads here
    // make all threads invoke the new function here
}

И ваша новая функция должна принимать объект finalImage, верхний левый уголпозиции, heightPerThread и widthPerThread в качестве аргументов и выполните обработку, которую вы сейчас выполняете, в самом applyMedian.

public newFunction(Image finalImage, int i, int j, int heightPerThread, int widthPerThread) {
    // do all processing here
    // call finalImage.setRGB
}

Надеюсь, это поможет!

...