1
+ import numpy as np
2
+ import cv2
3
+ from matplotlib import pyplot as plt
4
+ from scipy import ndimage as ndi
5
+ import glob
6
+
7
+
8
+ def process_blue (img ,bShow = False ,bSave = False ,strSaveFilename = '' , picname = '' ):
9
+ b ,g ,r = cv2 .split (img )
10
+ rgb = cv2 .merge ([r ,g ,b ])
11
+
12
+ ret , thresh = cv2 .threshold (b ,0 ,255 ,cv2 .THRESH_BINARY + cv2 .THRESH_OTSU )
13
+
14
+ figsize = (9 ,6 )
15
+ if bSave :
16
+ figsize = (15 , 10 )
17
+ fig , axes = plt .subplots (nrows = 2 , ncols = 4 , figsize = figsize , sharex = True , sharey = True )
18
+
19
+ ax = axes .ravel ()
20
+
21
+ # noise removal
22
+ kernel = np .ones ((3 ,3 ),np .uint8 )
23
+ opening = cv2 .morphologyEx (thresh ,cv2 .MORPH_OPEN ,kernel , iterations = 2 )
24
+
25
+ # sure background area
26
+ sure_bg = cv2 .dilate (opening ,kernel ,iterations = 3 )
27
+
28
+ # Finding sure foreground area
29
+ dist_transform = cv2 .distanceTransform (opening ,cv2 .DIST_L2 ,5 )
30
+ ret , sure_fg = cv2 .threshold (dist_transform ,0.4 * dist_transform .max (),255 ,0 )
31
+
32
+ # Finding unknown region
33
+ sure_fg = np .uint8 (sure_fg )
34
+ unknown = cv2 .subtract (sure_bg ,sure_fg )
35
+
36
+ # Marker labelling
37
+ ret , markers = cv2 .connectedComponents (sure_fg )
38
+
39
+ # Add one to all labels so that sure background is not 0, but 1
40
+ markers = markers + 1
41
+
42
+ # Now, mark the region of unknown with zero
43
+ markers [unknown == 255 ] = 0
44
+
45
+ markers = cv2 .watershed (rgb ,markers )
46
+ rgb_seg = np .copy (rgb );
47
+ rgb_seg [markers == - 1 ] = [0 ,255 ,0 ]
48
+
49
+
50
+ ax [0 ].imshow (rgb )
51
+ ax [0 ].set_title ('Original Image' )
52
+ ax [1 ].imshow (b , cmap = plt .cm .gray )
53
+ ax [1 ].set_title ('Blue component' )
54
+ ax [2 ].imshow (thresh , cmap = plt .cm .gray )
55
+ ax [2 ].set_title ('Otsu Threshold' )
56
+ ax [3 ].imshow (sure_bg , cmap = plt .cm .gray .reversed ())
57
+ ax [3 ].set_title ('Background' )
58
+ ax [4 ].imshow (sure_fg , cmap = plt .cm .gray )
59
+ ax [4 ].set_title ('Foreground seeds' )
60
+ ax [5 ].imshow (unknown , cmap = plt .cm .gray )
61
+ ax [5 ].set_title ('Borders' )
62
+ ax [6 ].imshow (dist_transform , cmap = plt .cm .gray )
63
+ ax [6 ].set_title ('Distance Transform' )
64
+ ax [7 ].imshow (rgb_seg )
65
+ ax [7 ].set_title ('Final Segmentation (nr Obj=' + str (ret - 1 ) + ')' )
66
+
67
+ for a in ax :
68
+ a .set_axis_off ()
69
+
70
+ fig .tight_layout ()
71
+ fig .suptitle (picname + ' - Blue Circles' , fontsize = 16 )
72
+ if bSave :
73
+ plt .savefig (strSaveFilename , dpi = 300 ,pad_inches = 0.1 )
74
+ if bShow :
75
+ plt .show ()
76
+ return ret - 1
77
+
78
+ def process_red (img ,bShow = False ,bSave = False ,strSaveFilename = '' , picname = '' ):
79
+ b ,g ,r = cv2 .split (img )
80
+ rgb = cv2 .merge ([r ,g ,b ])
81
+
82
+ r_denoised = cv2 .blur (r ,(2 ,2 ))
83
+ r_blurred = cv2 .blur (r ,(5 ,5 ))
84
+ diff = r_denoised .astype (float )- r_blurred .astype (float )
85
+ diff [diff < 0 ]= 0
86
+ diff = np .uint8 (diff )
87
+ ret , thresh = cv2 .threshold (diff ,10 ,255 ,cv2 .THRESH_BINARY )
88
+
89
+ figsize = (9 ,6 )
90
+ if bSave :
91
+ figsize = (15 , 10 )
92
+ fig , axes = plt .subplots (nrows = 2 , ncols = 4 , figsize = figsize , sharex = True , sharey = True )
93
+ ax = axes .ravel ()
94
+
95
+ # connect closer dots
96
+ kernel = np .ones ((3 ,3 ),np .uint8 )
97
+ connected = cv2 .dilate (thresh ,kernel ,iterations = 3 )
98
+ connected = np .uint8 (ndi .binary_fill_holes (connected ))* 255
99
+ kernel = np .ones ((3 ,3 ),np .uint8 )
100
+ img_erosion = cv2 .erode (connected ,kernel ,iterations = 2 )
101
+ unknown = cv2 .subtract (connected ,img_erosion )
102
+
103
+ # Marker labelling
104
+ ret , markers = cv2 .connectedComponents (connected )
105
+
106
+ # Add one to all labels so that sure background is not 0, but 1
107
+ markers = markers + 1
108
+
109
+ # Now, mark the region of unknown with zero
110
+ markers [unknown == 255 ] = 0
111
+
112
+ markers = cv2 .watershed (rgb ,markers )
113
+ rgb_seg = np .copy (rgb );
114
+ rgb_seg [markers == - 1 ] = [0 ,255 ,0 ]
115
+
116
+
117
+ #ax[0].imshow(r_denoised, cmap=plt.cm.gray)
118
+ ax [0 ].imshow (rgb )
119
+ ax [0 ].set_title ('Original Image' )
120
+ ax [1 ].imshow (r , cmap = plt .cm .gray )
121
+ ax [1 ].set_title ('Red component' )
122
+ ax [2 ].imshow (r_blurred , cmap = plt .cm .gray )
123
+ ax [2 ].set_title ('Red Blurred' )
124
+ ax [3 ].imshow (diff , cmap = plt .cm .gray )
125
+ ax [3 ].set_title ('Difference' )
126
+ ax [4 ].imshow (thresh , cmap = plt .cm .gray )
127
+ ax [4 ].set_title ('Segmentation' )
128
+ ax [5 ].imshow (connected , cmap = plt .cm .gray )
129
+ ax [5 ].set_title ('Dilation' )
130
+ ax [6 ].imshow (unknown , cmap = plt .cm .gray )
131
+ ax [6 ].set_title ('Borders' )
132
+ ax [7 ].imshow (rgb_seg )
133
+ ax [7 ].set_title ('Final Segmentation (nr Obj=' + str (ret - 1 ) + ')' )
134
+
135
+ for a in ax :
136
+ a .set_axis_off ()
137
+
138
+ fig .tight_layout ()
139
+ fig .suptitle (picname + ' - Red Dots' , fontsize = 16 )
140
+ if bSave :
141
+ plt .savefig (strSaveFilename , dpi = 300 ,pad_inches = 0.1 )
142
+ if bShow :
143
+ plt .show ()
144
+ return ret - 1
145
+
146
+ if __name__ == '__main__' :
147
+ bShow = False
148
+ bSave = True
149
+ strFolder = "Unlabelled\\ "
150
+ allValues = []
151
+ allValues .append (('Filename' ,'Num Blue Circles' ,'Num Red Dots' ))
152
+ for file in glob .glob (strFolder + "*.jpg" ):
153
+ img = cv2 .imread (file ,cv2 .IMREAD_COLOR )
154
+ numBlues = process_blue (img ,bShow ,bSave ,strSaveFilename = 'figBlue_' + file [len (strFolder ):- 4 ] + '.jpg' , picname = file [len (strFolder ):- 4 ])
155
+ numReds = process_red (img ,bShow ,bSave ,strSaveFilename = 'figRed_' + file [len (strFolder ):- 4 ] + '.jpg' , picname = file [len (strFolder ):- 4 ])
156
+ allValues .append ((file [len (strFolder ):],numBlues ,numReds ))
157
+
158
+ np .savetxt ('PLA_analysis.csv' , allValues , delimiter = "," , fmt = "%s" )
0 commit comments