def array_to_image(arr): # need to return old values to avoid python freeing memory arr = arr.transpose(2, 0, 1) c, h, w = arr.shape[0:3] arr = np.ascontiguousarray(arr.flat, dtype=np.float32) / 255.0 data = arr.ctypes.data_as(dn.POINTER(dn.c_float)) im = dn.IMAGE(w, h, c, data) return im, arr
def detect2(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45): boxes = dn.make_boxes(net) probs = dn.make_probs(net) num = dn.num_boxes(net) dn.network_detect(net, image, thresh, hier_thresh, nms, boxes, probs) res = [] for j in range(num): for i in range(meta.classes): if probs[j][i] > 0: res.append((meta.names[i], probs[j][i], (boxes[j].x, boxes[j].y, boxes[j].w, boxes[j].h))) res = sorted(res, key=lambda x: -x[1]) dn.free_ptrs(dn.cast(probs, dn.POINTER(dn.c_void_p)), num) return res
def detect(self, img, thresh=0.1, hier_thresh=.5, nms=.45): img = array2image(dn, img) boxes = dn.make_boxes(self.net) probs = dn.make_probs(self.net) num = dn.num_boxes(self.net) dn.network_detect(self.net, img, thresh, hier_thresh, nms, boxes, probs) res = [] for j in range(num): if probs[j][0] > thresh: res.append((probs[j][0], (boxes[j].x, boxes[j].y, boxes[j].w, boxes[j].h))) res = sorted(res, key=lambda x: -x[0]) dn.free_ptrs(dn.cast(probs, dn.POINTER(dn.c_void_p)), num) return res
def prepare_batch(images, network, channels=3): width = darknet.network_width(network) height = darknet.network_height(network) darknet_images = [] for image in images: image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image_resized = cv2.resize(image_rgb, (width, height), interpolation=cv2.INTER_LINEAR) custom_image = image_resized.transpose(2, 0, 1) darknet_images.append(custom_image) batch_array = np.concatenate(darknet_images, axis=0) batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32)/255.0 darknet_images = batch_array.ctypes.data_as(darknet.POINTER(darknet.c_float)) return darknet.IMAGE(width, height, channels, darknet_images)
def prepare_batch(images, network, channels=3): # YOLO의 허용 크기: 320x320, 609X609, 416X416 width = darknet.network_width(network) height = darknet.network_height(network) darknet_images = [] for image in images: image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) #opencv의 경우, image를 BGR 형태로 불러오므로 RGB로 변환 image_resized = cv2.resize(image_rgb, (width, height), interpolation=cv2.INTER_LINEAR) custom_image = image_resized.transpose(2, 0, 1) #opencv의 경우, image를 HWC 형태로 불러오므로 CHW 형태로 변환 darknet_images.append(custom_image) batch_array = np.concatenate(darknet_images, axis=0) #data 배열 합치기 batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32)/255.0 #memory에 연속적인 배열 생성 및 정규화 darknet_images = batch_array.ctypes.data_as(darknet.POINTER(darknet.c_float)) #data 형변환 return darknet.IMAGE(width, height, channels, darknet_images)
def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45): """ From darknet/python/darknet.py """ # im = dn.load_image(image, 0, 0) im = dn.load_image(image, dn.network_width(net), dn.network_height(net)) boxes = dn.make_boxes(net) probs = dn.make_probs(net) num = dn.num_boxes(net) dn.network_detect(net, im, thresh, hier_thresh, nms, boxes, probs) res = [] for j in range(num): for i in range(meta.classes): if probs[j][i] > 0: res.append((i, probs[j][i], (boxes[j].x, boxes[j].y, boxes[j].w, boxes[j].h))) res = sorted(res, key=lambda x: -x[1]) dn.free_image(im) dn.free_ptrs(dn.cast(probs, dn.POINTER(dn.c_void_p)), num) return res
weight_path, batch_size=batch_size) os.remove(tmp_config_path) stdin = sys.stdin.detach() while True: buf = stdin.read(batch_size * width * height * 3) if not buf: break arr = numpy.frombuffer(buf, dtype='uint8').reshape( (batch_size, height, width, 3)) arr = arr.transpose((0, 3, 1, 2)) arr = numpy.ascontiguousarray(arr.flat, dtype='float32') / 255.0 darknet_images = arr.ctypes.data_as(darknet.POINTER(darknet.c_float)) darknet_images = darknet.IMAGE(width, height, 3, darknet_images) raw_detections = darknet.network_predict_batch(net, darknet_images, batch_size, width, height, threshold, 0.5, None, 0, 0) detections = [] for idx in range(batch_size): num = raw_detections[idx].num raw_dlist = raw_detections[idx].dets darknet.do_nms_obj(raw_dlist, num, len(class_names), 0.45) raw_dlist = darknet.remove_negatives(raw_dlist, class_names, num) dlist = [] for cls, score, (cx, cy, w, h) in raw_dlist: dlist.append({ 'Category': cls, 'Score': float(score),
def prepare_batch(images, network, channels=3): width = darknet.network_width(network) height = darknet.network_height(network) darknet_images = [] for image in images: image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image_resized = cv2.resize(image_rgb, (width, height), interpolation=cv2.INTER_LINEAR) custom_image = image_resized.transpose(2, 0, 1) darknet_images.append(custom_image) batch_array = np.concatenate(darknet_images, axis=0) batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32)/255.0 darknet_images = batch_array.ctypes.data_as(darknet.POINTER(darknet.c_float)) return darknet.IMAGE(width, height, channels, darknet_images) def image_detection(image_path, network, class_names, class_colors, thresh): # Darknet doesn't accept numpy images. # Create one with image we reuse for each detect width = darknet.network_width(network) height = darknet.network_height(network) darknet_image = darknet.make_image(width, height, 3) image = cv2.imread(image_path) image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image_resized = cv2.resize(image_rgb, (width, height), interpolation=cv2.INTER_LINEAR)
def darknet_batch_detection_rs_images(network, image_path, save_dir, patch_groups, patch_count, class_names, batch_size, thresh=0.25, hier_thresh=.5, nms=.45): ''' # run batch detection of YOLO on an remote sensing image. :param network: a darknet network (already load the weight) :param image_path: the image patch. :param patch_groups: the group of images patch, each group has the same width and height. :param class_names: :param batch_size: :param thresh: :param hier_thresh: :param nms: :return: ''' # read the entire image entire_img_data, nodata = raster_io.read_raster_all_bands_np(image_path) entire_img_data = entire_img_data.transpose(1, 2, 0) # to opencv format # # RGB to BGR: Matplotlib image to OpenCV https://www.scivision.dev/numpy-image-bgr-to-rgb/ # entire_img_data = entire_img_data[..., ::-1].copy() # cancel RGB to BGR, since it make results worse, (maybe darknet already read images as RGB during training) entire_height, entire_width, band_num = entire_img_data.shape print("entire_height, entire_width, band_num", entire_height, entire_width, band_num) if band_num not in [1, 3]: raise ValueError('only accept one band or three band images') # class_colors={} #{'thaw_slump': (139, 140, 228)} # class_colors should get when load network # for name in class_names: # class_colors[name] = (0,0,0) patch_idx = 0 for key in patch_groups.keys(): patches_sameSize = patch_groups[key] batch_patches = [ patches_sameSize[i * batch_size:(i + 1) * batch_size] for i in range((len(patches_sameSize) + batch_size - 1) // batch_size) ] for a_batch_patch in batch_patches: t0 = time.time() input_batch_size = len(a_batch_patch) if input_batch_size != batch_size: if input_batch_size > batch_size: raise ValueError( 'input_batch_size (%d) is greater than batch_size (%d)' % (input_batch_size, batch_size)) while (len(a_batch_patch) < batch_size): a_batch_patch.append( a_batch_patch[0] ) # copy the first one to fit the batch size images = [ copy_one_patch_image_data(patch, entire_img_data) for patch in a_batch_patch ] # for the batch prediction, it seems have to resize to the network size img_height, img_width, band_num = images[0].shape width = darknet.network_width(network) height = darknet.network_height(network) # darknet_images = prepare_batch(images, network) # prepare_batch darknet_images = [] for image in images: # print('image shape',image.shape) image_resized = cv2.resize(image, (width, height), interpolation=cv2.INTER_LINEAR) if band_num == 1: image_resized = np.expand_dims( image_resized, axis=2) # add one diminsion at the last # print('image_resized shape', image_resized.shape) custom_image = image_resized.transpose(2, 0, 1) darknet_images.append(custom_image) batch_array = np.concatenate(darknet_images, axis=0) batch_array = np.ascontiguousarray(batch_array.flat, dtype=np.float32) / 255.0 darknet_images = batch_array.ctypes.data_as( darknet.POINTER(darknet.c_float)) darknet_images = darknet.IMAGE(width, height, band_num, darknet_images) # prediction batch_detections = darknet.network_predict_batch( network, darknet_images, batch_size, img_height, img_width, thresh, hier_thresh, None, 0, 0) batch_predictions = [] for idx in range(input_batch_size): num = batch_detections[idx].num detections = batch_detections[idx].dets if nms: darknet.do_nms_obj(detections, num, len(class_names), nms) predictions = darknet.remove_negatives(detections, class_names, num) # images[idx] = np.ascontiguousarray(images[idx]) # images[idx] = darknet.draw_boxes(predictions, images[idx], class_colors) batch_predictions.append(predictions) darknet.free_batch_detections(batch_detections, batch_size) for idx, (patch, image, predictions) in enumerate( zip(a_batch_patch, images, batch_predictions)): # remove the duplicated ones if idx >= input_batch_size: break # save results save_res_json = os.path.join(save_dir, '%d.json' % patch_idx) # the confidence output by network_predict_batch is 0-1, convert to percent save_one_patch_detection_json(patch, predictions, class_names, save_res_json, b_percent=True) # cv2.imwrite('%d.png'%patch_idx, image) # save for testing # for label, confidence, bbox in predictions: # bbox = darknet.bbox2points(bbox) # to [xmin, ymin, xmax, ymax] # print(label, class_names.index(label), bbox, confidence) if patch_idx % 100 == 0: print('saving %d patch, total: %d, cost %f second' % (patch_idx, patch_count, (time.time() - t0) / batch_size)) patch_idx += 1