| import numpy as np |
| import cv2 |
|
|
| CLASSES = ("person", "bicycle", "car", "motorbike ", "aeroplane ", "bus ", "train", "truck ", "boat", "traffic light", |
| "fire hydrant", "stop sign ", "parking meter", "bench", "bird", "cat", "dog ", "horse ", "sheep", "cow", "elephant", |
| "bear", "zebra ", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", |
| "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife ", |
| "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza ", "donut", "cake", "chair", "sofa", |
| "pottedplant", "bed", "diningtable", "toilet ", "tvmonitor", "laptop ", "mouse ", "remote ", "keyboard ", "cell phone", "microwave ", |
| "oven ", "toaster", "sink", "refrigerator ", "book", "clock", "vase", "scissors ", "teddy bear ", "hair drier", "toothbrush ") |
| |
| def eqprocess(image, size1, size2): |
| h,w,_ = image.shape |
| mask = np.zeros((size1,size2,3),dtype=np.float32) |
| scale1 = h /size1 |
| scale2 = w / size2 |
| if scale1 > scale2: |
| scale = scale1 |
| else: |
| scale = scale2 |
| img = cv2.resize(image,(int(w / scale),int(h / scale))) |
| mask[:int(h / scale),:int(w / scale),:] = img |
| return mask, scale |
|
|
| def xywh2xyxy(x): |
| ''' |
| Box (center x, center y, width, height) to (x1, y1, x2, y2) |
| ''' |
| y = np.copy(x) |
| y[:, 0] = x[:, 0] - x[:, 2] / 2 |
| y[:, 1] = x[:, 1] - x[:, 3] / 2 |
| y[:, 2] = x[:, 0] + x[:, 2] / 2 |
| y[:, 3] = x[:, 1] + x[:, 3] / 2 |
| return y |
|
|
| def xyxy2xywh(box): |
| ''' |
| Box (left_top x, left_top y, right_bottom x, right_bottom y) to (left_top x, left_top y, width, height) |
| ''' |
| box[:, 2:] = box[:, 2:] - box[:, :2] |
| return box |
|
|
| def NMS(dets, scores, thresh): |
| ''' |
| 单类NMS算法 |
| dets.shape = (N, 5), (left_top x, left_top y, right_bottom x, right_bottom y, Scores) |
| ''' |
| x1 = dets[:,0] |
| y1 = dets[:,1] |
| x2 = dets[:,2] |
| y2 = dets[:,3] |
| areas = (y2-y1+1) * (x2-x1+1) |
| keep = [] |
| index = scores.argsort()[::-1] |
| while index.size >0: |
| i = index[0] |
| keep.append(i) |
| x11 = np.maximum(x1[i], x1[index[1:]]) |
| y11 = np.maximum(y1[i], y1[index[1:]]) |
| x22 = np.minimum(x2[i], x2[index[1:]]) |
| y22 = np.minimum(y2[i], y2[index[1:]]) |
| w = np.maximum(0, x22-x11+1) |
| h = np.maximum(0, y22-y11+1) |
| overlaps = w*h |
| ious = overlaps / (areas[i]+areas[index[1:]] - overlaps) |
| idx = np.where(ious<=thresh)[0] |
| index = index[idx+1] |
| |
| return keep |
|
|
|
|
| def draw_detect_res(img, det_pred): |
| ''' |
| 检测结果绘制 |
| ''' |
| if det_pred is None: |
| return img |
|
|
| img = img.astype(np.uint8) |
| im_canvas = img.copy() |
| color_step = int(255/len(CLASSES)) |
| for i in range(len(det_pred)): |
| x1, y1, x2, y2 = [int(t) for t in det_pred[i][:4]] |
| cls_id = int(det_pred[i][5]) |
| print(i+1,[x1,y1,x2,y2],det_pred[i][4], f'{CLASSES[cls_id]}') |
| cv2.putText(img, f'{CLASSES[cls_id]}', (x1, y1-6), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1) |
| cv2.rectangle(img, (x1, y1), (x2, y2), (0, int(cls_id*color_step), int(255-cls_id*color_step)),thickness = 2) |
| img = cv2.addWeighted(im_canvas, 0.3, img, 0.7, 0) |
| return img |
|
|
| def scale_mask(masks, im0_shape): |
| masks = cv2.resize(masks, (im0_shape[1], im0_shape[0]), |
| interpolation=cv2.INTER_LINEAR) |
| if len(masks.shape) == 2: |
| masks = masks[:, :, None] |
| return masks |
|
|
| def crop_mask(masks, boxes): |
| n, h, w = masks.shape |
| x1, y1, x2, y2 = np.split(boxes[:, :, None], 4, 1) |
| r = np.arange(w, dtype=x1.dtype)[None, None, :] |
| c = np.arange(h, dtype=x1.dtype)[None, :, None] |
| return masks * ((r >= x1) * (r < x2) * (c >= y1) * (c < y2)) |
|
|
| def process_mask(protos, masks_in, bboxes, im0_shape): |
| c, mh, mw = protos.shape |
| masks = np.matmul(masks_in, protos.reshape((c, -1))).reshape((-1, mh, mw)).transpose(1, 2, 0) |
| masks = np.ascontiguousarray(masks) |
| masks = scale_mask(masks, im0_shape) |
| masks = np.einsum('HWN -> NHW', masks) |
| masks = crop_mask(masks, bboxes) |
| return np.greater(masks, 0.5) |
|
|
| def masks2segments(masks): |
| segments = [] |
| for x in masks.astype('uint8'): |
| c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0] |
| if c: |
| c = np.array(c[np.array([len(x) for x in c]).argmax()]).reshape(-1, 2) |
| else: |
| c = np.zeros((0, 2)) |
| segments.append(c.astype('float32')) |
| return segments |
|
|