Skip to content
Snippets Groups Projects
Commit d5c6d3c8 authored by Niklas Bretz's avatar Niklas Bretz
Browse files

Gesamtes Projekt auf Gitlab hochgeladen

parent ebe00139
No related branches found
No related tags found
No related merge requests found
# Auto detect text files and perform LF normalization
* text=auto
Ausgabe.pgm 0 → 100644
This diff is collapsed.
Bild1.pgm 0 → 100644
This diff is collapsed.
Bild2.pgm 0 → 100644
This diff is collapsed.
#https://stackoverflow.com/questions/4382945/abstract-methods-in-python
import abc
import icontract
class BorderBehavior:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
@icontract.require(lambda result: len(result) > 0)
def get_submatrix_list(self, point, matrix, radius = 1):
return
#point and matrix are given, returned boolean signals if the provided point is out of bounds
@classmethod
def check_if_oob(cls, point, matrix):
if point[0] < 0 or point[1] < 0:
return True
if point[0] > len(matrix) - 1 or point[1] > len(matrix[0]) - 1:
return True
return False
\ No newline at end of file
import icontract
from BorderBehavior import BorderBehavior
class ClampingPaddingBorderBehavior(BorderBehavior):
#the method gets a point as list, the image as a 2d list and the value a radius
#it returns the values around the provided point as a list
# if one of the values around the point is out of the bounds of the given matrix, its value is the value of the nearest pixel thats not out of bounds
@icontract.ensure(lambda radius: radius > 0, "radius must be 1 or more")
def get_submatrix_list(self, point, matrix, radius = 1):
submatrix_as_list = []
for j in range(point[0] - radius, point[0] + radius + 1):
for i in range(point[1] - radius, point[1] + radius + 1):
if ClampingPaddingBorderBehavior.check_if_oob([j, i], matrix):
# oob top left
if j == -1 and i == -1:
submatrix_as_list.append(matrix[j + 1][i + 1])
# oob bottom right
elif j == len(matrix) and i == len(matrix[0]):
submatrix_as_list.append(matrix[j - 1][i - 1])
# oob bottom left
elif j == len(matrix) and i == -1:
submatrix_as_list.append(matrix[j - 1][i + 1])
# oob top right
elif j == -1 and i == len(matrix[0]):
submatrix_as_list.append(matrix[j + 1][i - 1])
# oob left
elif i == -1 and not j == -1:
submatrix_as_list.append(matrix[j][i + 1])
# oob top
elif j == -1 and not i == -1:
submatrix_as_list.append(matrix[j + 1][i])
# oob right
elif i == len(matrix[0]) and not j == len(matrix):
submatrix_as_list.append(matrix[j][i - 1])
# oob bottom
elif j == len(matrix) and not i == len(matrix[0]):
submatrix_as_list.append(matrix[j - 1][i])
else:
submatrix_as_list.append(matrix[j][i])
return submatrix_as_list
@classmethod
def check_if_oob(cls, point, matrix):
return super().check_if_oob(point, matrix)
\ No newline at end of file
Image.py 0 → 100644
import icontract
@icontract.invariant(lambda self: self.magic_number_is_correct is True)
class Image:
PGM_PIXEL_OFFSET = 2
PGM_FILE_EXTENSION = ".pgm"
def __init__(self):
self.magic_number_is_correct = True
self.pixels = [[]]
@icontract.require(lambda pixels: len(pixels) >= 4)
def set_pixels(self, pixels):
self.pixels = pixels
@icontract.require(lambda filename: filename.endswith(Image.PGM_FILE_EXTENSION), "provided filename should be in .pgm format")
def readFromFile(self, filename):
file = open(filename, "r")
content = file.readlines()
content = Image.remove_comments(content)
lines = Image.trim_lines(content)
self.magic_number_is_correct = Image.check_for_magic_number(lines)
w_and_h = Image.extract_width_and_height(lines[1])
self.pixels = [[0 for x in range(w_and_h[0])] for y in range(w_and_h[1])]
#initalizing this way is from https://stackoverflow.com/questions/6667201/how-to-define-a-two-dimensional-array
k = Image.PGM_PIXEL_OFFSET
for i in range(len(self.pixels)):
for j in range(len(self.pixels[0])):
self.pixels[i][j] = lines[k]
k = k + 1
print(f"File {filename} has been read")
return self.pixels
@icontract.require(lambda filename: filename.endswith(Image.PGM_FILE_EXTENSION), "filename should end with .pgm")
def write_to_file(self, filename):
file = open(filename, "w")
file.writelines(["P2\n", f"{len(self.pixels[0])} {len(self.pixels)}\n", "255\n"])
for l in self.pixels:
for p in l:
file.write(str(p))
file.write("\n")
#initializes a new 2d matrix in which the filtered image gets stored
#after this the method gets the pixel values by using the kernel method get_pixel_value
@icontract.require(lambda output_filename: output_filename.endswith(Image.PGM_FILE_EXTENSION), "desired filename should end with .pgm")
def convolve(self, kernel, border_behavior, output_filename):
filtered_pixels = [[0 for x in range(len(self.pixels[0]))] for y in range(len(self.pixels))]
for height, rows in enumerate(self.pixels):
for width, p in enumerate(rows):
temp = int(kernel.get_pixel_value(height, width, self.pixels, border_behavior))
filtered_pixels[height][width] = Image.get_value_in_range(temp)
test = Image()
test.set_pixels(filtered_pixels)
test.write_to_file(output_filename)
print(f"File {output_filename} has been created!")
@staticmethod
def remove_comments(content):
for e in content:
if e.startswith("#"):
content.remove(e)
return content
@staticmethod
def trim_lines(lines):
for i in range(len(lines)):
lines[i] = lines[i].removesuffix('\n')
return lines
@staticmethod
def check_for_magic_number(lines):
if lines[0] == "P2":
return True
return False
@staticmethod
def extract_width_and_height(string):
temp = string.split()
temp[0] = int(temp[0])
temp[1] = int(temp[1])
return temp
@staticmethod
def get_value_in_range(value):
if value < 0:
return 0
if value > 255:
return 255
return value
''' for width, rows in enumerate(self.pixels):
for height, p in enumerate(rows):
temp = int(kernel.get_pixel_value(height, width, self.pixels, border_behavior))
filtered_pixels[width][height] = Image.get_value_in_range(temp)'''
\ No newline at end of file
class Kernel:
def __init__(self, filter_list, radius = 1):
self.radius = radius
self.filter_list = filter_list
pass
#method gets the point for which to compute the filtered value, the image as 2d array and a border_behavior object
#the border_behavior.get_submatrix_list method returns the submatrix of the values around the given point as list
#the returned list is multiplied entry by entry with the given filter_list
#the result of this multiplication is the value of the given point with the filter applied
def get_pixel_value(self, height, width, matrix, border_behavior):
sub_matrix = border_behavior.get_submatrix_list([height, width], matrix)
result = 0
for a, b in zip(self.filter_list, sub_matrix):
if type(b) == type("string"):
b = int(b)
result = result + (a * b)
return result
import icontract
#class returns kernel matrices list
class KernelFactory:
@staticmethod
def createVerticalPrewittKernel():
return [-1, -1, -1, 0, 0, 0, 1, 1, 1]
@staticmethod
def createHorizontalPrewittKernel():
return [-1, 0, 1, -1, 0, 1, -1, 0, 1]
@staticmethod
@icontract.require(lambda radius: isinstance(radius, int) is True, f"wrong datatype for radius provided")
def createBoxFilter(radius):
dimension = ((2 * radius) + 1) ** 2
return [1 / dimension for _ in range(dimension)]
from BorderBehavior import BorderBehavior
class ZeroPaddingBorderBehavior(BorderBehavior):
#the method gets a point as list, the image as a 2d list and the value a radius
#it returns the values around the provided point as a list
#if one of the values around the point is out of the bounds of the given matrix, its value is 0
def get_submatrix_list(self, point, matrix, radius = 1):
submatrix_as_list = []
for j in range(point[0] - radius, point[0] + radius + 1):
for i in range(point[1] - radius, point[1] + radius + 1):
if ZeroPaddingBorderBehavior.check_if_oob([j, i], matrix):
submatrix_as_list.append(0)
else:
submatrix_as_list.append(matrix[j][i])
return submatrix_as_list
@classmethod
def check_if_oob(cls, point, matrix):
return super().check_if_oob(point, matrix)
main.py 0 → 100644
from Image import Image
from Kernel import Kernel
from KernelFactory import KernelFactory
from ZeroPaddingBorderBehavior import ZeroPaddingBorderBehavior
from ClampingBorderBehavior import ClampingPaddingBorderBehavior
def aufgabe1():
d = Image()
d.readFromFile("Bild1.pgm")
zero_p_bb = ZeroPaddingBorderBehavior()
clamping_p_bb = ClampingPaddingBorderBehavior()
horizontal_pk = Kernel(KernelFactory().createHorizontalPrewittKernel())
vertical_pk = Kernel(KernelFactory().createVerticalPrewittKernel())
d.convolve(horizontal_pk, zero_p_bb, "./images/Ergebnis1-horizontal(zero-padding).pgm")
d.convolve(horizontal_pk, clamping_p_bb, "./images/Ergebnis1-horizontal(clamping-padding).pgm")
d.convolve(vertical_pk, zero_p_bb, "./images/Ergebnis1-vertical(zero-padding).pgm")
d.convolve(vertical_pk, clamping_p_bb, "./images/Ergebnis1-vertical(clamping-padding).pgm")
def aufgabe2():
zero_p_bb = ZeroPaddingBorderBehavior()
clamping_p_bb = ClampingPaddingBorderBehavior()
e = Image()
e.readFromFile("Bild2.pgm")
boxfilter_3 = Kernel(KernelFactory().createBoxFilter(1))
boxfilter_11 = Kernel(KernelFactory().createBoxFilter(5))
boxfilter_27 = Kernel(KernelFactory().createBoxFilter(13))
e.convolve(boxfilter_3, zero_p_bb, "./images/Ergebnis2-3(zero-bb).pgm")
e.convolve(boxfilter_3, clamping_p_bb, "./images/Ergebnis2-3(clamping_p_bb).pgm")
e.convolve(boxfilter_11, clamping_p_bb, "./images/Ergebnis2-11.pgm")
e.convolve(boxfilter_27, zero_p_bb, "./images/Ergebnis2-27.pgm")
if __name__ == "__main__":
aufgabe1()
aufgabe2()
print(type(int.g))
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment