-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.py
217 lines (182 loc) · 8.11 KB
/
util.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import os
import cv2
import numpy as np
from os.path import join, split
import random
def convert(size, box):
dw = 1. / (size[0])
dh = 1. / (size[1])
x = (box[0] + box[1]) / 2.0 - 1
y = (box[2] + box[3]) / 2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = round(x * dw, 6)
w = round(w * dw, 6)
y = round(y * dh, 6)
h = round(h * dh, 6)
return (x, y, w, h)
def issmallobject(bbox, thresh):
if bbox[0] * bbox[1] <= thresh:
return True
else:
return False
def read_label_txt(label_dir):
labels = []
with open(label_dir) as fp:
for f in fp.readlines():
labels.append(f.strip().split(' '))
return labels
def load_txt_label(label_dir):
return np.loadtxt(label_dir, dtype=str)
def load_txt_labels(label_dir):
labels = []
for l in label_dir:
la = load_txt_label(l)
labels.append(la)
return labels
def check_dir(dir):
if not os.path.exists(dir):
os.makedirs(dir)
def rescale_yolo_labels(labels, img_shape): # 将原图像对应的标签进行一个复原,因为提供的这种是基于归一化的coco数据集的格式,所以要复原!
height, width, nchannel = img_shape
rescale_boxes = []
for box in list(labels):
x_c = float(box[1]) * width
y_c = float(box[2]) * height
w = float(box[3]) * width
h = float(box[4]) * height
x_left = x_c - w * .5
y_left = y_c - h * .5
x_right = x_c + w * .5
y_right = y_c + h * .5
rescale_boxes.append([box[0], int(x_left), int(y_left), int(x_right), int(y_right)])
return rescale_boxes
def draw_annotation_to_image(img, annotation, save_img_dir):
for anno in annotation:
cl, x1, y1, x2, y2 = anno
cv2.rectangle(img, pt1=(x1, y1), pt2=(x2, y2), color=(255, 0, 0))
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, cl, (int((x1 + x2) / 2), y1 - 5), font, fontScale=0.8, color=(0, 0, 255))
cv2.imwrite(save_img_dir, img)
def bbox_iou(box1, box2):
cl, b1_x1, b1_y1, b1_x2, b1_y2 = box1
cl, b2_x1, b2_y1, b2_x2, b2_y2 = box2
# get the corrdinates of the intersection rectangle
inter_rect_x1 = max(b1_x1, b2_x1)
inter_rect_y1 = max(b1_y1, b2_y1)
inter_rect_x2 = min(b1_x2, b2_x2)
inter_rect_y2 = min(b1_y2, b2_y2)
# Intersection area
inter_width = inter_rect_x2 - inter_rect_x1 + 1
inter_height = inter_rect_y2 - inter_rect_y1 + 1
if inter_width > 0 and inter_height > 0: # strong condition
inter_area = inter_width * inter_height
# Union Area
b1_area = (b1_x2 - b1_x1 + 1) * (b1_y2 - b1_y1 + 1)
b2_area = (b2_x2 - b2_x1 + 1) * (b2_y2 - b2_y1 + 1)
iou = inter_area / (b1_area + b2_area - inter_area) # 如果重叠的宽度和高度都大于0,则计算IOU;
else:
iou = 0
return iou
def swap(x1, x2):
if (x1 > x2):
temp = x1
x1 = x2
x2 = temp
return x1, x2
def norm_sampling(search_space):
# 随机生成点
search_x_left, search_y_left, search_x_right, search_y_right = search_space
new_bbox_x_center = random.randint(int(search_x_left), int(search_x_right)) # 这种分布小数也可以!
new_bbox_y_center = random.randint(int(search_y_left), int(search_y_right))
return [new_bbox_x_center, new_bbox_y_center]
def flip_bbox(roi):
roi_flip = roi[:, ::-1, :]
return roi_flip
def sampling_new_bbox_center_point(img_shape, bbox):
#### sampling space ####
height, width, nc = img_shape
cl, x_left, y_left, x_right, y_right = bbox
bbox_w, bbox_h = x_right - x_left, y_right - y_left
### left top ###
if x_left <= width / 2:
search_x_left, search_y_left, search_x_right, search_y_right = width * 0.6, height / 2, width * 0.75, height * 0.75
if x_left > width / 2:
search_x_left, search_y_left, search_x_right, search_y_right = width * 0.25, height / 2, width * 0.5, height * 0.75
return [search_x_left, search_y_left, search_x_right, search_y_right]
def random_add_patches(bbox, rescale_boxes, shape, paste_number, iou_thresh):
temp = []
for rescale_bbox in rescale_boxes:
temp.append(rescale_bbox)
cl, x_left, y_left, x_right, y_right = bbox
bbox_w, bbox_h = x_right - x_left, y_right - y_left
center_search_space = sampling_new_bbox_center_point(shape, bbox)
success_num = 0
new_bboxes = []
while success_num < paste_number:
new_bbox_x_center, new_bbox_y_center = norm_sampling(center_search_space)
print(norm_sampling(center_search_space))
new_bbox_x_left, new_bbox_y_left, new_bbox_x_right, new_bbox_y_right = new_bbox_x_center - 0.5 * bbox_w, \
new_bbox_y_center - 0.5 * bbox_h, \
new_bbox_x_center + 0.5 * bbox_w, \
new_bbox_y_center + 0.5 * bbox_h
new_bbox = [cl, int(new_bbox_x_left), int(new_bbox_y_left), int(new_bbox_x_right), int(new_bbox_y_right)]
ious = [bbox_iou(new_bbox, bbox_t) for bbox_t in rescale_boxes] # rescale_boxes 是原图像中的标签在原图像中的边界框;
if max(ious) <= iou_thresh:
# for bbox_t in rescale_boxes:
# iou = bbox_iou(new_bbox[1:],bbox_t[1:])
# if(iou <= iou_thresh):
success_num += 1
temp.append(new_bbox)
new_bboxes.append(new_bbox)
else:
continue
return new_bboxes
def sampling_new_bbox_center_point2(img_shape, bbox):
#### sampling space ####
height, width, nc = img_shape
bbox_h, bbox_w, bbox_c = bbox
### left top ###
'''
search_x_left, search_y_left, search_x_right, search_y_right = width * 0.55 , height * 0.5 , \
width * 0.9 , height * 0.95
'''
search_x_left, search_y_left, search_x_right, search_y_right = width * 0.05 , height * 0.05 , \
width * 0.95 , height * 0.95
return [search_x_left, search_y_left, search_x_right, search_y_right]
def random_add_patches2(bbox_img, rescale_boxes, image_label, shape, iou_thresh):
temp = []
for rescale_bbox in rescale_boxes:
temp.append(rescale_bbox)
if len(temp) <= 15:
paste_number = 2
else:
paste_number = 1
bbox_h, bbox_w, bbox_c = bbox_img
img_h, img_w, img_c = shape
center_search_space = sampling_new_bbox_center_point2(shape, bbox_img) # 选取生成随机点区域,这个函数可以改进,选择不同的粘贴区域。
success_num = 0
new_bboxes = []
cl = image_label
while success_num < paste_number:
new_bbox_x_center, new_bbox_y_center = norm_sampling(center_search_space) # 随机生成中心点坐标
if new_bbox_x_center-0.5*bbox_w < 0 or new_bbox_x_center+0.5*bbox_w > img_w:
continue
if new_bbox_y_center-0.5*bbox_h < 0 or new_bbox_y_center+0.5*bbox_h > img_h:
continue
new_bbox_x_left, new_bbox_y_left, new_bbox_x_right, new_bbox_y_right = new_bbox_x_center - 0.5 * bbox_w, \
new_bbox_y_center - 0.5 * bbox_h, \
new_bbox_x_center + 0.5 * bbox_w, \
new_bbox_y_center + 0.5 * bbox_h
new_bbox = [cl, int(new_bbox_x_left), int(new_bbox_y_left), int(new_bbox_x_right), int(new_bbox_y_right)] # 框里已经包含了对应要粘贴的图片;
ious = [bbox_iou(new_bbox, bbox_t) for bbox_t in rescale_boxes]
ious2 = [bbox_iou(new_bbox,bbox_t1) for bbox_t1 in new_bboxes]
if ious2 == []:
ious2.append(0)
if max(ious) <= iou_thresh and max(ious2) <= iou_thresh:
success_num += 1
temp.append(new_bbox)
new_bboxes.append(new_bbox)
else:
continue
return new_bboxes