A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
141
Task/Image-convolution/Java/image-convolution.java
Normal file
141
Task/Image-convolution/Java/image-convolution.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
import java.awt.image.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.*;
|
||||
|
||||
public class ImageConvolution
|
||||
{
|
||||
public static class ArrayData
|
||||
{
|
||||
public final int[] dataArray;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
public ArrayData(int width, int height)
|
||||
{
|
||||
this(new int[width * height], width, height);
|
||||
}
|
||||
|
||||
public ArrayData(int[] dataArray, int width, int height)
|
||||
{
|
||||
this.dataArray = dataArray;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int get(int x, int y)
|
||||
{ return dataArray[y * width + x]; }
|
||||
|
||||
public void set(int x, int y, int value)
|
||||
{ dataArray[y * width + x] = value; }
|
||||
}
|
||||
|
||||
private static int bound(int value, int endIndex)
|
||||
{
|
||||
if (value < 0)
|
||||
return 0;
|
||||
if (value < endIndex)
|
||||
return value;
|
||||
return endIndex - 1;
|
||||
}
|
||||
|
||||
public static ArrayData convolute(ArrayData inputData, ArrayData kernel, int kernelDivisor)
|
||||
{
|
||||
int inputWidth = inputData.width;
|
||||
int inputHeight = inputData.height;
|
||||
int kernelWidth = kernel.width;
|
||||
int kernelHeight = kernel.height;
|
||||
if ((kernelWidth <= 0) || ((kernelWidth & 1) != 1))
|
||||
throw new IllegalArgumentException("Kernel must have odd width");
|
||||
if ((kernelHeight <= 0) || ((kernelHeight & 1) != 1))
|
||||
throw new IllegalArgumentException("Kernel must have odd height");
|
||||
int kernelWidthRadius = kernelWidth >>> 1;
|
||||
int kernelHeightRadius = kernelHeight >>> 1;
|
||||
|
||||
ArrayData outputData = new ArrayData(inputWidth, inputHeight);
|
||||
for (int i = inputWidth - 1; i >= 0; i--)
|
||||
{
|
||||
for (int j = inputHeight - 1; j >= 0; j--)
|
||||
{
|
||||
double newValue = 0.0;
|
||||
for (int kw = kernelWidth - 1; kw >= 0; kw--)
|
||||
for (int kh = kernelHeight - 1; kh >= 0; kh--)
|
||||
newValue += kernel.get(kw, kh) * inputData.get(
|
||||
bound(i + kw - kernelWidthRadius, inputWidth),
|
||||
bound(j + kh - kernelHeightRadius, inputHeight));
|
||||
outputData.set(i, j, (int)Math.round(newValue / kernelDivisor));
|
||||
}
|
||||
}
|
||||
return outputData;
|
||||
}
|
||||
|
||||
public static ArrayData[] getArrayDatasFromImage(String filename) throws IOException
|
||||
{
|
||||
BufferedImage inputImage = ImageIO.read(new File(filename));
|
||||
int width = inputImage.getWidth();
|
||||
int height = inputImage.getHeight();
|
||||
int[] rgbData = inputImage.getRGB(0, 0, width, height, null, 0, width);
|
||||
ArrayData reds = new ArrayData(width, height);
|
||||
ArrayData greens = new ArrayData(width, height);
|
||||
ArrayData blues = new ArrayData(width, height);
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
int rgbValue = rgbData[y * width + x];
|
||||
reds.set(x, y, (rgbValue >>> 16) & 0xFF);
|
||||
greens.set(x, y, (rgbValue >>> 8) & 0xFF);
|
||||
blues.set(x, y, rgbValue & 0xFF);
|
||||
}
|
||||
}
|
||||
return new ArrayData[] { reds, greens, blues };
|
||||
}
|
||||
|
||||
public static void writeOutputImage(String filename, ArrayData[] redGreenBlue) throws IOException
|
||||
{
|
||||
ArrayData reds = redGreenBlue[0];
|
||||
ArrayData greens = redGreenBlue[1];
|
||||
ArrayData blues = redGreenBlue[2];
|
||||
BufferedImage outputImage = new BufferedImage(reds.width, reds.height,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
for (int y = 0; y < reds.height; y++)
|
||||
{
|
||||
for (int x = 0; x < reds.width; x++)
|
||||
{
|
||||
int red = bound(reds.get(x, y), 256);
|
||||
int green = bound(greens.get(x, y), 256);
|
||||
int blue = bound(blues.get(x, y), 256);
|
||||
outputImage.setRGB(x, y, (red << 16) | (green << 8) | blue | -0x01000000);
|
||||
}
|
||||
}
|
||||
ImageIO.write(outputImage, "PNG", new File(filename));
|
||||
return;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException
|
||||
{
|
||||
int kernelWidth = Integer.parseInt(args[2]);
|
||||
int kernelHeight = Integer.parseInt(args[3]);
|
||||
int kernelDivisor = Integer.parseInt(args[4]);
|
||||
System.out.println("Kernel size: " + kernelWidth + "x" + kernelHeight +
|
||||
", divisor=" + kernelDivisor);
|
||||
int y = 5;
|
||||
ArrayData kernel = new ArrayData(kernelWidth, kernelHeight);
|
||||
for (int i = 0; i < kernelHeight; i++)
|
||||
{
|
||||
System.out.print("[");
|
||||
for (int j = 0; j < kernelWidth; j++)
|
||||
{
|
||||
kernel.set(j, i, Integer.parseInt(args[y++]));
|
||||
System.out.print(" " + kernel.get(j, i) + " ");
|
||||
}
|
||||
System.out.println("]");
|
||||
}
|
||||
|
||||
ArrayData[] dataArrays = getArrayDatasFromImage(args[0]);
|
||||
for (int i = 0; i < dataArrays.length; i++)
|
||||
dataArrays[i] = convolute(dataArrays[i], kernel, kernelDivisor);
|
||||
writeOutputImage(args[1], dataArrays);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue