DN05
This commit is contained in:
parent
22043e58f5
commit
a460c4de28
2
konvolucija1.p2
Normal file
2
konvolucija1.p2
Normal file
|
@ -0,0 +1,2 @@
|
|||
P2: 4 x 4
|
||||
0 64 128 255 255 128 64 0 0 0 1 1 255 255 37 5
|
2
slika.p2
Normal file
2
slika.p2
Normal file
|
@ -0,0 +1,2 @@
|
|||
P2: 15 x 10
|
||||
0 0 128 128 128 164 164 164 164 164 128 128 128 0 0 0 255 255 255 0 0 255 255 255 255 255 255 255 255 0 128 255 255 0 255 255 0 255 255 255 16 255 16 255 128 128 255 0 255 255 255 255 0 255 255 255 16 255 255 128 164 255 0 255 255 255 255 0 255 255 16 255 16 255 164 164 255 255 0 255 255 0 255 255 244 255 255 244 255 164 128 255 255 255 0 0 255 255 255 255 244 244 255 255 128 128 255 144 255 255 255 255 144 255 255 244 244 255 255 128 0 255 255 255 255 255 255 255 255 244 255 255 244 255 0 0 0 128 128 128 164 164 164 164 164 128 128 128 0 0
|
2
slikaB.p2
Normal file
2
slikaB.p2
Normal file
|
@ -0,0 +1,2 @@
|
|||
P2B: 4 x 3
|
||||
1072693248 1072693248 1073741823 672794241 1073741823 1047552 1047552 1073741823 0 1073741823 1023 1023
|
523
src/DN05.java
Normal file
523
src/DN05.java
Normal file
|
@ -0,0 +1,523 @@
|
|||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class DN05 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args[0].equals("barvna") || args[0].equals("sivinska")) {
|
||||
int[][][] barvnaSlika = preberiBarvnoSliko(args[1]);
|
||||
if (barvnaSlika == null) return;
|
||||
|
||||
switch (args[0]) {
|
||||
case "barvna":
|
||||
izpisiBarvnoSliko(barvnaSlika);
|
||||
return;
|
||||
case "sivinska":
|
||||
izpisiSliko(pretvoriVSivinsko(barvnaSlika));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int[][] slika = preberiSliko(args[1]);
|
||||
if (slika == null) return;
|
||||
|
||||
switch (args[0]) {
|
||||
case "izpisi":
|
||||
izpisiSliko(slika);
|
||||
break;
|
||||
case "histogram":
|
||||
izpisiHistogram(slika);
|
||||
break;
|
||||
case "svetlost":
|
||||
System.out.printf("Srednja vrednost sivine na sliki %s je: %.2f\n", args[1], svetlostSlike(slika));
|
||||
break;
|
||||
case "zmanjsaj":
|
||||
izpisiSliko(zmanjsajSliko(slika));
|
||||
break;
|
||||
case "rotiraj":
|
||||
izpisiSliko(rotirajSliko(slika));
|
||||
break;
|
||||
case "zrcali":
|
||||
izpisiSliko(zrcaliSliko(slika));
|
||||
break;
|
||||
case "vrstica":
|
||||
System.out.printf("Max razlika svetlo - temno je v %d. vrstici.\n", poisciMaxVrstico(slika));
|
||||
break;
|
||||
case "uredi":
|
||||
preberiVseInIzpisi(Arrays.stream(args).skip(1).toArray(String[]::new));
|
||||
break;
|
||||
case "jedro":
|
||||
konvolucijaJedro(slika);
|
||||
break;
|
||||
case "glajenje":
|
||||
konvolucijaGlajenje(slika);
|
||||
break;
|
||||
case "robovi":
|
||||
konvolucijaRobovi(slika);
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("Napaka: Neveljaven argument.");
|
||||
}
|
||||
}
|
||||
|
||||
static int[][] preberiSliko(String ime) {
|
||||
File file = new File(ime);
|
||||
|
||||
Scanner scanner;
|
||||
try {
|
||||
scanner = new Scanner(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.printf("Napaka: datoteka %s ne obstaja.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!scanner.hasNextLine()) {
|
||||
System.out.printf("Napaka: Datoteka %s je prazna.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
String format = scanner.nextLine();
|
||||
|
||||
Pattern pattern = Pattern.compile("^P2: (.+) x (.+)$");
|
||||
Matcher matcher = pattern.matcher(format);
|
||||
|
||||
if (!matcher.matches()) {
|
||||
System.out.printf("Napaka: datoteka %s ni v formatu P2.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
try {
|
||||
width = Integer.parseInt(matcher.group(1));
|
||||
height = Integer.parseInt(matcher.group(2));
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.printf("Napaka: datoteka %s ni v formatu P2 (velikost slike ni pravilna).\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
System.out.printf("Napaka: datoteka %s ni v formatu P2 (velikost slike je 0 ali negativna).\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!scanner.hasNextLine()) {
|
||||
System.out.printf("Napaka: datoteka %s vsebuje premalo podatkov.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] data = scanner.nextLine().split(" ");
|
||||
|
||||
if (data.length < width * height) {
|
||||
System.out.printf("Napaka: datoteka %s vsebuje premalo podatkov.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
int[][] image = new int[height][width];
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
int p = Integer.parseInt(data[i * width + j]);
|
||||
if (p < 0 || p > 255) {
|
||||
System.out.printf("Napaka: datoteka %s vsebuje podatke izven obsega 0 do 255.\n", ime);
|
||||
return null;
|
||||
}
|
||||
image[i][j] = p;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static void izpisiSliko(int[][] slika) {
|
||||
System.out.printf("velikost slike: %d x %d\n", slika[0].length, slika.length);
|
||||
|
||||
for (int[] row : slika) {
|
||||
for (int p : row) {
|
||||
System.out.printf("%3d ", p);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
static void izpisiHistogram(int[][] slika) {
|
||||
int[] histogram = new int[256];
|
||||
|
||||
for (int[] row : slika) {
|
||||
for (int p : row) {
|
||||
histogram[p]++;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("sivina : # pojavitev");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (histogram[i] == 0) continue;
|
||||
System.out.printf(" %3d : %d\n", i, histogram[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static double svetlostSlike(int[][] slika) {
|
||||
double sum = 0;
|
||||
for (int[] row : slika) {
|
||||
for (int p : row) {
|
||||
sum += p;
|
||||
}
|
||||
}
|
||||
return sum / (slika.length * slika[0].length);
|
||||
}
|
||||
|
||||
static int[][] zmanjsajSliko(int[][] slika) {
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
if (width < 3 || height < 3) {
|
||||
return slika;
|
||||
}
|
||||
|
||||
int newWidth = width / 2;
|
||||
int newHeight = height / 2;
|
||||
|
||||
int[][] newImage = new int[newHeight][newWidth];
|
||||
|
||||
for (int i = 0; i < newHeight; i++) {
|
||||
for (int j = 0; j < newWidth; j++) {
|
||||
newImage[i][j] = (slika[i * 2][j * 2] + slika[i * 2][j * 2 + 1] + slika[i * 2 + 1][j * 2] + slika[i * 2 + 1][j * 2 + 1]) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
static int[][] rotirajSliko(int[][] slika) {
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
|
||||
int[][] newImage = new int[width][height];
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
newImage[i][j] = slika[height - j - 1][i];
|
||||
}
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
static int[][] zrcaliSliko(int[][] slika) {
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
|
||||
int[][] newImage = new int[height][width];
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
newImage[i][j] = slika[i][width - j - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
static int poisciMaxVrstico(int[][] slika) {
|
||||
int maxDiff = 0;
|
||||
int maxDiffIndex = 0;
|
||||
|
||||
for (int i = 0; i < slika.length; i++) {
|
||||
int min = slika[i][0];
|
||||
int max = slika[i][0];
|
||||
|
||||
for (int j = 1; j < slika[i].length; j++) {
|
||||
if (slika[i][j] < min) {
|
||||
min = slika[i][j];
|
||||
}
|
||||
if (slika[i][j] > max) {
|
||||
max = slika[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
int diff = max - min;
|
||||
if (diff > maxDiff) {
|
||||
maxDiff = diff;
|
||||
maxDiffIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return maxDiffIndex + 1;
|
||||
}
|
||||
|
||||
static int[][][] preberiBarvnoSliko(String ime) {
|
||||
File file = new File(ime);
|
||||
|
||||
Scanner scanner;
|
||||
try {
|
||||
scanner = new Scanner(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.printf("Napaka: datoteka %s ne obstaja.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!scanner.hasNextLine()) {
|
||||
System.out.printf("Napaka: Datoteka %s je prazna.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
String format = scanner.nextLine();
|
||||
|
||||
Pattern pattern = Pattern.compile("^P2B: (.+) x (.+)$");
|
||||
Matcher matcher = pattern.matcher(format);
|
||||
|
||||
if (!matcher.matches()) {
|
||||
System.out.printf("Napaka: datoteka %s ni v formatu P2B.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
try {
|
||||
width = Integer.parseInt(matcher.group(1));
|
||||
height = Integer.parseInt(matcher.group(2));
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.printf("Napaka: datoteka %s ni v formatu P2B (velikost slike ni pravilna).\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
System.out.printf("Napaka: datoteka %s ni v formatu P2B (velikost slike je 0 ali negativna).\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!scanner.hasNextLine()) {
|
||||
System.out.printf("Napaka: datoteka %s vsebuje premalo podatkov.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] data = scanner.nextLine().split(" ");
|
||||
|
||||
if (data.length < width * height) {
|
||||
System.out.printf("Napaka: datoteka %s vsebuje premalo podatkov.\n", ime);
|
||||
return null;
|
||||
}
|
||||
|
||||
int[][][] image = new int[height][width][3];
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
int p = Integer.parseInt(data[i * width + j]);
|
||||
int mask = 0b1111111111;
|
||||
image[i][j][2] = p & mask;
|
||||
image[i][j][1] = (p >> 10) & mask;
|
||||
image[i][j][0] = (p >> 20) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static void izpisiBarvnoSliko(int[][][] slika) {
|
||||
System.out.println("velikost slike: " + slika[0].length + " x " + slika.length);
|
||||
|
||||
for (int[][] row : slika) {
|
||||
for (int[] p : row) {
|
||||
System.out.printf("(%4d, %4d, %4d) ", p[0], p[1], p[2]);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
static int[][] pretvoriVSivinsko(int[][][] slika) {
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
|
||||
int[][] newImage = new int[height][width];
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
newImage[i][j] = (slika[i][j][0] + slika[i][j][1] + slika[i][j][2]) / 3 * 255 / 1023;
|
||||
}
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
static void preberiVseInIzpisi(String[] imenaSlik) {
|
||||
int[][] map = new int[imenaSlik.length][2];
|
||||
|
||||
for (int i = 0; i < imenaSlik.length; i++) {
|
||||
int[][] slika = preberiSliko(imenaSlik[i]);
|
||||
if (slika == null) continue;
|
||||
int svetlost = (int) Math.round(svetlostSlike(slika));
|
||||
map[i][0] = svetlost;
|
||||
map[i][1] = i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < map.length; i++) {
|
||||
for (int j = 0; j < map.length - i - 1; j++) {
|
||||
if (map[j][0] < map[j + 1][0] || (map[j][0] == map[j + 1][0] && imenaSlik[map[j][1]].compareToIgnoreCase(imenaSlik[map[j + 1][1]]) > 0)) {
|
||||
int[] temp = map[j];
|
||||
map[j] = map[j + 1];
|
||||
map[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int[] pair : map) {
|
||||
System.out.printf("%s (%d)\n", imenaSlik[pair[1]], pair[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void konvolucijaJedro(int[][] slika) {
|
||||
int[][] jedro = {
|
||||
{1, 1, 1},
|
||||
{1, 1, 1},
|
||||
{1, 1, 1}
|
||||
};
|
||||
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
|
||||
int[][] novaSlika = new int[height - 2][width - 2];
|
||||
|
||||
for (int i = 1; i < height - 1; i++) {
|
||||
for (int j = 1; j < width - 1; j++) {
|
||||
int sum = 0;
|
||||
for (int k = -1; k <= 1; k++) {
|
||||
for (int l = -1; l <= 1; l++) {
|
||||
sum += slika[i + k][j + l] * jedro[k + 1][l + 1];
|
||||
}
|
||||
}
|
||||
novaSlika[i - 1][j - 1] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
izpisiSliko(novaSlika);
|
||||
}
|
||||
|
||||
static int[][] razsiriSliko(int[][] slika) {
|
||||
int w = slika[0].length;
|
||||
int h = slika.length;
|
||||
|
||||
int[][] razsirjena = new int[h + 2][w + 2];
|
||||
for (int i = 0; i < razsirjena.length; i++) {
|
||||
for (int j = 0; j < razsirjena[i].length; j++) {
|
||||
if (i == 0 && j == 0) {
|
||||
razsirjena[i][j] = slika[0][0];
|
||||
} else if (i == 0 && j == w + 1) {
|
||||
razsirjena[i][j] = slika[0][w - 1];
|
||||
} else if (i == h + 1 && j == 0) {
|
||||
razsirjena[i][j] = slika[h - 1][0];
|
||||
} else if (i == h + 1 && j == w + 1) {
|
||||
razsirjena[i][j] = slika[h - 1][w - 1];
|
||||
} else if (i == 0) {
|
||||
razsirjena[i][j] = slika[0][j - 1];
|
||||
} else if (i == h + 1) {
|
||||
razsirjena[i][j] = slika[h - 1][j - 1];
|
||||
} else if (j == 0) {
|
||||
razsirjena[i][j] = slika[i - 1][0];
|
||||
} else if (j == w + 1) {
|
||||
razsirjena[i][j] = slika[i - 1][w - 1];
|
||||
} else {
|
||||
razsirjena[i][j] = slika[i - 1][j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return razsirjena;
|
||||
}
|
||||
|
||||
static void konvolucijaGlajenje(int[][] slika) {
|
||||
double[][] jedro = {
|
||||
{16, 8, 16},
|
||||
{8, 4, 8},
|
||||
{16, 8, 16},
|
||||
};
|
||||
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
|
||||
int[][] razsirjenaSlika = razsiriSliko(slika);
|
||||
|
||||
int[][] novaSlika = new int[height][width];
|
||||
|
||||
for (int i = 1; i <= height; i++) {
|
||||
for (int j = 1; j <= width; j++) {
|
||||
int sum = 0;
|
||||
for (int k = -1; k <= 1; k++) {
|
||||
for (int l = -1; l <= 1; l++) {
|
||||
sum += (int) Math.round(razsirjenaSlika[i + k][j + l] / jedro[k + 1][l + 1]);
|
||||
}
|
||||
}
|
||||
novaSlika[i - 1][j - 1] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
izpisiSliko(novaSlika);
|
||||
}
|
||||
|
||||
static void konvolucijaRobovi(int[][] slika) {
|
||||
int width = slika[0].length;
|
||||
int height = slika.length;
|
||||
|
||||
int[][] razsirjenaSlika = razsiriSliko(slika);
|
||||
|
||||
int[][] navpicni = {
|
||||
{1, 0, -1},
|
||||
{2, 0, -2},
|
||||
{1, 0, -1}
|
||||
};
|
||||
int[][] roboviNavpicno = new int[height][width];
|
||||
for (int i = 1; i <= height; i++) {
|
||||
for (int j = 1; j <= width; j++) {
|
||||
int sum = 0;
|
||||
for (int k = -1; k <= 1; k++) {
|
||||
for (int l = -1; l <= 1; l++) {
|
||||
sum += razsirjenaSlika[i + k][j + l] * navpicni[k + 1][l + 1];
|
||||
}
|
||||
}
|
||||
roboviNavpicno[i - 1][j - 1] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
int[][] vodoravni = {
|
||||
{1, 2, 1},
|
||||
{0, 0, 0},
|
||||
{-1, -2, -1}
|
||||
};
|
||||
int[][] roboviVodoravno = new int[height][width];
|
||||
for (int i = 1; i <= height; i++) {
|
||||
for (int j = 1; j <= width; j++) {
|
||||
int sum = 0;
|
||||
for (int k = -1; k <= 1; k++) {
|
||||
for (int l = -1; l <= 1; l++) {
|
||||
sum += razsirjenaSlika[i + k][j + l] * vodoravni[k + 1][l + 1];
|
||||
}
|
||||
}
|
||||
roboviVodoravno[i - 1][j - 1] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
int[][] roboviSkupaj = new int[height][width];
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
roboviSkupaj[i][j] = (int) Math.round(Math.sqrt(roboviNavpicno[i][j] * roboviNavpicno[i][j] + roboviVodoravno[i][j] * roboviVodoravno[i][j]));
|
||||
}
|
||||
}
|
||||
|
||||
int max = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
max = Math.max(max, roboviSkupaj[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
int[][] roboviKoncni = new int[height][width];
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
roboviKoncni[i][j] = (int) Math.round(roboviSkupaj[i][j] * 255.0 / max);
|
||||
}
|
||||
}
|
||||
|
||||
izpisiSliko(roboviKoncni);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user