目标检测矩形框与polygon数据增加--裁剪,拓展,旋转

1.裁剪 

import torch
from torchvision import transforms
import cv2
import numpy as np
import types
from numpy import random
class RandomSampleCrop(object):"""CropArguments:img (Image): the image being input during trainingboxes (Tensor): the original bounding boxes in pt formlabels (Tensor): the class labels for each bboxmode (float tuple): the min and max jaccard overlapsReturn:(img, boxes, classes)img (Image): the cropped imageboxes (Tensor): the adjusted bounding boxes in pt formlabels (Tensor): the class labels for each bbox"""def __init__(self):self.sample_options = (# using entire original input imageNone,# sample a patch s.t. MIN jaccard w/ obj in .1,.3,.4,.7,.9(0.1, None),(0.3, None),(0.7, None),(0.9, None),# randomly sample a patch(None, None),)def __call__(self, image, boxes=None, labels=None):height, width, _ = image.shapewhile True:# randomly choose a modemode = random.choice(self.sample_options)if mode is None:return image, boxes, labelsmin_iou, max_iou = modeif min_iou is None:min_iou = float('-inf')if max_iou is None:max_iou = float('inf')# max trails (50)for _ in range(50):current_image = imagew = random.uniform(0.3 * width, width)h = random.uniform(0.3 * height, height)# aspect ratio constraint b/t .5 & 2if h / w < 0.5 or h / w > 2:continueleft = random.uniform(width - w)top = random.uniform(height - h)# convert to integer rect x1,y1,x2,y2rect = np.array([int(left), int(top), int(left + w), int(top + h)])# calculate IoU (jaccard overlap) b/t the cropped and gt boxesoverlap = jaccard_numpy(boxes, rect)# is min and max overlap constraint satisfied? if not try againif overlap.min() < min_iou and max_iou < overlap.max():continue# cut the crop from the imagecurrent_image = current_image[rect[1]:rect[3], rect[0]:rect[2],:]# keep overlap with gt box IF center in sampled patchcenters = (boxes[:, :2] + boxes[:, 2:]) / 2.0# mask in all gt boxes that above and to the left of centersm1 = (rect[0] < centers[:, 0]) * (rect[1] < centers[:, 1])# mask in all gt boxes that under and to the right of centersm2 = (rect[2] > centers[:, 0]) * (rect[3] > centers[:, 1])# mask in that both m1 and m2 are truemask = m1 * m2# have any valid boxes? try again if notif not mask.any():continue# take only matching gt boxescurrent_boxes = boxes[mask, :].copy()# take only matching gt labelscurrent_labels = labels[mask]# should we use the box left and top corner or the crop'scurrent_boxes[:, :2] = np.maximum(current_boxes[:, :2],rect[:2])# adjust to crop (by substracting crop's left,top)current_boxes[:, :2] -= rect[:2]current_boxes[:, 2:] = np.minimum(current_boxes[:, 2:],rect[2:])# adjust to crop (by substracting crop's left,top)current_boxes[:, 2:] -= rect[:2]return current_image, current_boxes, current_labelsdef debug_random_crop():random_crop = RandomSampleCrop()import cv2path = './test.jpg'img = cv2.imread(path)print(img.shape)boxes = np.array([[68, 62, 311, 523],[276, 235, 498, 535],[480, 160, 701, 510]])labels = np.array([[1],[1],[1]])current_image, current_boxes, current_labels = random_crop(img, boxes, labels)print('==current_image.shape:', current_image.shape)print('==current_boxes:', current_boxes)print('==current_labels:', current_labels)for box in current_boxes:x1,y1,x2,y2 = boxcv2.rectangle(current_image,(x1,y1),(x2,y2),color=(0,0,255),thickness=2)cv2.imwrite('./draw_current_image.jpg', current_image)
if __name__ == '__main__':debug_random_crop()

变为

2.拓展

def expand(image, boxes, filler):"""Perform a zooming out operation by placing the image in a larger canvas of filler material.Helps to learn to detect smaller objects.:param image: image, a tensor of dimensions (3, original_h, original_w):param boxes: bounding boxes in boundary coordinates, a tensor of dimensions (n_objects, 4):param filler: RBG values of the filler material, a list like [R, G, B]:return: expanded image, updated bounding box coordinates"""# Calculate dimensions of proposed expanded (zoomed-out) imageoriginal_h = image.size(1)original_w = image.size(2)max_scale = 4scale = random.uniform(1, max_scale)new_h = int(scale * original_h)new_w = int(scale * original_w)# Create such an image with the fillerfiller = torch.FloatTensor(filler)  # (3)new_image = torch.ones((3, new_h, new_w), dtype=torch.float) * filler.unsqueeze(1).unsqueeze(1)  # (3, new_h, new_w)# Note - do not use expand() like new_image = filler.unsqueeze(1).unsqueeze(1).expand(3, new_h, new_w)# because all expanded values will share the same memory, so changing one pixel will change all# Place the original image at random coordinates in this new image (origin at top-left of image)left = random.randint(0, new_w - original_w)right = left + original_wtop = random.randint(0, new_h - original_h)bottom = top + original_hnew_image[:, top:bottom, left:right] = imageprint('==boxes:', boxes)# Adjust bounding boxes' coordinates accordinglynew_boxes = boxes + torch.FloatTensor([left, top, left, top]).unsqueeze(0)  # (n_objects, 4), n_objects is the no. of objects in this imageprint('===new_boxes:', new_boxes)return new_image, new_boxesdef torch_cutout():info = {"boxes": [[52, 86, 470, 419],[157, 43, 288, 166]],"labels": [13, 15], "difficulties": [0, 0]}image = Image.open('./2008_000008.jpg', mode='r')image = image.convert('RGB')bboxs = info['boxes']lables = info['labels']difficulties = info['difficulties']img = np.array(image)[..., ::-1].copy()for box in bboxs:x1, y1, x2, y2 = boxprint('x1, y1, x2, y2:', x1, y1, x2, y2)cv2.rectangle(img, (x1,y1), (x2,y2),color=(0,0,255),thickness=2)cv2.imwrite('./img_rect.jpg', img)mean = [0.485, 0.456, 0.406]std = [0.229, 0.224, 0.225]new_image = FT.to_tensor(image)boxes = torch.FloatTensor(bboxs)labels = torch.LongTensor(lables)  # (n_objects)difficulties = torch.ByteTensor(difficulties)  # (n_objects)# new_image, new_boxes, new_labels, new_difficulties = random_crop(new_image, boxes, labels, difficulties)# print('new_image, new_boxes, new_labels, new_difficulties', new_image.shape, new_boxes, new_labels, new_difficulties)new_image, new_boxes = expand(new_image, boxes, filler=mean)fin_img = new_image.permute(1, 2, 0).numpy()*255.fin_img = fin_img[..., ::-1].copy()print('fin_img.shape:', fin_img.shape)fin_boxes = new_boxes.numpy()print(fin_boxes)for box in fin_boxes:x1, y1, x2, y2 = boxprint('x1, y1, x2, y2:', x1, y1, x2, y2)cv2.rectangle(fin_img, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)cv2.imwrite('./fin_img_rect.jpg', fin_img)
if __name__ == '__main__':torch_cutout()

变为

检测的整个transform包括随机裁剪,扩张,resize等等。

import torch
from torchvision import transforms
import cv2
import numpy as np
import types
from numpy import randomdef intersect(box_a, box_b):max_xy = np.minimum(box_a[:, 2:], box_b[2:])min_xy = np.maximum(box_a[:, :2], box_b[:2])inter = np.clip((max_xy - min_xy), a_min=0, a_max=np.inf)return inter[:, 0] * inter[:, 1]def jaccard_numpy(box_a, box_b):"""Compute the jaccard overlap of two sets of boxes.  The jaccard overlapis simply the intersection over union of two boxes.E.g.:A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)Args:box_a: Multiple bounding boxes, Shape: [num_boxes,4]box_b: Single bounding box, Shape: [4]Return:jaccard overlap: Shape: [box_a.shape[0], box_a.shape[1]]"""inter = intersect(box_a, box_b)area_a = ((box_a[:, 2] - box_a[:, 0]) *(box_a[:, 3] - box_a[:, 1]))  # [A,B]area_b = ((box_b[2] - box_b[0]) *(box_b[3] - box_b[1]))  # [A,B]union = area_a + area_b - interreturn inter / union  # [A,B]class Compose(object):"""Composes several augmentations together.Args:transforms (List[Transform]): list of transforms to compose.Example:>>> augmentations.Compose([>>>     transforms.CenterCrop(10),>>>     transforms.ToTensor(),>>> ])"""def __init__(self, transforms):self.transforms = transformsdef __call__(self, img, boxes=None, labels=None):for t in self.transforms:img, boxes, labels = t(img, boxes, labels)return img, boxes, labelsclass Lambda(object):"""Applies a lambda as a transform."""def __init__(self, lambd):assert isinstance(lambd, types.LambdaType)self.lambd = lambddef __call__(self, img, boxes=None, labels=None):return self.lambd(img, boxes, labels)class ConvertFromInts(object):def __call__(self, image, boxes=None, labels=None):return image.astype(np.float32), boxes, labelsclass Normalize(object):def __init__(self, mean=None, std=None):self.mean = np.array(mean, dtype=np.float32)self.std = np.array(std, dtype=np.float32)def __call__(self, image, boxes=None, labels=None):image = image.astype(np.float32)image /= 255.image -= self.meanimage /= self.stdreturn image, boxes, labelsclass ToAbsoluteCoords(object):def __call__(self, image, boxes=None, labels=None):height, width, channels = image.shapeboxes[:, 0] *= widthboxes[:, 2] *= widthboxes[:, 1] *= heightboxes[:, 3] *= heightreturn image, boxes, labelsclass ToPercentCoords(object):def __call__(self, image, boxes=None, labels=None):height, width, channels = image.shapeboxes[:, 0] /= widthboxes[:, 2] /= widthboxes[:, 1] /= heightboxes[:, 3] /= heightreturn image, boxes, labelsclass Resize(object):def __init__(self, size=300):self.size = sizedef __call__(self, image, boxes=None, labels=None):image = cv2.resize(image, (self.size,self.size))return image, boxes, labelsclass RandomSaturation(object):def __init__(self, lower=0.5, upper=1.5):self.lower = lowerself.upper = upperassert self.upper >= self.lower, "contrast upper must be >= lower."assert self.lower >= 0, "contrast lower must be non-negative."def __call__(self, image, boxes=None, labels=None):if random.randint(2):image[:, :, 1] *= random.uniform(self.lower, self.upper)return image, boxes, labelsclass RandomHue(object):def __init__(self, delta=18.0):assert delta >= 0.0 and delta <= 360.0self.delta = deltadef __call__(self, image, boxes=None, labels=None):if random.randint(2):image[:, :, 0] += random.uniform(-self.delta, self.delta)image[:, :, 0][image[:, :, 0] > 360.0] -= 360.0image[:, :, 0][image[:, :, 0] < 0.0] += 360.0return image, boxes, labelsclass RandomLightingNoise(object):def __init__(self):self.perms = ((0, 1, 2), (0, 2, 1),(1, 0, 2), (1, 2, 0),(2, 0, 1), (2, 1, 0))def __call__(self, image, boxes=None, labels=None):if random.randint(2):swap = self.perms[random.randint(len(self.perms))]shuffle = SwapChannels(swap)  # shuffle channelsimage = shuffle(image)return image, boxes, labelsclass ConvertColor(object):def __init__(self, current='BGR', transform='HSV'):self.transform = transformself.current = currentdef __call__(self, image, boxes=None, labels=None):if self.current == 'BGR' and self.transform == 'HSV':image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)elif self.current == 'HSV' and self.transform == 'BGR':image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)else:raise NotImplementedErrorreturn image, boxes, labelsclass RandomContrast(object):def __init__(self, lower=0.5, upper=1.5):self.lower = lowerself.upper = upperassert self.upper >= self.lower, "contrast upper must be >= lower."assert self.lower >= 0, "contrast lower must be non-negative."# expects float imagedef __call__(self, image, boxes=None, labels=None):if random.randint(2):alpha = random.uniform(self.lower, self.upper)image *= alphareturn image, boxes, labelsclass RandomBrightness(object):def __init__(self, delta=32):assert delta >= 0.0assert delta <= 255.0self.delta = deltadef __call__(self, image, boxes=None, labels=None):if random.randint(2):delta = random.uniform(-self.delta, self.delta)image += deltareturn image, boxes, labelsclass ToCV2Image(object):def __call__(self, tensor, boxes=None, labels=None):return tensor.cpu().numpy().astype(np.float32).transpose((1, 2, 0)), boxes, labelsclass ToTensor(object):def __call__(self, cvimage, boxes=None, labels=None):return torch.from_numpy(cvimage.astype(np.float32)).permute(2, 0, 1), boxes, labelsclass RandomSampleCrop(object):"""CropArguments:img (Image): the image being input during trainingboxes (Tensor): the original bounding boxes in pt formlabels (Tensor): the class labels for each bboxmode (float tuple): the min and max jaccard overlapsReturn:(img, boxes, classes)img (Image): the cropped imageboxes (Tensor): the adjusted bounding boxes in pt formlabels (Tensor): the class labels for each bbox"""def __init__(self):self.sample_options = (# using entire original input imageNone,# sample a patch s.t. MIN jaccard w/ obj in .1,.3,.4,.7,.9(0.1, None),(0.3, None),(0.7, None),(0.9, None),# randomly sample a patch(None, None),)def __call__(self, image, boxes=None, labels=None):height, width, _ = image.shapewhile True:# randomly choose a modemode = random.choice(self.sample_options)if mode is None:return image, boxes, labelsmin_iou, max_iou = modeif min_iou is None:min_iou = float('-inf')if max_iou is None:max_iou = float('inf')# max trails (50)for _ in range(50):current_image = imagew = random.uniform(0.3 * width, width)h = random.uniform(0.3 * height, height)# aspect ratio constraint b/t .5 & 2if h / w < 0.5 or h / w > 2:continueleft = random.uniform(width - w)top = random.uniform(height - h)# convert to integer rect x1,y1,x2,y2rect = np.array([int(left), int(top), int(left + w), int(top + h)])# calculate IoU (jaccard overlap) b/t the cropped and gt boxesoverlap = jaccard_numpy(boxes, rect)# is min and max overlap constraint satisfied? if not try againif overlap.min() < min_iou and max_iou < overlap.max():continue# cut the crop from the imagecurrent_image = current_image[rect[1]:rect[3], rect[0]:rect[2],:]# keep overlap with gt box IF center in sampled patchcenters = (boxes[:, :2] + boxes[:, 2:]) / 2.0# mask in all gt boxes that above and to the left of centersm1 = (rect[0] < centers[:, 0]) * (rect[1] < centers[:, 1])# mask in all gt boxes that under and to the right of centersm2 = (rect[2] > centers[:, 0]) * (rect[3] > centers[:, 1])# mask in that both m1 and m2 are truemask = m1 * m2# have any valid boxes? try again if notif not mask.any():continue# take only matching gt boxescurrent_boxes = boxes[mask, :].copy()# take only matching gt labelscurrent_labels = labels[mask]# should we use the box left and top corner or the crop'scurrent_boxes[:, :2] = np.maximum(current_boxes[:, :2],rect[:2])# adjust to crop (by substracting crop's left,top)current_boxes[:, :2] -= rect[:2]current_boxes[:, 2:] = np.minimum(current_boxes[:, 2:],rect[2:])# adjust to crop (by substracting crop's left,top)current_boxes[:, 2:] -= rect[:2]return current_image, current_boxes, current_labelsclass Expand(object):def __init__(self, mean):self.mean = meandef __call__(self, image, boxes, labels):if random.randint(2):return image, boxes, labelsheight, width, depth = image.shaperatio = random.uniform(1, 4)left = random.uniform(0, width * ratio - width)top = random.uniform(0, height * ratio - height)expand_image = np.zeros((int(height * ratio), int(width * ratio), depth),dtype=image.dtype)expand_image[:, :, :] = self.meanexpand_image[int(top):int(top + height),int(left):int(left + width)] = imageimage = expand_imageboxes = boxes.copy()boxes[:, :2] += (int(left), int(top))boxes[:, 2:] += (int(left), int(top))return image, boxes, labelsclass RandomMirror(object):def __call__(self, image, boxes, classes):_, width, _ = image.shapeif random.randint(2):image = image[:, ::-1]boxes = boxes.copy()boxes[:, 0::2] = width - boxes[:, 2::-2]return image, boxes, classesclass SwapChannels(object):"""Transforms a tensorized image by swapping the channels in the orderspecified in the swap tuple.Args:swaps (int triple): final order of channelseg: (2, 1, 0)"""def __init__(self, swaps):self.swaps = swapsdef __call__(self, image):"""Args:image (Tensor): image tensor to be transformedReturn:a tensor with channels swapped according to swap"""# if torch.is_tensor(image):#     image = image.data.cpu().numpy()# else:#     image = np.array(image)image = image[:, :, self.swaps]return imageclass PhotometricDistort(object):def __init__(self):self.pd = [RandomContrast(),ConvertColor(transform='HSV'),RandomSaturation(),RandomHue(),ConvertColor(current='HSV', transform='BGR'),RandomContrast()]self.rand_brightness = RandomBrightness()# self.rand_light_noise = RandomLightingNoise()def __call__(self, image, boxes, labels):im = image.copy()im, boxes, labels = self.rand_brightness(im, boxes, labels)if random.randint(2):distort = Compose(self.pd[:-1])else:distort = Compose(self.pd[1:])im, boxes, labels = distort(im, boxes, labels)return im, boxes, labels# return self.rand_light_noise(im, boxes, labels)class SSDAugmentation(object):def __init__(self, size=300, mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229)):self.mean = meanself.size = sizeself.std = stdself.augment = Compose([ConvertFromInts(),ToAbsoluteCoords(),PhotometricDistort(),Expand(self.mean),RandomSampleCrop(),RandomMirror(),ToPercentCoords(),Resize(self.size),Normalize(self.mean, self.std)])def __call__(self, img, boxes, labels):return self.augment(img, boxes, labels)def debug_random_crop():random_crop = RandomSampleCrop()import cv2path = './test.jpg'img = cv2.imread(path)print(img.shape)boxes = np.array([[68, 62, 311, 523],[276, 235, 498, 535],[480, 160, 701, 510]])labels = np.array([[1],[1],[1]])current_image, current_boxes, current_labels = random_crop(img, boxes, labels)print('==current_image.shape:', current_image.shape)print('==current_boxes:', current_boxes)print('==current_labels:', current_labels)for box in current_boxes:x1,y1,x2,y2 = boxcv2.rectangle(current_image,(x1,y1),(x2,y2),color=(0,0,255),thickness=2)cv2.imwrite('./draw_current_image.jpg', current_image)
if __name__ == '__main__':debug_random_crop()

3.旋转

imgaug文档说明


import os
import cv2
import numpy as np
import json
import imgaug as ia
from imgaug import augmenters as iaadef may_augment_poly(aug, img_shape, poly):# for p in poly:#     print('==p', p)keypoints = [ia.Keypoint(p[0], p[1]) for p in poly]keypoints = aug.augment_keypoints([ia.KeypointsOnImage(keypoints, shape=img_shape)])[0].keypointspoly = [(p.x, p.y) for p in keypoints]return polydef get_express_code_txt():path = './标好快递单二维码数据'# output_path = './标好快递单二维码数据_out'# if not os.path.exists(output_path):#     os.mkdir(output_path)imgs_list_path =[os.path.join(path, i) for i in os.listdir(path) if '.jpg' in i]for i, img_list_path in enumerate(imgs_list_path):if i < 1:print('==img_list_path:', img_list_path)img = cv2.imread(img_list_path)json_list_path = img_list_path.replace('.jpg', '.json')with open(json_list_path, 'r') as file:json_info = json.load(file)shapes = json_info['shapes']output_points = []for shape in shapes:points = np.array(shape['points']).astype(np.int)# print('===before points', points)points = cal_stand_points(points)points = polygon_area1(points)# print('===after points', points)# cv2.polylines(img, [np.array(points).reshape(-1, 1, 2)], True, (0, 255, 0), thickness=2)output_points.append(list(map(int, (points.reshape(-1).tolist()))))print('==output_points:', output_points)seq = iaa.Sequential([# iaa.Multiply((1.2, 1.5)),  # change brightness, doesn't affect keypointsiaa.Fliplr(0.5),iaa.Affine(rotate=(0, 360),#0~360随机旋转scale=(0.7, 1.0),#通过增加黑边缩小图片),  # rotate by exactly 0~360deg and scale to 70-100%, affects keypoints# iaa.Resize(0.5, 3)])seq_def = seq.to_deterministic()image_aug = seq_def.augment_image(img)print('==image_aug.shape:', image_aug.shape)line_polys = []polys = np.array(output_points).reshape(-1, 4, 2).astype(np.int)print('==polys:', polys.shape)for poly in polys:new_poly = may_augment_poly(seq_def, img.shape, poly)line_polys.append(new_poly)print('=line_polys:', line_polys)#debugfor line_poly in line_polys:# print('==line_poly:', line_poly)cv2.polylines(image_aug, [np.array(line_poly).reshape(-1, 1, 2).astype(np.int)], True, (0, 0, 255), thickness=2)cv2.imwrite('./image_aug.jpg', image_aug)
if __name__ == '__main__':get_express_code_txt()

json文件:

{"version": "4.2.10","shapes": [{"shape_type": "polygon","group_id": null,"label": "code","points": [[207.6190476190476,689.2857142857143],[613.5714285714286,545.2380952380953],[654.047619047619,635.7142857142858],[254.04761904761904,777.3809523809524]],"flags": {}},{"shape_type": "polygon","group_id": null,"label": "code","points": [[500.4761904761905,883.3333333333334],[858.8095238095239,757.1428571428572],[881.4285714285716,796.4285714285714],[513.5714285714286,925.0]],"flags": {}},{"shape_type": "polygon","group_id": null,"label": "code","points": [[595.7142857142858,1059.5238095238096],[960.0,933.3333333333334],[981.4285714285716,973.8095238095239],[606.4285714285714,1101.1904761904761]],"flags": {}}],"lineColor": [0,255,0,128],"fillColor": [255,0,0,128],"imageHeight": 1422,"imageData": null,"imageWidth": 1152,"imagePath": "72.jpg","flags": {}
}

原图                                                                          增强图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/493193.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医生们说,AI不会取代我们!

来源&#xff1a;IEEE电气电子工程师学会每次人工智能在医疗任务中与医生进行竞争&#xff08;对此我们已经报道过很多次&#xff09;时&#xff0c;一个问题不可避免地浮出水面&#xff1a;人工智能会取代医生吗&#xff1f;如果你与AI 专家或硅谷投资者交谈&#xff0c;答案往…

ubuntu安装python3.5+pycharm+anaconda+opencv+docker+nvidia-docker+tensorflow+pytorch+Cmake3.8

一&#xff0c;切换python版本为3.5 装好ubuntu&#xff0c;python版本是2.7的 我自己安装并更改打开为python3.5 sudo apt-get install python3.5 设置优先级和默认环境&#xff1a; sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 100 su…

学界 | 量化深度强化学习算法的泛化能力

来源&#xff1a;AI 科技评论OpenAI 近期发布了一个新的训练环境 CoinRun&#xff0c;它提供了一个度量智能体将其学习经验活学活用到新情况的能力指标&#xff0c;而且还可以解决一项长期存在于强化学习中的疑难问题——即使是广受赞誉的强化算法在训练过程中也总是没有运用监…

《科学》评出2018年度十大科学突破事件

来源&#xff1a;科学大院《科学》杂志每年会评出在即将过去的一年里最为重要的十大科学突破&#xff08;Science Breakthrough&#xff09;。今年&#xff0c;夺得年度突破桂冠的是“单细胞水平细胞谱系追踪技术”&#xff0c;帮助破获多起悬案的法医系谱技术、#MeToo 运动等也…

递归理解以及时间复杂度计算

一.复杂度分析&#xff1a; 可以理解为递归的深度就是空间复杂度&#xff0c;时间复杂度就是O(T*depth),其中&#xff34;是每个递归函数的时间复杂度&#xff0c;depth是递归深度&#xff0e; #空间复杂度O(1) def sum1_(n):res 0for i in range(n1):resireturn res#递归 空…

性价比高出英特尔45%,亚马逊的云服务器芯片如何做到?| 解读

来源&#xff1a;TheNextPlatform编译&#xff1a;机器之能 张玺摘要&#xff1a;到目前为止&#xff0c;亚马逊和其他大型云运营商几乎全部使用英特尔的 Xeon 芯片。虽然在服务器芯片市场&#xff0c;英特尔市场占有率非常高&#xff0c;但亚马逊正使用折扣策略来赢得客户。亚…

GIOU loss+DIOU loss+CIOU loss

一.IOU 1.GIOU解决没有交集的框,IOU为0,其损失函数导数为0,无法优化的问题。 图1 GIOU,IOU,l2范数差异 a)可看出 l2值一样,IOU值是不一样的,说明L1,L2这些Loss用于回归任务时&#xff0c;不能等价于最后用于评测检测的IoU. b)可看出当框有包含关系,GIOU就退化为IOU 其是找…

