-
Notifications
You must be signed in to change notification settings - Fork 0
/
mp02.py
161 lines (128 loc) · 3.99 KB
/
mp02.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/python
import Image, ImageDraw
import sys
from itertools import product
from ccl import *
import matplotlib.pyplot as plt
# Erosion function for white images on black background
def Erosion(img, SE):
X, Y = img.size
data = img.load()
outimg = Image.new(img.mode, img.size)
outimg_data = outimg.load()
# Define dimensions of SE
seX = 3
seY = 3
# Define centre of SE
hx = seX/2
hy = seY/2
for y, x in product(range(hy, Y-hy), range(hx, X-hx)):
x0 = []
if(data[x, y] == 255):
# Check all pixels in SE and set only elements at the above range to be white
if SE[0]: x0.append(data[x-1, y-1])
if SE[1]: x0.append(data[x, y-1])
if SE[2]: x0.append(data[x+1, y-1])
if SE[3]: x0.append(data[x-1, y])
if SE[4]: x0.append(data[x, y])
if SE[5]: x0.append(data[x+1, y])
if SE[6]: x0.append(data[x-1, y+1])
if SE[7]: x0.append(data[x, y+1])
if SE[8]: x0.append(data[x+1, y+1])
if all(x0): outimg_data[x, y] = 255
return outimg
# Dilation function for white images on black background
def Dilation(img, SE):
X, Y = img.size
data = img.load()
outimg = Image.new(img.mode, img.size)
outimg_data = outimg.load()
# Define dimensions of SE
seX = 3
seY = 3
# Define centre of SE
hx = seX/2
hy = seY/2
for y, x in product(range(hy, Y-hy), range(hx, X-hx)):
if(data[x, y] == 255):
# Check SE & set the respective surrounding pixels in original image to be white
if SE[0]: outimg_data[x-1, y-1] = 255
if SE[1]: outimg_data[x, y-1] = 255
if SE[2]: outimg_data[x+1, y-1] = 255
if SE[3]: outimg_data[x-1, y] = 255
if SE[4]: outimg_data[x, y] = 255
if SE[5]: outimg_data[x+1, y] = 255
if SE[6]: outimg_data[x-1, y+1] = 255
if SE[7]: outimg_data[x, y+1] = 255
if SE[8]: outimg_data[x+1, y+1] = 255
return outimg
# Define 'Opening' function as a combination of Erosion followed by Dilation
def Opening(img, SE):
return Dilation(Erosion(img, SE), SE)
# Define 'Opening' function as a combination of Dilation followed by Erosion
def Closing(img, SE):
return Erosion(Dilation(img, SE), SE)
'''Define Boundary as a function that performs the following morphological operation :
A - A(-)B where A is original image and B is SE
'''
def Boundary(img):
X, Y = img.size
data1 = img.load()
outimg = Image.new(img.mode, img.size)
outimg_data = outimg.load()
data2 = Erosion(img, (1,1,1,1,1,1,1,1,1)).load()
for y, x in product(range(Y), range(X)):
outimg_data[x, y] = data1[x, y] - data2[x, y]
return outimg
# A helper function to get the image after filtering and removing noise (using CCL and size filter from MP01)
def getOutputImg2(img, TH):
labels = applyCcl(img)
labels = applySizeFilter(labels, TH)
output_img = Image.new(img.mode, img.size)
outdata = output_img.load()
colors = {}
for (x, y) in labels:
temp = find(labels[(x, y)])
labels[(x, y)] = temp
if temp not in colors:
colors[temp] = 255
outdata[x, y] = colors[temp]
return output_img
'''
When running in command line, this program takes in 3 arguments:
1. image: e.g. 'gun.bmp'
2. SE (3x3 pix element): e.g. 111111111
3. morph operations (any number of combinations): e.g. D2E1CB
D2E1CB = Dilation x 2 --> Erosion x 1 --> Closing --> Boundary Extraction
'''
def main():
img = Image.open(sys.argv[1])
img = img.convert('1')
outimg = img
try:
SE = sys.argv[2]
SE = map(int, SE)
todo = sys.argv[3]
for i in range(len(todo)):
if todo[i] == 'D':
itr = int(todo[i+1])
for i in range(itr):
outimg = Dilation(outimg, SE)
if todo[i] == 'E':
itr = int(todo[i+1])
for i in range(itr):
outimg = Erosion(outimg, SE)
if todo[i] == 'C':
outimg = Closing(outimg, SE)
if todo[i] == 'O':
outimg = Opening(outimg, SE)
if todo[i] == 'B':
# outimg = getOutputImg2(outimg)
outimg = Boundary(outimg)
if todo[i] == 'N':
outimg = getOutputImg2(outimg, int(sys.argv[4]))
img.show() # Display original image
outimg.show() # Display output image
except:
print "Please check your input arguments!"
if __name__ == "__main__": main()