nuwandaa commited on
Commit
058d49f
·
verified ·
1 Parent(s): 076d46d

Create trimap_module.py

Browse files
Files changed (1) hide show
  1. trimap_module.py +164 -0
trimap_module.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ import cv2, os, sys
3
+ import numpy as np
4
+
5
+ def extractImage(path):
6
+ # error handller if the intended path is not found
7
+ image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
8
+ return image
9
+
10
+ def checkImage(image):
11
+ """
12
+ Args:
13
+ image: input image to be checked
14
+ Returns:
15
+ binary image
16
+ Raises:
17
+ RGB image, grayscale image, all-black, and all-white image
18
+
19
+ """
20
+ if len(image.shape) > 2:
21
+ print("ERROR: non-binary image (RGB)"); sys.exit();
22
+
23
+ smallest = image.min(axis=0).min(axis=0) # lowest pixel value: 0 (black)
24
+ largest = image.max(axis=0).max(axis=0) # highest pixel value: 1 (white)
25
+
26
+ if (smallest == 0 and largest == 0):
27
+ print("ERROR: non-binary image (all black)"); sys.exit()
28
+ elif (smallest == 255 and largest == 255):
29
+ print("ERROR: non-binary image (all white)"); sys.exit()
30
+ elif (smallest > 0 or largest < 255 ):
31
+ print("ERROR: non-binary image (grayscale)"); sys.exit()
32
+ else:
33
+ return True
34
+
35
+ class Toolbox:
36
+ def __init__(self, image):
37
+ self.image = image
38
+
39
+ @property
40
+ def printImage(self):
41
+ """
42
+ Print image into a file for checking purpose
43
+ unitTest = Toolbox(image);
44
+ unitTest.printImage(image);
45
+ """
46
+ f = open("image_results.dat", "w+")
47
+ for i in range(0, self.image.shape[0]):
48
+ for j in range(0, self.image.shape[1]):
49
+ f.write("%d " %self.image[i,j])
50
+ f.write("\n")
51
+ f.close()
52
+
53
+ @property
54
+ def displayImage(self):
55
+ """
56
+ Display the image on a window
57
+ Press any key to exit
58
+ """
59
+ cv2.imshow('Displayed Image', self.image)
60
+ cv2.waitKey(0)
61
+ cv2.destroyAllWindows()
62
+
63
+ def saveImage(self, title, extension):
64
+ """
65
+ Save as a specific image format (bmp, png, or jpeg)
66
+ """
67
+ cv2.imwrite("{}.{}".format(title,extension), self.image)
68
+
69
+ def morph_open(self, image, kernel):
70
+ """
71
+ Remove all white noises or speckles outside images
72
+ Need to tune the kernel size
73
+ Instruction:
74
+ unit01 = Toolbox(image);
75
+ kernel = np.ones( (9,9), np.uint8 );
76
+ morph = unit01.morph_open(input_image, kernel);
77
+ """
78
+ bin_open = cv2.morphologyEx(self.image, cv2.MORPH_OPEN, kernel)
79
+ return bin_open
80
+
81
+ def morph_close(self, image, kernel):
82
+ """
83
+ Remove all black noises or speckles inside images
84
+ Need to tune the kernel size
85
+ Instruction:
86
+ unit01 = Toolbox(image);
87
+ kernel = np.ones( (11,11)_, np.uint8 );
88
+ morph = unit01.morph_close(input_image, kernel);
89
+ """
90
+ bin_close = cv2.morphologyEx(self.image, cv2.MORPH_CLOSE, kernel)
91
+ return bin_close
92
+
93
+
94
+ def trimap(image, name, size, number, erosion=False):
95
+ """
96
+ This function creates a trimap based on simple dilation algorithm
97
+ Inputs [4]: a binary image (black & white only), name of the image, dilation pixels
98
+ the last argument is optional; i.e., how many iterations will the image get eroded
99
+ Output : a trimap
100
+ """
101
+ checkImage(image)
102
+ row = image.shape[0]
103
+ col = image.shape[1]
104
+ pixels = 2*size + 1 ## Double and plus 1 to have an odd-sized kernel
105
+ kernel = np.ones((pixels,pixels),np.uint8) ## Pixel of extension I get
106
+
107
+ if erosion is not False:
108
+ erosion = int(erosion)
109
+ erosion_kernel = np.ones((3,3), np.uint8) ## Design an odd-sized erosion kernel
110
+ image = cv2.erode(image, erosion_kernel, iterations=erosion) ## How many erosion do you expect
111
+ image = np.where(image > 0, 255, image) ## Any gray-clored pixel becomes white (smoothing)
112
+ # Error-handler to prevent entire foreground annihilation
113
+ if cv2.countNonZero(image) == 0:
114
+ print("ERROR: foreground has been entirely eroded")
115
+ sys.exit()
116
+
117
+ dilation = cv2.dilate(image, kernel, iterations = 1)
118
+
119
+ dilation = np.where(dilation == 255, 127, dilation) ## WHITE to GRAY
120
+ remake = np.where(dilation != 127, 0, dilation) ## Smoothing
121
+ remake = np.where(image > 127, 200, dilation) ## mark the tumor inside GRAY
122
+
123
+ remake = np.where(remake < 127, 0, remake) ## Embelishment
124
+ remake = np.where(remake > 200, 0, remake) ## Embelishment
125
+ remake = np.where(remake == 200, 255, remake) ## GRAY to WHITE
126
+
127
+ #############################################
128
+ # Ensures only three pixel values available #
129
+ # TODO: Optimization with Cython #
130
+ #############################################
131
+ for i in range(0,row):
132
+ for j in range (0,col):
133
+ if (remake[i,j] != 0 and remake[i,j] != 255):
134
+ remake[i,j] = 127
135
+
136
+ path = "./images/results/" ## Change the directory
137
+ new_name = '{}px_'.format(size) + name + '_{}.png'.format(number)
138
+ cv2.imwrite(os.path.join(path, new_name) , remake)
139
+
140
+
141
+ #############################################
142
+ ### TESTING SECTION ###
143
+ #############################################
144
+ if __name__ == '__main__':
145
+ path = "./images/test_images/test_image_11.png"
146
+ image = extractImage(path)
147
+
148
+ size = 10
149
+ number = path[-5]
150
+ title = "test_image"
151
+
152
+ unit01 = Toolbox(image);
153
+ kernel1 = np.ones( (11,11), np.uint8 )
154
+ unit01.displayImage
155
+
156
+ opening = unit01.morph_close(image,kernel1)
157
+ trimap(opening, title, size, number, erosion=False)
158
+ unit02 = Toolbox(opening)
159
+ unit02.displayImage
160
+
161
+ ########################################################
162
+ ## Default instruction (no binary opening or closing ##
163
+ ## trimap(image, title, size, number, erosion=False); ##
164
+ ########################################################