《科学》十大年度科学突破反映的新动向

来源&#xff1a;新华网摘要&#xff1a;从测定分子结构到宇宙探索&#xff0c;从发现远古动物到揭示细胞的秘密&#xff0c;美国权威学术刊物《科学》杂志评选的2018年十大科学突破&#xff0c;在时间和空间尺度上拓宽着人类认知的边界&#xff0c;也反映了近年来科学发展的三…

ctpn论文阅读与代码

代码地址: https://github.com/zonghaofan/ctpn_torch 1.通用的目标检测是封闭的,而文字是封闭且连续 2. 构造一系列宽度相等的小文本,回归中心y坐标和高度 3. 对于边界回归x坐标,在进一次修正 4.整个模型就是backbone提取特征,将每个像素点的相邻3*3像素拉成行向量,利用空间…

yum配置与使用

yum配置与使用(很详细) yum的配置一般有两种方式&#xff0c;一种是直接配置/etc目录下的yum.conf文件&#xff0c;另外一种是在/etc/yum.repos.d目录下增加.repo文件。一、yum的配置文件$ cat /etc/yum.conf [main]cachedir/var/cache/yum #yum下载的RPM包的缓存目录k…

新技术不断涌现,下一代云计算的突破口在哪里?

来源&#xff1a;日知录技术社区这是一个IT技术飞速发展的时代&#xff0c;在硬件基础设施的不断升级以及虚拟化网络等技术的日益成熟下&#xff0c;云厂商也正面临着各种新技术带来的巨大挑战。从数据中心的基础建设到云平台的系统构建再到产品底层的技术改革&#xff0c;该如…

