com.simiacryptus.mindseye.util.ImageUtil Maven / Gradle / Ivy
/*
* Copyright (c) 2019 by Andrew Charneski.
*
* The author licenses this file to you under the
* Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance
* with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.simiacryptus.mindseye.util;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.simiacryptus.mindseye.lang.Tensor;
import com.simiacryptus.util.data.DoubleStatistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class ImageUtil {
private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);
public static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setDaemon(true).build());
public static Stream renderToImages(@Nonnull final Tensor tensor, final boolean normalize) {
final DoubleStatistics[] statistics = IntStream.range(0, tensor.getDimensions()[2]).mapToObj(band -> {
return new DoubleStatistics().accept(tensor.coordStream(false)
.filter(x -> x.getCoords()[2] == band)
.mapToDouble(c -> tensor.get(c)).toArray());
}).toArray(i -> new DoubleStatistics[i]);
@Nonnull final BiFunction transform = (value, stats) -> {
final double width = Math.sqrt(2) * stats.getStandardDeviation();
final double centered = value - stats.getAverage();
final double distance = Math.abs(value - stats.getAverage());
final double positiveMax = stats.getMax() - stats.getAverage();
final double negativeMax = stats.getAverage() - stats.getMin();
final double unitValue;
if (value < centered) {
if (distance > width) {
unitValue = 0.25 - 0.25 * ((distance - width) / (negativeMax - width));
} else {
unitValue = 0.5 - 0.25 * (distance / width);
}
} else {
if (distance > width) {
unitValue = 0.75 + 0.25 * ((distance - width) / (positiveMax - width));
} else {
unitValue = 0.5 + 0.25 * (distance / width);
}
}
return 0xFF * unitValue;
};
tensor.coordStream(true).collect(Collectors.groupingBy(x -> x.getCoords()[2], Collectors.toList()));
@Nullable final Tensor normal = tensor.mapCoords((c) -> transform.apply(tensor.get(c), statistics[c.getCoords()[2]]))
.map(v -> Math.min(0xFF, Math.max(0, v)));
return (normalize ? normal : tensor).toImages().stream();
}
@Nonnull
public static BufferedImage resize(@Nonnull final BufferedImage source, final int size) {
return resize(source, size, false);
}
@Nonnull
public static BufferedImage resize(@Nonnull final BufferedImage source, final int size, boolean preserveAspect) {
if (size <= 0) return source;
double zoom = (double) size / source.getWidth();
int steps = (int) Math.ceil(Math.abs(Math.log(zoom)) / Math.log(1.5));
BufferedImage img = source;
for (int i = 1; i <= steps; i++) {
double pos = ((double) i / steps);
double z = Math.pow(zoom, pos);
int targetWidth = (int) (source.getWidth() * z);
int targetHeight = (int) ((source.getWidth() == source.getHeight()) ? targetWidth : ((preserveAspect ? source.getHeight() : source.getWidth()) * z));
img = resize(img, targetWidth, targetHeight);
}
return img;
}
public static BufferedImage resizePx(@Nonnull final BufferedImage source, final long size) {
if (size < 0) return source;
double scale = Math.sqrt(size / ((double) source.getHeight() * source.getWidth()));
int width = (int) (scale * source.getWidth());
int height = (int) (scale * source.getHeight());
return resize(source, width, height);
}
@Nonnull
public static BufferedImage resize(BufferedImage source, int width, int height) {
@Nonnull final BufferedImage image = new BufferedImage(width, height, source.getType());
@Nonnull final Graphics2D graphics = (Graphics2D) image.getGraphics();
HashMap © 2015 - 2025 Weber Informatics LLC | Privacy Policy