Skip to content
Snippets Groups Projects
Commit 7181eb7b authored by Sebastian Schwarz's avatar Sebastian Schwarz
Browse files

Documentation added

parent 4db1350c
No related branches found
No related tags found
No related merge requests found
Showing
with 70087 additions and 41 deletions
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ No newline at end of file
Gruppe: Beachboys
Ragnar Kuhl: 768097
Mika Rasmussen: 768364
Juan Lauer Garrido: 768446
Sebastian Schwarz: 768298
Wieso liefert hier zero-padding ein minimal anderes Ergebnis als clamping? Hinweis: Kanten?
Was bewirkt den Ergebnissen nach zu urteilen eine Vergrößerung desFilterkernels bei einem Boxfilter?
Wie wirken sich zero-padding und clamping hier aus?
...@@ -2,6 +2,7 @@ from abc import ABC, abstractmethod ...@@ -2,6 +2,7 @@ from abc import ABC, abstractmethod
class BorderBehavior(ABC): class BorderBehavior(ABC):
''' This abstract function is overwritten in the inherited classes ZeroPaddingBorderBehavior and ClampingBorderBehavior. '''
@abstractmethod @abstractmethod
def getPixelValue(self, i, j, image): def getPixelValue(self, i, j, image):
pass pass
......
from BorderBehavior import BorderBehavior from BorderBehavior import BorderBehavior
'''
ClampingBorderBehavior, welche für (i, j) ausserhalb des Bildes,
wie in Abbildung 2 unten dargestellt, den Wert des am nächsten
gelegenen Randpixels zurückgibt (2p)
'''
''' This function limits a value to a given range
Source: https://www.pythonpool.com/python-clamp/ '''
def clamp(num, min_value, max_value): def clamp(num, min_value, max_value):
num = max(min(num, max_value), min_value) num = max(min(num, max_value), min_value)
return num return num
class ClampingBorderBehavior(BorderBehavior): class ClampingBorderBehavior(BorderBehavior):
''' This function returns the value of the image at the given index. If the index is out of range or negative it returns the value of the nearest pixel. '''
def getPixelValue(self, i, j, image): def getPixelValue(self, i, j, image):
try: try:
if i < 0 or j < 0: if i < 0 or j < 0:
clamped_i = clamp(i, 0, image.shape[1] - 1) clamped_i = clamp(i, 0, image.shape[0] - 1)
clamped_j = clamp(j, 0, image.shape[0] - 1) clamped_j = clamp(j, 0, image.shape[1] - 1)
else: else:
return image[i][j] return image[i][j]
except IndexError: except IndexError:
clamped_i = clamp(i, 0, image.shape[1]-1) clamped_i = clamp(i, 0, image.shape[0]-1)
clamped_j = clamp(j, 0, image.shape[0]-1) clamped_j = clamp(j, 0, image.shape[1]-1)
return image[clamped_i][clamped_j] return image[clamped_i][clamped_j]
...@@ -3,18 +3,23 @@ from numpy import array ...@@ -3,18 +3,23 @@ from numpy import array
class Image: class Image:
''' Constructor to create an instance of Image. '''
def __init__(self): def __init__(self):
self.__imageData = None self.__imageData = None
''' This function gets the imageData of the image. '''
def get_imageData(self): def get_imageData(self):
return self.__imageData return self.__imageData
''' This function sets the imageData to the given Value. '''
def set_imageData(self, value): def set_imageData(self, value):
self.__imageData = value self.__imageData = value
return self.__imageData return self.__imageData
'''This function reads PGM image files and returns
a numpy array. Image needs to have a P2 header number.
Line1 stores the magic number, line2 the width and height of the array and line3 the maximum gray level.
Comments are ignored. '''
def readFromFile(self, filename): def readFromFile(self, filename):
try: try:
...@@ -22,14 +27,14 @@ class Image: ...@@ -22,14 +27,14 @@ class Image:
except OSError: except OSError:
print("Could not read file: ", filename) print("Could not read file: ", filename)
exit() exit()
# Read header information
count = 0 count = 0
while count < 3: while count < 3:
line = f.readline() line = f.readline()
if line[0] == '#': # Ignore comments if line[0] == '#':
continue continue
count = count + 1 count = count + 1
if count == 1: # Magic num info if count == 1:
magicNum = line.strip() magicNum = line.strip()
try: try:
assert magicNum == "P2" assert magicNum == "P2"
...@@ -37,18 +42,17 @@ class Image: ...@@ -37,18 +42,17 @@ class Image:
print("Invalid PGM file! Wrong magic number.") print("Invalid PGM file! Wrong magic number.")
f.close() f.close()
exit() exit()
elif count == 2: # Width and Height elif count == 2:
size = (line.strip()).split() size = (line.strip()).split()
width = int(size[0]) width = int(size[0])
height = int(size[1]) height = int(size[1])
elif count == 3: # Max gray level elif count == 3:
maxVal = int(line.strip()) maxVal = int(line.strip())
try: try:
assert maxVal >= 0 and maxVal <= 255 assert maxVal >= 0 and maxVal <= 255
except AssertionError: except AssertionError:
print("Invalid PGM file! Invalid Pixel value.") print("Invalid PGM file! Invalid Pixel value.")
img = [] img = []
values = f.read() values = f.read()
elem = values.split() elem = values.split()
...@@ -67,6 +71,9 @@ class Image: ...@@ -67,6 +71,9 @@ class Image:
return self.__imageData return self.__imageData
''' This function writes a numpy array to a PGM
image file. By default, header number "P2" and max gray level "255" are
written. Width and height are same as the size of the given list. '''
def writeToFile(self, filename): def writeToFile(self, filename):
...@@ -89,9 +96,11 @@ class Image: ...@@ -89,9 +96,11 @@ class Image:
for i in range(height): for i in range(height):
for j in range(width): for j in range(width):
f.write(str(self.__imageData[i][j]) + ' ') f.write(str(self.__imageData[i][j]) + " ")
f.write('\n') f.write("\n")
''' This function calculates and returns the new value of a single pixel.
The central element of the filter matrix is located at the given index.'''
def get_filtered_pixel(self, i, j, imageData, kernel, borderBehavior): def get_filtered_pixel(self, i, j, imageData, kernel, borderBehavior):
kernel_half = int((len(kernel) - 1) / 2) kernel_half = int((len(kernel) - 1) / 2)
...@@ -105,13 +114,19 @@ class Image: ...@@ -105,13 +114,19 @@ class Image:
final_pixel_value += current_pixel * kernel_factor final_pixel_value += current_pixel * kernel_factor
return int(final_pixel_value) return int(final_pixel_value)
''' This function calculates the convolved image with the given kernel filter and border behavior
and returns the new convolved image.'''
def convolve(self, kernel, borderBehavior): def convolve(self, kernel, borderBehavior):
newImage = Image()
rows = len(self.__imageData) rows = len(self.__imageData)
cols = len(self.__imageData[0]) cols = len(self.__imageData[0])
newImage = [[0 for x in range(cols)] for y in range(rows)]
for i in range(cols): for i in range(rows):
for j in range(rows): for j in range(cols):
self.__imageData[i][j] = Image.get_filtered_pixel(self, i, j, self.__imageData, kernel, borderBehavior) newImage[i][j] = Image.get_filtered_pixel(self, i, j, self.__imageData, kernel, borderBehavior)
return self.__imageData
return newImage
class KernelFactory: class KernelFactory:
''' This static function returns a fix 3x3 matrix (Vertical Prewitt Kernel) '''
@staticmethod @staticmethod
def createVerticalPrewittKernel(): def createVerticalPrewittKernel():
verticalPrewittKernel = [[-1, -1, -1], verticalPrewittKernel = [[-1, -1, -1],
...@@ -7,6 +8,7 @@ class KernelFactory: ...@@ -7,6 +8,7 @@ class KernelFactory:
[1, 1, 1]] [1, 1, 1]]
return verticalPrewittKernel return verticalPrewittKernel
''' This static function returns a fix 3*3 matrix (Horizontal Prewitt Kernel) '''
@staticmethod @staticmethod
def createHorizontalPrewittKernel(): def createHorizontalPrewittKernel():
horizontalPrewittKernel = [[-1, 0, 1], horizontalPrewittKernel = [[-1, 0, 1],
...@@ -14,6 +16,7 @@ class KernelFactory: ...@@ -14,6 +16,7 @@ class KernelFactory:
[-1, 0, 1]] [-1, 0, 1]]
return horizontalPrewittKernel return horizontalPrewittKernel
''' This static function returns a n*n sized Matrix depending on the given size. Size has to be odd. '''
@staticmethod @staticmethod
def createBoxFilter(size): def createBoxFilter(size):
if size % 2 != 0: if size % 2 != 0:
......
from BorderBehavior import BorderBehavior from BorderBehavior import BorderBehavior
'''
ZeroPaddingBorderBehavior, welche für (i, j) ausserhalb des
Bildes, wie in Abbildung 2 oben dargestellt, den Wert 0 zurückgibt
(2p).
'''
class ZeroPaddingBorderBehavior(BorderBehavior): class ZeroPaddingBorderBehavior(BorderBehavior):
''' This function returns the value of the image at the given index. If the index is out of range or negative it returns 0 instead. '''
def getPixelValue(self, i, j, image): def getPixelValue(self, i, j, image):
if i < 0 or j < 0: if i < 0 or j < 0:
return 0 return 0
......
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed.
This diff is collapsed.
from Image import Image from Image import Image
import os
from KernelFactory import KernelFactory from KernelFactory import KernelFactory
from ZeroPaddingBorderBehavior import ZeroPaddingBorderBehavior from ZeroPaddingBorderBehavior import ZeroPaddingBorderBehavior
from ClampingBorderBehavior import ClampingBorderBehavior from ClampingBorderBehavior import ClampingBorderBehavior
'''RELATIVE PFADE!'''
path = "E:/Downloads/test.pgm"
path1 = "E:/Downloads/test1.pgm"
path2 ="E:/Downloads/test2.pgm"
#array = np.random.randint(256, size=(4, 4)) pathImg1 = "\images\Bild 1.pgm"
pathImg2 = "\images\Bild 2.pgm"
'''Main for showing the functionalities of the implementation'''
if __name__ == '__main__': if __name__ == '__main__':
img = Image()
print(img.readFromFile(path1))
img.writeToFile(path2)
clamping = ClampingBorderBehavior() clamping = ClampingBorderBehavior()
zero = ZeroPaddingBorderBehavior() zero = ZeroPaddingBorderBehavior()
kernel = KernelFactory.createHorizontalPrewittKernel()
img.readFromFile(path1) img = Image()
print(img.convolve(kernel, clamping)) neu = Image()
...@@ -36,7 +41,6 @@ if __name__ == '__main__': ...@@ -36,7 +41,6 @@ if __name__ == '__main__':
#print(KernelFactory.createBoxFilter(5))
......
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