|
| 1 | +import os |
| 2 | +from xml.dom.minidom import Document |
| 3 | +import numpy as np |
| 4 | +import copy |
| 5 | +import cv2 |
| 6 | +import sys |
| 7 | +sys.path.append('../../..') |
| 8 | + |
| 9 | +from help_utils.tools import mkdir |
| 10 | +from libs.box_utils.coordinate_convert import backward_convert |
| 11 | + |
| 12 | + |
| 13 | +def save_to_xml(save_path, im_height, im_width, objects_axis, label_name): |
| 14 | + im_depth = 0 |
| 15 | + object_num = len(objects_axis) |
| 16 | + doc = Document() |
| 17 | + |
| 18 | + annotation = doc.createElement('annotation') |
| 19 | + doc.appendChild(annotation) |
| 20 | + |
| 21 | + folder = doc.createElement('folder') |
| 22 | + folder_name = doc.createTextNode('VOC2007') |
| 23 | + folder.appendChild(folder_name) |
| 24 | + annotation.appendChild(folder) |
| 25 | + |
| 26 | + filename = doc.createElement('filename') |
| 27 | + filename_name = doc.createTextNode('000024.jpg') |
| 28 | + filename.appendChild(filename_name) |
| 29 | + annotation.appendChild(filename) |
| 30 | + |
| 31 | + source = doc.createElement('source') |
| 32 | + annotation.appendChild(source) |
| 33 | + |
| 34 | + database = doc.createElement('database') |
| 35 | + database.appendChild(doc.createTextNode('The VOC2007 Database')) |
| 36 | + source.appendChild(database) |
| 37 | + |
| 38 | + annotation_s = doc.createElement('annotation') |
| 39 | + annotation_s.appendChild(doc.createTextNode('PASCAL VOC2007')) |
| 40 | + source.appendChild(annotation_s) |
| 41 | + |
| 42 | + image = doc.createElement('image') |
| 43 | + image.appendChild(doc.createTextNode('flickr')) |
| 44 | + source.appendChild(image) |
| 45 | + |
| 46 | + flickrid = doc.createElement('flickrid') |
| 47 | + flickrid.appendChild(doc.createTextNode('322409915')) |
| 48 | + source.appendChild(flickrid) |
| 49 | + |
| 50 | + owner = doc.createElement('owner') |
| 51 | + annotation.appendChild(owner) |
| 52 | + |
| 53 | + flickrid_o = doc.createElement('flickrid') |
| 54 | + flickrid_o.appendChild(doc.createTextNode('knautia')) |
| 55 | + owner.appendChild(flickrid_o) |
| 56 | + |
| 57 | + name_o = doc.createElement('name') |
| 58 | + name_o.appendChild(doc.createTextNode('yang')) |
| 59 | + owner.appendChild(name_o) |
| 60 | + |
| 61 | + size = doc.createElement('size') |
| 62 | + annotation.appendChild(size) |
| 63 | + width = doc.createElement('width') |
| 64 | + width.appendChild(doc.createTextNode(str(im_width))) |
| 65 | + height = doc.createElement('height') |
| 66 | + height.appendChild(doc.createTextNode(str(im_height))) |
| 67 | + depth = doc.createElement('depth') |
| 68 | + depth.appendChild(doc.createTextNode(str(im_depth))) |
| 69 | + size.appendChild(width) |
| 70 | + size.appendChild(height) |
| 71 | + size.appendChild(depth) |
| 72 | + segmented = doc.createElement('segmented') |
| 73 | + segmented.appendChild(doc.createTextNode('0')) |
| 74 | + annotation.appendChild(segmented) |
| 75 | + for i in range(object_num): |
| 76 | + objects = doc.createElement('object') |
| 77 | + annotation.appendChild(objects) |
| 78 | + object_name = doc.createElement('name') |
| 79 | + object_name.appendChild(doc.createTextNode(label_name[int(objects_axis[i][-1])])) |
| 80 | + objects.appendChild(object_name) |
| 81 | + pose = doc.createElement('pose') |
| 82 | + pose.appendChild(doc.createTextNode('Unspecified')) |
| 83 | + objects.appendChild(pose) |
| 84 | + truncated = doc.createElement('truncated') |
| 85 | + truncated.appendChild(doc.createTextNode('1')) |
| 86 | + objects.appendChild(truncated) |
| 87 | + difficult = doc.createElement('difficult') |
| 88 | + difficult.appendChild(doc.createTextNode('0')) |
| 89 | + objects.appendChild(difficult) |
| 90 | + bndbox = doc.createElement('bndbox') |
| 91 | + objects.appendChild(bndbox) |
| 92 | + |
| 93 | + x0 = doc.createElement('x0') |
| 94 | + x0.appendChild(doc.createTextNode(str((objects_axis[i][0])))) |
| 95 | + bndbox.appendChild(x0) |
| 96 | + y0 = doc.createElement('y0') |
| 97 | + y0.appendChild(doc.createTextNode(str((objects_axis[i][1])))) |
| 98 | + bndbox.appendChild(y0) |
| 99 | + |
| 100 | + x1 = doc.createElement('x1') |
| 101 | + x1.appendChild(doc.createTextNode(str((objects_axis[i][2])))) |
| 102 | + bndbox.appendChild(x1) |
| 103 | + y1 = doc.createElement('y1') |
| 104 | + y1.appendChild(doc.createTextNode(str((objects_axis[i][3])))) |
| 105 | + bndbox.appendChild(y1) |
| 106 | + |
| 107 | + x2 = doc.createElement('x2') |
| 108 | + x2.appendChild(doc.createTextNode(str((objects_axis[i][4])))) |
| 109 | + bndbox.appendChild(x2) |
| 110 | + y2 = doc.createElement('y2') |
| 111 | + y2.appendChild(doc.createTextNode(str((objects_axis[i][5])))) |
| 112 | + bndbox.appendChild(y2) |
| 113 | + |
| 114 | + x3 = doc.createElement('x3') |
| 115 | + x3.appendChild(doc.createTextNode(str((objects_axis[i][6])))) |
| 116 | + bndbox.appendChild(x3) |
| 117 | + y3 = doc.createElement('y3') |
| 118 | + y3.appendChild(doc.createTextNode(str((objects_axis[i][7])))) |
| 119 | + bndbox.appendChild(y3) |
| 120 | + |
| 121 | + f = open(save_path, 'w') |
| 122 | + f.write(doc.toprettyxml(indent='')) |
| 123 | + f.close() |
| 124 | + |
| 125 | + |
| 126 | +class_list = ['plane', 'baseball-diamond', 'bridge', 'ground-track-field', |
| 127 | + 'small-vehicle', 'large-vehicle', 'ship', |
| 128 | + 'tennis-court', 'basketball-court', |
| 129 | + 'storage-tank', 'soccer-ball-field', |
| 130 | + 'roundabout', 'harbor', |
| 131 | + 'swimming-pool', 'helicopter', 'container-crane'] |
| 132 | + |
| 133 | + |
| 134 | +def format_label(txt_list): |
| 135 | + format_data = [] |
| 136 | + for i in txt_list: |
| 137 | + if len(i.split(' ')) < 9: |
| 138 | + continue |
| 139 | + format_data.append( |
| 140 | + [float(xy) for xy in i.split(' ')[:8]] + [class_list.index(i.split(' ')[8])] |
| 141 | + ) |
| 142 | + |
| 143 | + if i.split(' ')[8] not in class_list: |
| 144 | + print('warning found a new label :', i.split(' ')[8]) |
| 145 | + exit() |
| 146 | + return np.array(format_data) |
| 147 | + |
| 148 | + |
| 149 | +def clip_image(file_idx, image, boxes_all, width, height, stride_w, stride_h): |
| 150 | + min_pixel = 5 |
| 151 | + print(file_idx) |
| 152 | + boxes_all_5 = backward_convert(boxes_all[:, :8], False) |
| 153 | + print(boxes_all[np.logical_or(boxes_all_5[:, 2] <= min_pixel, boxes_all_5[:, 3] <= min_pixel), :]) |
| 154 | + boxes_all = boxes_all[np.logical_and(boxes_all_5[:, 2] > min_pixel, boxes_all_5[:, 3] > min_pixel), :] |
| 155 | + |
| 156 | + if boxes_all.shape[0] > 0: |
| 157 | + shape = image.shape |
| 158 | + for start_h in range(0, shape[0], stride_h): |
| 159 | + for start_w in range(0, shape[1], stride_w): |
| 160 | + boxes = copy.deepcopy(boxes_all) |
| 161 | + box = np.zeros_like(boxes_all) |
| 162 | + start_h_new = start_h |
| 163 | + start_w_new = start_w |
| 164 | + if start_h + height > shape[0]: |
| 165 | + start_h_new = shape[0] - height |
| 166 | + if start_w + width > shape[1]: |
| 167 | + start_w_new = shape[1] - width |
| 168 | + top_left_row = max(start_h_new, 0) |
| 169 | + top_left_col = max(start_w_new, 0) |
| 170 | + bottom_right_row = min(start_h + height, shape[0]) |
| 171 | + bottom_right_col = min(start_w + width, shape[1]) |
| 172 | + |
| 173 | + subImage = image[top_left_row:bottom_right_row, top_left_col: bottom_right_col] |
| 174 | + |
| 175 | + box[:, 0] = boxes[:, 0] - top_left_col |
| 176 | + box[:, 2] = boxes[:, 2] - top_left_col |
| 177 | + box[:, 4] = boxes[:, 4] - top_left_col |
| 178 | + box[:, 6] = boxes[:, 6] - top_left_col |
| 179 | + |
| 180 | + box[:, 1] = boxes[:, 1] - top_left_row |
| 181 | + box[:, 3] = boxes[:, 3] - top_left_row |
| 182 | + box[:, 5] = boxes[:, 5] - top_left_row |
| 183 | + box[:, 7] = boxes[:, 7] - top_left_row |
| 184 | + box[:, 8] = boxes[:, 8] |
| 185 | + center_y = 0.25 * (box[:, 1] + box[:, 3] + box[:, 5] + box[:, 7]) |
| 186 | + center_x = 0.25 * (box[:, 0] + box[:, 2] + box[:, 4] + box[:, 6]) |
| 187 | + |
| 188 | + cond1 = np.intersect1d(np.where(center_y[:] >= 0)[0], np.where(center_x[:] >= 0)[0]) |
| 189 | + cond2 = np.intersect1d(np.where(center_y[:] <= (bottom_right_row - top_left_row))[0], |
| 190 | + np.where(center_x[:] <= (bottom_right_col - top_left_col))[0]) |
| 191 | + idx = np.intersect1d(cond1, cond2) |
| 192 | + if len(idx) > 0 and (subImage.shape[0] > 5 and subImage.shape[1] > 5): |
| 193 | + mkdir(os.path.join(save_dir, 'images')) |
| 194 | + img = os.path.join(save_dir, 'images', |
| 195 | + "%s_%04d_%04d.png" % (file_idx, top_left_row, top_left_col)) |
| 196 | + cv2.imwrite(img, subImage) |
| 197 | + |
| 198 | + mkdir(os.path.join(save_dir, 'labeltxt')) |
| 199 | + xml = os.path.join(save_dir, 'labeltxt', |
| 200 | + "%s_%04d_%04d.xml" % (file_idx, top_left_row, top_left_col)) |
| 201 | + save_to_xml(xml, subImage.shape[0], subImage.shape[1], box[idx, :], class_list) |
| 202 | + |
| 203 | + |
| 204 | +print('class_list', len(class_list)) |
| 205 | +raw_data = '/data/yangxue/dataset/DOTA/val/' |
| 206 | +raw_images_dir = os.path.join(raw_data, 'images', 'images') |
| 207 | +raw_label_dir = os.path.join(raw_data, 'labelTxt', 'labelTxt') |
| 208 | + |
| 209 | +save_dir = '/data/yangxue/dataset/DOTA/DOTA1.0/trainval/' |
| 210 | + |
| 211 | +images = [i for i in os.listdir(raw_images_dir) if 'png' in i] |
| 212 | +labels = [i for i in os.listdir(raw_label_dir) if 'txt' in i] |
| 213 | + |
| 214 | +print('find image', len(images)) |
| 215 | +print('find label', len(labels)) |
| 216 | + |
| 217 | +min_length = 1e10 |
| 218 | +max_length = 1 |
| 219 | + |
| 220 | +img_h, img_w, stride_h, stride_w = 600, 600, 450, 450 |
| 221 | + |
| 222 | +for idx, img in enumerate(images): |
| 223 | + print(idx, 'read image', img) |
| 224 | + img_data = cv2.imread(os.path.join(raw_images_dir, img)) |
| 225 | + |
| 226 | + txt_data = open(os.path.join(raw_label_dir, img.replace('png', 'txt')), 'r').readlines() |
| 227 | + box = format_label(txt_data) |
| 228 | + |
| 229 | + if box.shape[0] > 0: |
| 230 | + clip_image(img.strip('.png'), img_data, box, img_w, img_h, stride_w, stride_h) |
0 commit comments