李开祥 commited on
Commit
2eacc9a
1 Parent(s): 2f0b579
checkpoints/not empty.txt ADDED
File without changes
input/not empty.txt ADDED
File without changes
opencv_transform/__init__.py ADDED
File without changes
opencv_transform/annotation.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #Object annotation class:
3
+ class BodyPart:
4
+
5
+ def __init__(self, name, xmin, ymin, xmax, ymax, x, y, w, h):
6
+ self.name = name
7
+ #Bounding Box:
8
+ self.xmin = xmin
9
+ self.ymin = ymin
10
+ self.xmax = xmax
11
+ self.ymax = ymax
12
+ #Center:
13
+ self.x = x
14
+ self.y = y
15
+ #Dimensione:
16
+ self.w = w
17
+ self.h = h
opencv_transform/dress_to_correct.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import math
3
+ import numpy as np
4
+ import os
5
+
6
+ # create_correct ===============================================================
7
+ # return:
8
+ # (<Boolean> True/False), depending on the transformation process
9
+ def create_correct(cv_dress):
10
+
11
+ #Production dir:
12
+ return correct_color(cv_dress, 5)
13
+
14
+ # correct_color ==============================================================================
15
+ # return:
16
+ # <RGB> image corrected
17
+ def correct_color(img, percent):
18
+
19
+ assert img.shape[2] == 3
20
+ assert percent > 0 and percent < 100
21
+
22
+ half_percent = percent / 200.0
23
+
24
+ channels = cv2.split(img)
25
+
26
+ out_channels = []
27
+ for channel in channels:
28
+ assert len(channel.shape) == 2
29
+ # find the low and high precentile values (based on the input percentile)
30
+ height, width = channel.shape
31
+ vec_size = width * height
32
+ flat = channel.reshape(vec_size)
33
+
34
+ assert len(flat.shape) == 1
35
+
36
+ flat = np.sort(flat)
37
+
38
+ n_cols = flat.shape[0]
39
+
40
+ low_val = flat[math.floor(n_cols * half_percent)]
41
+ high_val = flat[math.ceil( n_cols * (1.0 - half_percent))]
42
+
43
+ # saturate below the low percentile and above the high percentile
44
+ thresholded = apply_threshold(channel, low_val, high_val)
45
+ # scale the channel
46
+ normalized = cv2.normalize(thresholded, thresholded.copy(), 0, 255, cv2.NORM_MINMAX)
47
+ out_channels.append(normalized)
48
+
49
+ return cv2.merge(out_channels)
50
+
51
+ #Color correction utils
52
+ def apply_threshold(matrix, low_value, high_value):
53
+ low_mask = matrix < low_value
54
+ matrix = apply_mask(matrix, low_mask, low_value)
55
+
56
+ high_mask = matrix > high_value
57
+ matrix = apply_mask(matrix, high_mask, high_value)
58
+
59
+ return matrix
60
+
61
+ #Color correction utils
62
+ def apply_mask(matrix, mask, fill_value):
63
+ masked = np.ma.array(matrix, mask=mask, fill_value=fill_value)
64
+ return masked.filled()
opencv_transform/mask_to_maskref.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import os
4
+
5
+ ###
6
+ #
7
+ # maskdet_to_maskfin
8
+ #
9
+ #
10
+ ###
11
+
12
+ # create_maskref ===============================================================
13
+ # return:
14
+ # maskref image
15
+ def create_maskref(cv_mask, cv_correct):
16
+
17
+ #Create a total green image
18
+ green = np.zeros((512,512,3), np.uint8)
19
+ green[:,:,:] = (0,255,0) # (B, G, R)
20
+
21
+ #Define the green color filter
22
+ f1 = np.asarray([0, 250, 0]) # green color filter
23
+ f2 = np.asarray([10, 255, 10])
24
+
25
+ #From mask, extrapolate only the green mask
26
+ green_mask = cv2.inRange(cv_mask, f1, f2) #green is 0
27
+
28
+ # (OPTIONAL) Apply dilate and open to mask
29
+ kernel = np.ones((5,5),np.uint8) #Try change it?
30
+ green_mask = cv2.dilate(green_mask, kernel, iterations = 1)
31
+ #green_mask = cv2.morphologyEx(green_mask, cv2.MORPH_OPEN, kernel)
32
+
33
+ # Create an inverted mask
34
+ green_mask_inv = cv2.bitwise_not(green_mask)
35
+
36
+ # Cut correct and green image, using the green_mask & green_mask_inv
37
+ res1 = cv2.bitwise_and(cv_correct, cv_correct, mask = green_mask_inv)
38
+ res2 = cv2.bitwise_and(green, green, mask = green_mask)
39
+
40
+ # Compone:
41
+ return cv2.add(res1, res2)
opencv_transform/maskdet_to_maskfin.py ADDED
@@ -0,0 +1,519 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import os
4
+ import random
5
+
6
+ #My library:
7
+ from opencv_transform.annotation import BodyPart
8
+
9
+ ###
10
+ #
11
+ # maskdet_to_maskfin
12
+ #
13
+ # steps:
14
+ # 1. Extract annotation
15
+ # 1.a: Filter by color
16
+ # 1.b: Find ellipses
17
+ # 1.c: Filter out ellipses by max size, and max total numbers
18
+ # 1.d: Detect Problems
19
+ # 1.e: Resolve the problems, or discard the transformation
20
+ # 2. With the body list, draw maskfin, using maskref
21
+ #
22
+ ###
23
+
24
+ # create_maskfin ==============================================================================
25
+ # return:
26
+ # (<Boolean> True/False), depending on the transformation process
27
+ def create_maskfin(maskref, maskdet):
28
+
29
+ #Create a total green image, in which draw details ellipses
30
+ details = np.zeros((512,512,3), np.uint8)
31
+ details[:,:,:] = (0,255,0) # (B, G, R)
32
+
33
+ #Extract body part features:
34
+ bodypart_list = extractAnnotations(maskdet);
35
+
36
+ #Check if the list is not empty:
37
+ if bodypart_list:
38
+
39
+ #Draw body part in details image:
40
+ for obj in bodypart_list:
41
+
42
+ if obj.w < obj.h:
43
+ aMax = int(obj.h/2) #asse maggiore
44
+ aMin = int(obj.w/2) #asse minore
45
+ angle = 0 #angle
46
+ else:
47
+ aMax = int(obj.w/2)
48
+ aMin = int(obj.h/2)
49
+ angle = 90
50
+
51
+ x = int(obj.x)
52
+ y = int(obj.y)
53
+
54
+ #Draw ellipse
55
+ if obj.name == "tit":
56
+ cv2.ellipse(details,(x,y),(aMax,aMin),angle,0,360,(0,205,0),-1) #(0,0,0,50)
57
+ elif obj.name == "aur":
58
+ cv2.ellipse(details,(x,y),(aMax,aMin),angle,0,360,(0,0,255),-1) #red
59
+ elif obj.name == "nip":
60
+ cv2.ellipse(details,(x,y),(aMax,aMin),angle,0,360,(255,255,255),-1) #white
61
+ elif obj.name == "belly":
62
+ cv2.ellipse(details,(x,y),(aMax,aMin),angle,0,360,(255,0,255),-1) #purple
63
+ elif obj.name == "vag":
64
+ cv2.ellipse(details,(x,y),(aMax,aMin),angle,0,360,(255,0,0),-1) #blue
65
+ elif obj.name == "hair":
66
+ xmin = x - int(obj.w/2)
67
+ ymin = y - int(obj.h/2)
68
+ xmax = x + int(obj.w/2)
69
+ ymax = y + int(obj.h/2)
70
+ cv2.rectangle(details,(xmin,ymin),(xmax,ymax),(100,100,100),-1)
71
+
72
+ #Define the green color filter
73
+ f1 = np.asarray([0, 250, 0]) # green color filter
74
+ f2 = np.asarray([10, 255, 10])
75
+
76
+ #From maskref, extrapolate only the green mask
77
+ green_mask = cv2.bitwise_not(cv2.inRange(maskref, f1, f2)) #green is 0
78
+
79
+ # Create an inverted mask
80
+ green_mask_inv = cv2.bitwise_not(green_mask)
81
+
82
+ # Cut maskref and detail image, using the green_mask & green_mask_inv
83
+ res1 = cv2.bitwise_and(maskref, maskref, mask = green_mask)
84
+ res2 = cv2.bitwise_and(details, details, mask = green_mask_inv)
85
+
86
+ # Compone:
87
+ maskfin = cv2.add(res1, res2)
88
+ return maskfin
89
+
90
+ # extractAnnotations ==============================================================================
91
+ # input parameter:
92
+ # (<string> maskdet_img): relative path of the single maskdet image (es: testimg1/maskdet/1.png)
93
+ # return:
94
+ # (<BodyPart []> bodypart_list) - for failure/error, return an empty list []
95
+ def extractAnnotations(maskdet):
96
+
97
+ #Load the image
98
+ #image = cv2.imread(maskdet_img)
99
+
100
+ #Find body part
101
+ tits_list = findBodyPart(maskdet, "tit")
102
+ aur_list = findBodyPart(maskdet, "aur")
103
+ vag_list = findBodyPart(maskdet, "vag")
104
+ belly_list = findBodyPart(maskdet, "belly")
105
+
106
+ #Filter out parts basing on dimension (area and aspect ratio):
107
+ aur_list = filterDimParts(aur_list, 100, 1000, 0.5, 3);
108
+ tits_list = filterDimParts(tits_list, 1000, 60000, 0.2, 3);
109
+ vag_list = filterDimParts(vag_list, 10, 1000, 0.2, 3);
110
+ belly_list = filterDimParts(belly_list, 10, 1000, 0.2, 3);
111
+
112
+ #Filter couple (if parts are > 2, choose only 2)
113
+ aur_list = filterCouple(aur_list);
114
+ tits_list = filterCouple(tits_list);
115
+
116
+ #Detect a missing problem:
117
+ missing_problem = detectTitAurMissingProblem(tits_list, aur_list) #return a Number (code of the problem)
118
+
119
+ #Check if problem is SOLVEABLE:
120
+ if (missing_problem in [3,6,7,8]):
121
+ resolveTitAurMissingProblems(tits_list, aur_list, missing_problem)
122
+
123
+ #Infer the nips:
124
+ nip_list = inferNip(aur_list)
125
+
126
+ #Infer the hair:
127
+ hair_list = inferHair(vag_list)
128
+
129
+ #Return a combined list:
130
+ return tits_list + aur_list + nip_list + vag_list + hair_list + belly_list
131
+
132
+ # findBodyPart ==============================================================================
133
+ # input parameters:
134
+ # (<RGB>image, <string>part_name)
135
+ # return
136
+ # (<BodyPart[]>list)
137
+ def findBodyPart(image, part_name):
138
+
139
+ bodypart_list = [] #empty BodyPart list
140
+
141
+ #Get the correct color filter:
142
+ if part_name == "tit":
143
+ #Use combined color filter
144
+ f1 = np.asarray([0, 0, 0]) # tit color filter
145
+ f2 = np.asarray([10, 10, 10])
146
+ f3 = np.asarray([0, 0, 250]) # aur color filter
147
+ f4 = np.asarray([0, 0, 255])
148
+ color_mask1 = cv2.inRange(image, f1, f2)
149
+ color_mask2 = cv2.inRange(image, f3, f4)
150
+ color_mask = cv2.bitwise_or(color_mask1, color_mask2) #combine
151
+
152
+ elif part_name == "aur":
153
+ f1 = np.asarray([0, 0, 250]) # aur color filter
154
+ f2 = np.asarray([0, 0, 255])
155
+ color_mask = cv2.inRange(image, f1, f2)
156
+
157
+ elif part_name == "vag":
158
+ f1 = np.asarray([250, 0, 0]) # vag filter
159
+ f2 = np.asarray([255, 0, 0])
160
+ color_mask = cv2.inRange(image, f1, f2)
161
+
162
+ elif part_name == "belly":
163
+ f1 = np.asarray([250, 0, 250]) # belly filter
164
+ f2 = np.asarray([255, 0, 255])
165
+ color_mask = cv2.inRange(image, f1, f2)
166
+
167
+ #find contours:
168
+ contours, hierarchy = cv2.findContours(color_mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
169
+
170
+ #for every contour:
171
+ for cnt in contours:
172
+
173
+ if len(cnt)>5: #at least 5 points to fit ellipse
174
+
175
+ #(x, y), (MA, ma), angle = cv2.fitEllipse(cnt)
176
+ ellipse = cv2.fitEllipse(cnt)
177
+
178
+ #Fit Result:
179
+ x = ellipse[0][0] #center x
180
+ y = ellipse[0][1] #center y
181
+ angle = ellipse[2] #angle
182
+ aMin = ellipse[1][0]; #asse minore
183
+ aMax = ellipse[1][1]; #asse maggiore
184
+
185
+ #Detect direction:
186
+ if angle == 0:
187
+ h = aMax
188
+ w = aMin
189
+ else:
190
+ h = aMin
191
+ w = aMax
192
+
193
+ #Normalize the belly size:
194
+ if part_name == "belly":
195
+ if w<15:
196
+ w *= 2
197
+ if h<15:
198
+ h *= 2
199
+
200
+ #Normalize the vag size:
201
+ if part_name == "vag":
202
+ if w<15:
203
+ w *= 2
204
+ if h<15:
205
+ h *= 2
206
+
207
+ #Calculate Bounding Box:
208
+ xmin = int(x - (w/2))
209
+ xmax = int(x + (w/2))
210
+ ymin = int(y - (h/2))
211
+ ymax = int(y + (h/2))
212
+
213
+ bodypart_list.append(BodyPart(part_name, xmin, ymin, xmax, ymax, x, y, w, h ))
214
+
215
+ return bodypart_list
216
+
217
+ # filterDimParts ==============================================================================
218
+ # input parameters:
219
+ # (<BodyPart[]>list, <num> minimum area of part, <num> max area, <num> min aspect ratio, <num> max aspect ratio)
220
+ def filterDimParts(bp_list, min_area, max_area, min_ar, max_ar):
221
+
222
+ b_filt = []
223
+
224
+ for obj in bp_list:
225
+
226
+ a = obj.w*obj.h #Object AREA
227
+
228
+ if ((a > min_area)and(a < max_area)):
229
+
230
+ ar = obj.w/obj.h #Object ASPECT RATIO
231
+
232
+ if ((ar>min_ar)and(ar<max_ar)):
233
+
234
+ b_filt.append(obj)
235
+
236
+ return b_filt
237
+
238
+ # filterCouple ==============================================================================
239
+ # input parameters:
240
+ # (<BodyPart[]>list)
241
+ def filterCouple(bp_list):
242
+
243
+ #Remove exceed parts
244
+ if (len(bp_list)>2):
245
+
246
+ #trovare coppia (a,b) che minimizza bp_list[a].y-bp_list[b].y
247
+ min_a = 0
248
+ min_b = 1
249
+ min_diff = abs(bp_list[min_a].y-bp_list[min_b].y)
250
+
251
+ for a in range(0,len(bp_list)):
252
+ for b in range(0,len(bp_list)):
253
+ #TODO: avoid repetition (1,0) (0,1)
254
+ if a != b:
255
+ diff = abs(bp_list[a].y-bp_list[b].y)
256
+ if diff<min_diff:
257
+ min_diff = diff
258
+ min_a = a
259
+ min_b = b
260
+ b_filt = []
261
+
262
+ b_filt.append(bp_list[min_a])
263
+ b_filt.append(bp_list[min_b])
264
+
265
+ return b_filt
266
+ else:
267
+ #No change
268
+ return bp_list
269
+
270
+
271
+
272
+ # detectTitAurMissingProblem ==============================================================================
273
+ # input parameters:
274
+ # (<BodyPart[]> tits list, <BodyPart[]> aur list)
275
+ # return
276
+ # (<num> problem code)
277
+ # TIT | AUR | code | SOLVE? |
278
+ # 0 | 0 | 1 | NO |
279
+ # 0 | 1 | 2 | NO |
280
+ # 0 | 2 | 3 | YES |
281
+ # 1 | 0 | 4 | NO |
282
+ # 1 | 1 | 5 | NO |
283
+ # 1 | 2 | 6 | YES |
284
+ # 2 | 0 | 7 | YES |
285
+ # 2 | 1 | 8 | YES |
286
+ def detectTitAurMissingProblem(tits_list, aur_list):
287
+
288
+ t_len = len(tits_list)
289
+ a_len = len(aur_list)
290
+
291
+ if (t_len == 0):
292
+ if (a_len == 0):
293
+ return 1
294
+ elif (a_len == 1):
295
+ return 2
296
+ elif (a_len == 2):
297
+ return 3
298
+ else:
299
+ return -1
300
+ elif (t_len == 1):
301
+ if (a_len == 0):
302
+ return 4
303
+ elif (a_len == 1):
304
+ return 5
305
+ elif (a_len == 2):
306
+ return 6
307
+ else:
308
+ return -1
309
+ elif (t_len == 2):
310
+ if (a_len == 0):
311
+ return 7
312
+ elif (a_len == 1):
313
+ return 8
314
+ else:
315
+ return -1
316
+ else:
317
+ return -1
318
+
319
+ # resolveTitAurMissingProblems ==============================================================================
320
+ # input parameters:
321
+ # (<BodyPart[]> tits list, <BodyPart[]> aur list, problem code)
322
+ # return
323
+ # none
324
+ def resolveTitAurMissingProblems(tits_list, aur_list, problem_code):
325
+
326
+ if problem_code == 3:
327
+
328
+ random_tit_factor = random.randint(2, 5) #TOTEST
329
+
330
+ #Add the first tit:
331
+ new_w = aur_list[0].w * random_tit_factor #TOTEST
332
+ new_x = aur_list[0].x
333
+ new_y = aur_list[0].y
334
+
335
+ xmin = int(new_x - (new_w/2))
336
+ xmax = int(new_x + (new_w/2))
337
+ ymin = int(new_y - (new_w/2))
338
+ ymax = int(new_y + (new_w/2))
339
+
340
+ tits_list.append(BodyPart("tit", xmin, ymin, xmax, ymax, new_x, new_y, new_w, new_w ))
341
+
342
+ #Add the second tit:
343
+ new_w = aur_list[1].w * random_tit_factor #TOTEST
344
+ new_x = aur_list[1].x
345
+ new_y = aur_list[1].y
346
+
347
+ xmin = int(new_x - (new_w/2))
348
+ xmax = int(new_x + (new_w/2))
349
+ ymin = int(new_y - (new_w/2))
350
+ ymax = int(new_y + (new_w/2))
351
+
352
+ tits_list.append(BodyPart("tit", xmin, ymin, xmax, ymax, new_x, new_y, new_w, new_w ))
353
+
354
+ elif problem_code == 6:
355
+
356
+ #Find wich aur is full:
357
+ d1 = abs(tits_list[0].x - aur_list[0].x)
358
+ d2 = abs(tits_list[0].x - aur_list[1].x)
359
+
360
+ if d1 > d2:
361
+ #aur[0] is empty
362
+ new_x = aur_list[0].x
363
+ new_y = aur_list[0].y
364
+ else:
365
+ #aur[1] is empty
366
+ new_x = aur_list[1].x
367
+ new_y = aur_list[1].y
368
+
369
+ #Calculate Bounding Box:
370
+ xmin = int(new_x - (tits_list[0].w/2))
371
+ xmax = int(new_x + (tits_list[0].w/2))
372
+ ymin = int(new_y - (tits_list[0].w/2))
373
+ ymax = int(new_y + (tits_list[0].w/2))
374
+
375
+ tits_list.append(BodyPart("tit", xmin, ymin, xmax, ymax, new_x, new_y, tits_list[0].w, tits_list[0].w ))
376
+
377
+ elif problem_code == 7:
378
+
379
+ #Add the first aur:
380
+ new_w = tits_list[0].w * random.uniform(0.03, 0.1) #TOTEST
381
+ new_x = tits_list[0].x
382
+ new_y = tits_list[0].y
383
+
384
+ xmin = int(new_x - (new_w/2))
385
+ xmax = int(new_x + (new_w/2))
386
+ ymin = int(new_y - (new_w/2))
387
+ ymax = int(new_y + (new_w/2))
388
+
389
+ aur_list.append(BodyPart("aur", xmin, ymin, xmax, ymax, new_x, new_y, new_w, new_w ))
390
+
391
+ #Add the second aur:
392
+ new_w = tits_list[1].w * random.uniform(0.03, 0.1) #TOTEST
393
+ new_x = tits_list[1].x
394
+ new_y = tits_list[1].y
395
+
396
+ xmin = int(new_x - (new_w/2))
397
+ xmax = int(new_x + (new_w/2))
398
+ ymin = int(new_y - (new_w/2))
399
+ ymax = int(new_y + (new_w/2))
400
+
401
+ aur_list.append(BodyPart("aur", xmin, ymin, xmax, ymax, new_x, new_y, new_w, new_w ))
402
+
403
+ elif problem_code == 8:
404
+
405
+ #Find wich tit is full:
406
+ d1 = abs(aur_list[0].x - tits_list[0].x)
407
+ d2 = abs(aur_list[0].x - tits_list[1].x)
408
+
409
+ if d1 > d2:
410
+ #tit[0] is empty
411
+ new_x = tits_list[0].x
412
+ new_y = tits_list[0].y
413
+ else:
414
+ #tit[1] is empty
415
+ new_x = tits_list[1].x
416
+ new_y = tits_list[1].y
417
+
418
+ #Calculate Bounding Box:
419
+ xmin = int(new_x - (aur_list[0].w/2))
420
+ xmax = int(new_x + (aur_list[0].w/2))
421
+ ymin = int(new_y - (aur_list[0].w/2))
422
+ ymax = int(new_y + (aur_list[0].w/2))
423
+ aur_list.append(BodyPart("aur", xmin, ymin, xmax, ymax, new_x, new_y, aur_list[0].w, aur_list[0].w ))
424
+
425
+ # detectTitAurPositionProblem ==============================================================================
426
+ # input parameters:
427
+ # (<BodyPart[]> tits list, <BodyPart[]> aur list)
428
+ # return
429
+ # (<Boolean> True/False)
430
+ def detectTitAurPositionProblem(tits_list, aur_list):
431
+
432
+ diffTitsX = abs(tits_list[0].x - tits_list[1].x)
433
+ if diffTitsX < 40:
434
+ print("diffTitsX")
435
+ #Tits too narrow (orizontally)
436
+ return True
437
+
438
+ diffTitsY = abs(tits_list[0].y - tits_list[1].y)
439
+ if diffTitsY > 120:
440
+ #Tits too distanced (vertically)
441
+ print("diffTitsY")
442
+ return True
443
+
444
+ diffTitsW = abs(tits_list[0].w - tits_list[1].w)
445
+ if ((diffTitsW < 0.1)or(diffTitsW>60)):
446
+ print("diffTitsW")
447
+ #Tits too equals, or too different (width)
448
+ return True
449
+
450
+ #Check if body position is too low (face not covered by watermark)
451
+ if aur_list[0].y > 350: #tits too low
452
+ #Calculate the ratio between y and aurs distance
453
+ rapp = aur_list[0].y/(abs(aur_list[0].x - aur_list[1].x))
454
+ if rapp > 2.8:
455
+ print("aurDown")
456
+ return True
457
+
458
+ return False
459
+
460
+ # inferNip ==============================================================================
461
+ # input parameters:
462
+ # (<BodyPart[]> aur list)
463
+ # return
464
+ # (<BodyPart[]> nip list)
465
+ def inferNip(aur_list):
466
+ nip_list = []
467
+
468
+ for aur in aur_list:
469
+
470
+ #Nip rules:
471
+ # - circle (w == h)
472
+ # - min dim: 5
473
+ # - bigger if aur is bigger
474
+ nip_dim = int(5 + aur.w*random.uniform(0.03, 0.09))
475
+
476
+ #center:
477
+ x = aur.x
478
+ y = aur.y
479
+
480
+ #Calculate Bounding Box:
481
+ xmin = int(x - (nip_dim/2))
482
+ xmax = int(x + (nip_dim/2))
483
+ ymin = int(y - (nip_dim/2))
484
+ ymax = int(y + (nip_dim/2))
485
+
486
+ nip_list.append(BodyPart("nip", xmin, ymin, xmax, ymax, x, y, nip_dim, nip_dim ))
487
+
488
+ return nip_list
489
+
490
+ # inferHair (TOTEST) ==============================================================================
491
+ # input parameters:
492
+ # (<BodyPart[]> vag list)
493
+ # return
494
+ # (<BodyPart[]> hair list)
495
+ def inferHair(vag_list):
496
+ hair_list = []
497
+
498
+ #70% of chanche to add hair
499
+ if random.uniform(0.0, 1.0) > 0.3:
500
+
501
+ for vag in vag_list:
502
+
503
+ #Hair rules:
504
+ hair_w = vag.w*random.uniform(0.4, 1.5)
505
+ hair_h = vag.h*random.uniform(0.4, 1.5)
506
+
507
+ #center:
508
+ x = vag.x
509
+ y = vag.y - (hair_h/2) - (vag.h/2)
510
+
511
+ #Calculate Bounding Box:
512
+ xmin = int(x - (hair_w/2))
513
+ xmax = int(x + (hair_w/2))
514
+ ymin = int(y - (hair_h/2))
515
+ ymax = int(y + (hair_h/2))
516
+
517
+ hair_list.append(BodyPart("hair", xmin, ymin, xmax, ymax, x, y, hair_w, hair_h ))
518
+
519
+ return hair_list
opencv_transform/nude_to_watermark.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import os
4
+
5
+ # create_watermark ===============================================================
6
+ # return:
7
+ # (<Boolean> True/False), depending on the transformation process
8
+ def create_watermark(nude):
9
+
10
+ # Add alpha channel if missing
11
+ # if nude.shape[2] < 4:
12
+ # nude = np.dstack([nude, np.ones((512, 512), dtype="uint8") * 255])
13
+
14
+ # watermark = cv2.imread("fake.png", cv2.IMREAD_UNCHANGED)
15
+
16
+ # f1 = np.asarray([0, 0, 0, 250]) # red color filter
17
+ # f2 = np.asarray([255, 255, 255, 255])
18
+ # mask = cv2.bitwise_not(cv2.inRange(watermark, f1, f2))
19
+ # mask_inv = cv2.bitwise_not(mask)
20
+
21
+ # res1 = cv2.bitwise_and(nude, nude, mask = mask)
22
+ # # res2 = cv2.bitwise_and(nude, nude, mask = mask)
23
+ # # res2 = cv2.bitwise_and(watermark, watermark, mask = mask_inv)
24
+ # res = res1
25
+
26
+ # alpha = 0.6
27
+ # return cv2.addWeighted(res, alpha, nude, 1 - alpha, 0)
28
+ return nude