生成高斯热力图(craft中有使用)+2d heatmap+3d heatmap

一.生成高斯热力图 from math import exp import numpy as np import cv2 import osclass GaussianTransformer(object):def __init__(self, imgSize512, region_threshold0.4,affinity_threshold0.2):distanceRatio 3.34scaledGaussian lambda x: exp(-(1 / 2) * (x ** 2))…

POP动画[1]

POP动画[1] pop动画是facebook扩展CoreAnimation的,使用及其方便:) 1:Spring系列的弹簧效果(两个动画kPOPLayerBounds与kPOPLayerCornerRadius同时运行) #import "RootViewController.h" #import "YXEasing.h" #import "POP.h" #import "YX…

远比5G发展凶猛!物联网2018白皮书,国内规模已达1.2万亿

来源&#xff1a;智东西摘要&#xff1a;研判物联网的技术产业进展情况&#xff0c;梳理消费物联网、智慧城市物联网、生产性物联网三类物联网应用现状及驱动因素 。在供给侧和需求侧的双重推动下&#xff0c;物联网进入以基础性行业和规模消费为代表的第三次发展浪潮。 5G、 低…

收缩分割多边形(PSENet中有使用)

目的:为了解决密集文本的分割问题 代码: # -*- codingutf-8 -*- import os import cv2 import Polygon as plg import pyclipper import numpy as npdef dist(a, b):return np.sqrt(np.sum((a - b) ** 2))#计算周长 def perimeter(bbox):peri 0.0for i in range(bbox.shape[…

