I'm currently doing a student project which does some image processings (dilation and erosion) on greyscale pgm file. I tried to implement dilation on the image object but got weird result. I expected the image object will be larger than the original image. But I got multiple copies of the object depending the kernel size I use.
Original Picture:
Dilation result:
This is my dilation source code
import numpy as np
def pgm_read(filename):
"""Read PGM file to a array"""
# Performance Bottleneck: I/O system calls, parallel write/read
try:
with open(filename, 'r') as fp:
lines = fp.readlines()
header_info = lines[2].split()
return np.array([line.strip('\n') for line in lines[4:]], dtype=np.int32).reshape(int(header_info[0]),
int(header_info[1]))
except OSError:
print("An exception occurred")
def pgm_write(img, dest, header):
"""Write numpy array to PGM file"""
try:
header = "P2\n# test\n" + header + "\n80\n"
f = open(dest, "w")
f.write(header)
f.close()
with open(dest, "a") as f:
for x in range(img.shape[0]):
for y in range(img.shape[1]):
f.write(str(img[x][y]) + "\n")
except OSError:
print("Writing exception occurred")
def dilation(img):
rows, cols = img.shape
dilated_img = np.zeros((rows, cols), dtype=np.int32)
kernel = np.ones((2, 2))
rows2, cols2 = kernel.shape
for x in range(rows):
for y in range(cols):
"""Search the object within the image"""
if img[x][y] == 1:
# Convolve with kernel
for i in range(rows2):
for j in range(cols2):
if kernel[i][j] == 1:
# Object Enlargement
c = x + i
d = y + j
if c < rows and d < cols:
dilated_img[c][d] = 1
for x in range(rows):
for y in range(cols):
"""Give the object brightest colour for debugging purpose"""
if dilated_img[x][y] == 1:
dilated_img[x][y] = 80
return dilated_img
if __name__ == '__main__':
a = pgm_read("Axial_68.pgm")
a = dilation(a)
target = "Axial_68_1.pgm"
header = "265 490"
pgm_write(a, target, header)
I am very certain my file reading and writing functions work properly as I can use it to read and write other source pgm file properly.
And one thing I found very weird behaviour is I could print half pgm file like this.
using code
for x in range(rows // 2):
for y in range(columns):
arr[x][y] = 80
But when I use this code and expect half vertical using code:
for x in range(rows):
for y in range(columns // 2):
arr[x][y] = 80
I got this:
I have tried this with a few other generated pgm files and all are same result. I wonder if my dilation code has something to do with this weird behaviour.
It always helps displaying a matrix directly, rather than relying on routines that you wrote yourself to write it to file for examination. For example, adding
import matplotlib.pyplot as pp
#...
a = pgm_read("Axial_68.pgm")
pp.imshow(a)
pp.show()
to your code immediately reveals that the input image is not read in correctly. Swapping the two dimensions in the reshape
function call fixed it for me:
return np.array([line.strip('\n') for line in lines[4:]], dtype=np.int32).reshape(int(header_info[1]),
int(header_info[0]))
I highly recommend that you use a library to read and write image files. For example imageio is a good option. Matplotlib itself also reads and writes various image file formats. If you want to do image processing, get a library for that too. For example Pillow, OpenCV or DIPlib. These all also include image file reading and writing functionality.