Android 3D emulation 架构理解

Android Emulator 给用户提供 GPU on 选项&#xff0c;意思是利用 Host ( 就是执行 Emulator 的PC机) 的 GPU. 当然PC机必须把 OpenGL 的驱动装好 在实现上就是把 libGLESv1_CM.so libGLESv2.so 替换掉&#xff0c;当system调用 gl的函数的时候&#xff0c;把调用打包为strea…

年度回顾:2018年的人工智能/机器学习惊喜及预测19年的走势

来源&#xff1a;网络大数据考虑到技术变革的速度&#xff0c;我认为让专业IT人士分享他们对2018年最大惊喜及2019年预测的看法会很有趣。以下是他们对人工智能(AI)&#xff0c;机器学习( ML)和其他数据科学迭代的看法&#xff1a;CLARA分析公司首席执行官兼创始人&#xff1a;…

利用dbnet分割条形码与文字(代码+模型)+知识蒸馏+tensorrt推理+利用pyzbar和zxing进行条形码解析

一.DBnet 1.代码链接 分割条形码与文字代码:github链接:GitHub - zonghaofan/dbnet_torch: you can use dbnet to detect word or bar code,Knowledge Distillation is provided,also python tensorrt inference is provided.&#xff08;提供模型&#xff09; 2.论文阅读 …

全球值得关注的11家人脸识别公司与机构

来源&#xff1a;资本实验室根据美国国家标准与技术研究院&#xff08;NIST&#xff09;的2018年全球人脸识别算法测试&#xff08;FRVT&#xff09;最新结果&#xff0c;今年共有来自全球的39家企业和机构参与本次竞赛。在最新排名中&#xff0c;前五名算法被中国公司包揽&…

图论基础知识--最小生成树算法kruskal(克鲁斯克尔)和普里姆算法(Prim算法);最短路径算法Dijkstra(迪杰斯特拉)和Floyd(弗洛伊德)

一.基础知识 有向图 无向图 以无向图为例: 邻接矩阵: 度矩阵(对角矩阵): 二&#xff0e;最小生成树 应用&#xff1a;将网络顶点看着城市&#xff0c;边看着城市之间通讯网&#xff0c;边的权重看着成本&#xff0c;根据最小生成树可以构建城市之间成本最低的通讯网&#x…