有时训练和检测图像的分辨率可能会比较大,直接缩放后放到模型中训练和识别可能小目标的性能会比较差,多尺度训练可以改善,样本裁剪也可以改善,yolt 针对高分辨率卫星图像的目标检测就是这个思路

import os
import pandas as pd
import numpy as np
import cv2
import json
import random
import glob
import math
import shutil
from tqdm import trange
from pathlib import Path
from PIL import Image
from sklearn.model_selection import train_test_split
import matplotlib.pylab as pltdef drawImg(img, resizeCo):resizeCo = 50b,g,r = cv2.split(img)image_RGB = cv2.merge([r,g,b])plt.figure(figsize=(image_RGB.shape[0] / resizeCo, image_RGB.shape[1]/ resizeCo))plt.imshow(image_RGB)plt.show()def mat_inter(box1, box2):# 判断两个矩形是否相交# box=(xA,yA,xB,yB)(x01, y01, x02, y02) = box1(x11, y11, x12, y12)  = box2lx = abs((x01 + x02) / 2 - (x11 + x12) / 2)ly = abs((y01 + y02) / 2 - (y11 + y12) / 2)sax = abs(x01 - x02)sbx = abs(x11 - x12)say = abs(y01 - y02)sby = abs(y11 - y12)if lx <= (sax + sbx) / 2 and ly <= (say + sby) / 2:return Trueelse:return Falsedef solve_coincide(box1,box2):# 计算两个矩形框的重合度# box=(xA,yA,xB,yB)if mat_inter(box1,box2)==True:(x01, y01, x02, y02) = box1(x11, y11, x12, y12)  = box2col=min(x02,x12)-max(x01,x11)row=min(y02,y12)-max(y01,y11)intersection=col*rowarea1=(x02-x01)*(y02-y01)area2=(x12-x11)*(y12-y11)coincide=intersection/(area1+area2-intersection)coincide=intersection/(area2)return coincideelse:return 0def expandBox(bbox, expandRatio):# 缩放矩形框,由中心扩展boxCenter = ((bbox[0]+bbox[2])/2, (bbox[1]+bbox[3])/2)w = bbox[2] - bbox[0]h = bbox[3] - bbox[1]nw = w * expandRationh = h * expandRatiox1 = boxCenter[0] - nw / 2x2 = boxCenter[0] + nw / 2y1 = boxCenter[1] - nh / 2y2 = boxCenter[1] + nh / 2return [x1, y1, x2, y2]def resizeBox(bbox, expandRatio):"""缩放矩形标注框"""x1 = bbox[0]*expandRatiox2 = bbox[2]*expandRatioy1 = bbox[1]*expandRatioy2 = bbox[3]*expandRatioreturn [x1, y1, x2, y2]def prepare_dirs(prefix='/output/'):""""""img_dir = os.path.join(prefix, "images")label_dir = os.path.join(prefix, "labels")if os.path.exists(img_dir) and os.path.isdir(img_dir):shutil.rmtree(img_dir)if os.path.exists(label_dir) and os.path.isdir(label_dir):shutil.rmtree(label_dir)os.makedirs(img_dir, exist_ok=True)os.makedirs(label_dir, exist_ok=True)return img_dir, label_dirdef covertYoloLabelxyxy(imWidth, imHeight, x1, y1, x2, y2):dw = 1 / imWidthdh = 1 / imHeightcenterX = (x1 + x2) / 2.0 centerY = (y1 + y2) / 2.0w = (x2 - x1)h = (y2 - y1)centerX = centerX * dw centerY = centerY * dhw = w * dwh = h * dhreturn [centerX, centerY, w, h]def drawBBox(image, color, objBbox):image = cv2.rectangle(image, (int(objBbox[0]), int(objBbox[1])), (int(objBbox[2]), int(objBbox[3])), color, 2)def Yolo2RealLabel(imWidth, imHeight, centerX, centerY, w, h):centerX = centerX * imWidth centerY = centerY * imHeightw = w * imWidthh = h * imHeightx1 = centerX - w/2x2 = centerX + w/2y1 = centerY - h/2y2 = centerY + h/2return [x1, y1, x2, y2]def calLabelAddRate(ratio):coe = (math.atan(ratio)- 0.7853981633974483) / (1.5707963 - 0.7853981633974483)coe = 0.9 - coe * 0.4return coe

单张图像裁剪

def cropImgSlidingWindow(img, cropSize, repetitionRate):"""滑动窗口裁剪图像img:<h,w,c> or <h,w>cropSize:裁剪大小,宽高一致repetitionRate:滑动窗口间的重叠率return:裁剪框,裁剪图像"""height = img.shape[0]width = img.shape[1]croppedBoxs = []for i in range(int((height - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):for j in range(int((width - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):ys = int(i * CropSize * (1 - RepetitionRate)) ye = int(i * CropSize * (1 - RepetitionRate)) + CropSizexs = int(j * CropSize * (1 - RepetitionRate)) xe = int(j * CropSize * (1 - RepetitionRate)) + CropSizeif xe > width:print('游动裁剪')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))for i in range(int((height-CropSize*RepetitionRate)/(CropSize*(1-RepetitionRate)))):ys = int(i * CropSize * (1 - RepetitionRate))ye = int(i * CropSize * (1 - RepetitionRate)) + CropSizexs = (width - CropSize)xe = widthif xe > width or (xe - xs) != CropSize:print('img.shape:', height, width)print('向前裁剪最后一列')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))#  向前裁剪最后一行for j in range(int((width - CropSize * RepetitionRate) / (CropSize * (1 - RepetitionRate)))):ys = (height - CropSize) ye = heightxs = int(j * CropSize * (1 - RepetitionRate))xe = int(j * CropSize * (1 - RepetitionRate)) + CropSizeif xe > width or (xe - xs) != CropSize:print('img.shape:', height, width)print('向前裁剪最后一行')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))#  裁剪右下角ys = (height - CropSize) ye = heightxs = (width - CropSize)xe = widthif xe > width or (xe - xs) != CropSize:print('img.shape:', height, width)print('裁剪右下角')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))cropImgs = []for croppedBox in croppedBoxs:(xs, ys, xe, ye) = croppedBox#  如果图像是单波段if(len(img.shape) == 2):cropped = img[ys : ye, xs : xe]#  如果图像是多波段else:cropped = img[ys : ye, xs : xe, :]if (ye - ys) != cropped.shape[0] or (xe - xs) != cropped.shape[1]:raise Exception("错误:裁剪图像的宽高与设计部一致")cropImgs.append(cropped)if len(cropImgs)!= len(croppedBoxs):raise Exception("错误:裁剪图像数与裁剪框数不一致")return croppedBoxs, cropImgs

增加标注框的处理

def cropLabelImg(imgSavePath, labelSavePath, imgName, img, width, height, cropSize, repetitionRate, labelAddRate, labels, bboxs):"""imgSavePath:裁剪图像保存路径labelSavePath:标注文件保存路径imgName:原始文件名img:图像数据width:宽height:高CropSize:裁剪大小RepetitionRate:裁剪框重叠率labelAddRate: 标注框添加阈值,如果标注框与裁剪框相交面积占其面积的比值超过阈值则添加到裁剪图像的标注labels:原始标注框类别bboxs:原始标注框"""# 对于小于裁剪图像大小的原始样本图像放大到裁剪框大小,方便裁剪,相对直接缩放会好点resizeRatio = 1edgeMax = min(width, height)if edgeMax < CropSize:resizeRatio = CropSize / edgeMaxif edgeMax > 1600:resizeRatio = 1600 / edgeMax# 缩放图像nimg = imgif resizeRatio != 1:width = int(round(width * resizeRatio))height = int(round(height * resizeRatio))nimg = cv2.resize(img, (width, height), interpolation=cv2.INTER_LINEAR)   # 缩放标注框nbboxs = []for bbox in bboxs:nbbox = resizeBox(bbox, resizeRatio)nbboxs.append(nbbox)croppedBoxs, cropImgs =  cropImgSlidingWindow(nimg, cropSize, repetitionRate)cropBoxId = 0for croppedBox, cropImg in zip(croppedBoxs, cropImgs):(xs, ys, xe, ye) = croppedBox#  写图像cropImgPath = imgSavePath + "/" + imgName + "_" + str(cropBoxId) + ".jpg"cv2.imwrite(cropImgPath, cropImg)cv2.waitKey(1)#  写标注文件cropImgLabelPath = labelSavePath + "/" + imgName + "_" + str(cropBoxId) + ".txt"
#         print(cropImgLabelPath)f_Label = open(cropImgLabelPath, "w+")croppedDraw = cropped.copy()for label, nbbox in zip(labels, nbboxs):# 标注框boxAddRate = labelAddRate# 针对操作杆目标,目标本身占标注框的比值很小,因此虽然与裁剪框相交面积大,但也可能存在目标完全不在裁剪框里的情况,calLabelAddRate函数定义了一个使用长宽比来动态设置IOU阈值比例的函数if label == '4': # operatingbarw = nbbox[2]-nbbox[0]h = nbbox[3]-nbbox[1]boxAddRate = calLabelAddRate(max(w, h) / min(w, h))if solve_coincide(croppedBox, nbbox) > boxAddRate:
#                 print(cropImgLabelPath, '+nbboxs:', nbboxs)x1,y1,x2,y2 = nbbox[0],nbbox[1],nbbox[2],nbbox[3]if x1 < xs:x1 = xsif x2 > xe:x2 = xeif y1 < ys:y1 = ysif y2 > ye:y2 = yex1 = x1 - xsx2 = x2 - xsy1 = y1 - ysy2 = y2 - ys#                 print(cropImgLabelPath, '+nbboxs:', nbboxs)drawBBox(croppedDraw, (0, 0, 255), (x1, y1, x2, y2))bb = covertYoloLabelxyxy(cropped.shape[1], cropped.shape[0], x1, y1, x2, y2)f_Label.writelines(str(label) + " " + " ".join(str(b) for b in bb) + '\n')f_Label.close()#  文件名 + 1cropBoxId = cropBoxId + 1      

仅裁剪没有标注框的背景图像

def cropBgImg(imgSavePath, labelSavePath, imgName, img, width, height, cropSize, repetitionRate, labelAddRate, labels, bboxs):"""从训练集中截取背景图像imgSavePath:裁剪图像保存路径labelSavePath:标注文件保存路径imgName:原始文件名img:图像数据width:宽height:高cropSize:裁剪大小repetitionRate:裁剪框重叠率labelAddRate: 标注框添加阈值,如果任意标注框与裁剪框相交面积占标注框面积的比值超过阈值则不添加到背景图像集labels:原始标注框类别bboxs:原始标注框"""# 对于小于裁剪图像大小的原始样本图像放大到裁剪框大小,方便裁剪,相对直接缩放会好点resizeRatio = 1edgeMax = min(width, height)if edgeMax < CropSize:resizeRatio = CropSize / edgeMaxif edgeMax > 1600:resizeRatio = 1600 / edgeMax# 缩放图像nimg = imgif resizeRatio != 1:width = int(round(width * resizeRatio))height = int(round(height * resizeRatio))nimg = cv2.resize(img, (width, height), interpolation=cv2.INTER_LINEAR)   # 缩放标注框nbboxs = []for bbox in bboxs:nbbox = resizeBox(bbox, resizeRatio)nbboxs.append(nbbox)croppedBoxs, cropImgs =  cropImgSlidingWindow(nimg, cropSize, repetitionRate)cropBoxId = 0for croppedBox, cropImg in zip(croppedBoxs, cropImgs):(xs, ys, xe, ye) = croppedBoxlableNoCropCount = 0for label, nbbox in zip(labels, nbboxs):if solve_coincide(croppedBox, nbbox) < labelAddRate:lableNoCropCount = lableNoCropCount + 1if lableNoCropCount == len(nbboxs):#  写图像cropImgPath = imgSavePath + "/" + imgName + "_" + str(cropBoxId) + ".jpg"cv2.imwrite(cropImgPath, cropImg)cv2.waitKey(1)#  写标注文件cropImgLabelPath = labelSavePath + "/" + imgName + "_" + str(cropBoxId) + ".txt"f_Label = open(cropImgLabelPath, "w+")f_Label.close()#  文件名 + 1cropBoxId = cropBoxId + 1      

yolov5 检测经过裁剪的图像

# detect-crop.pyimport argparse
import time
from pathlib import Path
import glob
import os
import cv2
import torch
import torch.backends.cudnn as cudnn
import numpy as np
from models.experimental import attempt_load
from utils.datasets import LoadStreams, LoadImages
from utils.general import check_img_size, check_requirements, weighted_boxes_fusion, non_max_suppression, apply_classifier, \scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path, save_one_box
from utils.plots import colors, plot_one_box
from utils.torch_utils import select_device, load_classifier, time_synchronizeddef cropImgSlidingWindow(img, cropSize, repetitionRate):"""滑动窗口裁剪图像img:<c, h, w,c> or <h, w>cropSize:裁剪大小,宽高一致repetitionRate:滑动窗口间的重叠率return:裁剪框,裁剪图像"""height = img.shape[1]width = img.shape[2]croppedBoxs = []for i in range(int((height - cropSize * repetitionRate) / (cropSize * (1 - repetitionRate)))):for j in range(int((width - cropSize * repetitionRate) / (cropSize * (1 - repetitionRate)))):ys = int(i * cropSize * (1 - repetitionRate))ye = int(i * cropSize * (1 - repetitionRate)) + cropSizexs = int(j * cropSize * (1 - repetitionRate))xe = int(j * cropSize * (1 - repetitionRate)) + cropSizeif xe > width:print('游动裁剪')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))for i in range(int((height-cropSize*repetitionRate)/(cropSize*(1-repetitionRate)))):ys = int(i * cropSize * (1 - repetitionRate))ye = int(i * cropSize * (1 - repetitionRate)) + cropSizexs = (width - cropSize)xe = widthif xe > width or (xe - xs) != cropSize:print('img.shape:', height, width)print('向前裁剪最后一列')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))#  向前裁剪最后一行for j in range(int((width - cropSize * repetitionRate) / (cropSize * (1 - repetitionRate)))):ys = (height - cropSize)ye = heightxs = int(j * cropSize * (1 - repetitionRate))xe = int(j * cropSize * (1 - repetitionRate)) + cropSizeif xe > width or (xe - xs) != cropSize:print('img.shape:', height, width)print('向前裁剪最后一行')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))#  裁剪右下角ys = (height - cropSize)ye = heightxs = (width - cropSize)xe = widthif xe > width or (xe - xs) != cropSize:print('img.shape:', height, width)print('裁剪右下角')print((xs, ys, xe, ye))croppedBoxs.append((xs, ys, xe, ye))cropImgs = []for croppedBox in croppedBoxs:(xs, ys, xe, ye) = croppedBox#  如果图像是单波段if(len(img.shape) == 2):cropped = img[ys: ye, xs: xe]#  如果图像是多波段else:cropped = img[:, ys: ye, xs: xe]if (ye - ys) != cropped.shape[1] or (xe - xs) != cropped.shape[2]:raise Exception("错误:裁剪图像的宽高与设计N一致")cropImgs.append(cropped)if len(cropImgs) != len(croppedBoxs):raise Exception("错误:裁剪图像数与裁剪框数不一致")return croppedBoxs, cropImgsimg_formats = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'dng', 'webp', 'mpo']  # acceptable image suffixesclass LoadImagesforCrop:  # for inferencedef __init__(self, path, img_size=1600, crop_size=1024):p = str(Path(path).absolute())  # os-agnostic absolute pathif '*' in p:files = sorted(glob.glob(p, recursive=True))  # globelif os.path.isdir(p):files = sorted(glob.glob(os.path.join(p, '*.*')))  # direlif os.path.isfile(p):files = [p]  # fileselse:raise Exception(f'ERROR: {p} does not exist')images = [x for x in files if x.split('.')[-1].lower() in img_formats]ni = len(images)self.img_size = img_sizeself.files = imagesself.nf = ni  # number of filesself.crop_size = crop_sizeself.mode = 'image'assert self.nf > 0, f'No images found in {p}. ' \f'Supported formats are:\nimages: {img_formats}'def __iter__(self):self.count = 0return selfdef __next__(self):if self.count == self.nf:raise StopIterationpath = self.files[self.count]# Read imageself.count += 1img0 = cv2.imread(path)  # BGRassert img0 is not None, 'Image Not Found ' + pathprint(f'image {self.count}/{self.nf} {path}: ', end='')height = img0.shape[0]width = img0.shape[1]resize_ratio = 1edgeMax = min(width, height)if edgeMax < self.crop_size:resize_ratio = self.crop_size / edgeMaxif edgeMax > self.img_size:resize_ratio = self.img_size / edgeMax# 缩放图像nimg = img0if resize_ratio != 1:width = int(round(width * resize_ratio))height = int(round(height * resize_ratio))nimg = cv2.resize(img0, (width, height), interpolation=cv2.INTER_LINEAR)# Convertimg = nimg[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416img = np.ascontiguousarray(img)return path, img, img0, resize_ratiodef __len__(self):return self.nf  # number of filesdef resizeBox(bbox, expandRatio):x1 = bbox[0]*expandRatiox2 = bbox[2]*expandRatioy1 = bbox[1]*expandRatioy2 = bbox[3]*expandRatioreturn [x1, y1, x2, y2]@torch.no_grad()
def detect(weights='yolov5s.pt',  # model.pt path(s)source='data/images',  # file/dir/URL/glob, 0 for webcamresize_target = 1600,  # 图像缩放目标 by wxfcrop_size=1024,  # 裁剪图像宽高大小 by wxfrepetition_rate=0.3,  # 裁剪框间重叠率 by wxfimgsz=640,  # inference size (pixels)conf_thres=0.25,  # confidence thresholdiou_thres=0.45,  # NMS IOU thresholdmax_det=1000,  # maximum detections per imagedevice='',  # cuda device, i.e. 0 or 0,1,2,3 or cpuview_img=False,  # show resultssave_txt=False,  # save results to *.txtsave_conf=False,  # save confidences in --save-txt labelssave_crop=False,  # save cropped prediction boxesnosave=False,  # do not save images/videosclasses=None,  # filter by class: --class 0, or --class 0 2 3agnostic_nms=False,  # class-agnostic NMSaugment=False,  # augmented inferenceupdate=False,  # update all modelsproject='runs/detect',  # save results to project/namename='exp',  # save results to project/nameexist_ok=False,  # existing project/name ok, do not incrementline_thickness=3,  # bounding box thickness (pixels)hide_labels=False,  # hide labelshide_conf=False,  # hide confidenceshalf=False,  # use FP16 half-precision inference):save_img = not nosave and not source.endswith('.txt')  # save inference imageswebcam = source.isnumeric() or source.endswith('.txt') or source.lower().startswith(('rtsp://', 'rtmp://', 'http://', 'https://'))# Directoriessave_dir = increment_path(Path(project) / name, exist_ok=exist_ok)  # increment run(save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir# Initializeset_logging()device = select_device(device)half &= device.type != 'cpu'  # half precision only supported on CUDA# Load modelmodel = attempt_load(weights, map_location=device)  # load FP32 modelnames = model.module.names if hasattr(model, 'module') else model.names  # get class namesif half:model.half()  # to FP16# Second-stage classifierclassify = Falseif classify:modelc = load_classifier(name='resnet101', n=2)  # initializemodelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']).to(device).eval()# Set Dataloadervid_path, vid_writer = None, Nonedataset = LoadImagesforCrop(source, img_size=1600, crop_size=1024)# Run inferenceif device.type != 'cpu':model(torch.zeros(1, 3, imgsz, imgsz).to(device).type_as(next(model.parameters())))  # run oncet0 = time.time()noCheckPaths = []for path, img, im0s, resize_ratio in dataset:# 计算滑动窗口方式的裁剪框和裁剪图像croppedBoxs, cropImgs = cropImgSlidingWindow(img, crop_size, repetition_rate)# 调用模型对裁剪图像进行识别predSrcImg = []for croppedBox, cropImg in zip(croppedBoxs, cropImgs):(xs, ys, xe, ye) = croppedBoximg = torch.from_numpy(cropImg).to(device)img = img.half() if half else img.float()  # uint8 to fp16/32img /= 255.0  # 0 - 255 to 0.0 - 1.0if img.ndimension() == 3:img = img.unsqueeze(0)# Inferencet1 = time_synchronized()pred = model(img, augment=augment)[0]# Apply NMSpred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det)# pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms) # wxf modifyt2 = time_synchronized()for p in pred[0]:p[0] = (p[0] + xs) / resize_ratiop[2] = (p[2] + xs) / resize_ratiop[1] = (p[1] + ys) / resize_ratiop[3] = (p[3] + ys) / resize_ratiopredSrcImg.extend(pred[0])predSrcImg = torch.stack(predSrcImg)wbf_boxes = predSrcImg[:, 0:4].clone() / 4096.0wbf_scores = predSrcImg[:, 4]wbf_classId = predSrcImg[:, 5]wbf_b, wbf_s, wbf_c = weighted_boxes_fusion([wbf_boxes], [wbf_scores], [wbf_classId], iou_thr=0.1, skip_box_thr=0.65, weights=None)wbf_b = wbf_b * 4096wbf_b = torch.from_numpy(wbf_b).cuda()wbf_s = torch.from_numpy(wbf_s).view(len(wbf_s), -1).cuda()wbf_c = torch.from_numpy(wbf_c).view(len(wbf_s), -1).cuda()pred = [torch.cat((wbf_b, wbf_s, wbf_c), 1)]# Apply Classifierif classify:pred = apply_classifier(pred, modelc, img, im0s)# Process detectionsfor i, det in enumerate(pred):  # detections per imageif webcam:  # batch_size >= 1p, s, im0, frame = path[i], f'{i}: ', im0s[i].copy(), dataset.countelse:p, s, im0, frame = path, '', im0s.copy(), getattr(dataset, 'frame', 0)p = Path(p)  # to Pathsave_path = str(save_dir / p.name)  # img.jpgtxt_path = str(save_dir / 'labels' / p.stem) + ('' if dataset.mode == 'image' else f'_{frame}')  # img.txts += '%gx%g ' % img.shape[2:]  # print stringgn = torch.tensor(im0.shape)[[1, 0, 1, 0]]  # normalization gain whwhimc = im0.copy() if save_crop else im0  # for save_cropif len(det):# Rescale boxes from img_size to im0 size# det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()# Print resultsfor c in det[:, -1].unique():n = (det[:, -1] == c).sum()  # detections per classs += f"{n} {names[int(c)]}{'s' * (n > 1)}, "  # add to string# Write resultsfor *xyxy, conf, cls in reversed(det):if save_txt:  # Write to filexywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh# line = (cls, *xywh, conf) if save_conf else (cls, *xywh)  # label formatline = (cls, *xyxy, conf) if save_conf else (cls, *xyxy)  # label format modify by wxfwith open(txt_path + '.txt', 'a') as f:f.write(('%g ' * len(line)).rstrip() % line + '\n')if save_img or save_crop or view_img:  # Add bbox to imagec = int(cls)  # integer classlabel = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}')plot_one_box(xyxy, im0, label=label, color=colors(c, True), line_thickness=line_thickness)if save_crop:save_one_box(xyxy, imc, file=save_dir / 'crops' / names[c] / f'{p.stem}.jpg', BGR=True)else:pass# Print time (inference + NMS)print(f'{s}Done. ({t2 - t1:.3f}s)')if 'person' not in s: # add by wxf:check personprint("NO ret !!!!!!!!!!!!!")noCheckPaths.append(path)print(len(noCheckPaths))# Stream resultsif view_img:cv2.imshow(str(p), im0)cv2.waitKey(1)  # 1 millisecond# Save results (image with detections)if save_img:if dataset.mode == 'image':cv2.imwrite(save_path, im0)if save_txt or save_img:s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ''print(f"Results saved to {save_dir}{s}")if update:strip_optimizer(weights)  # update model (to fix SourceChangeWarning)print(noCheckPaths)print(f'Done. ({time.time() - t0:.3f}s)')if __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')parser.add_argument('--source', type=str, default='data/images', help='file/dir/URL/glob, 0 for webcam')parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)')parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')parser.add_argument('--iou-thres', type=float, default=0.6, help='NMS IoU threshold')parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--view-img', action='store_true', help='show results')parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')parser.add_argument('--nosave', action='store_true', help='do not save images/videos')parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')parser.add_argument('--augment', action='store_true', help='augmented inference')parser.add_argument('--update', action='store_true', help='update all models')parser.add_argument('--project', default='runs/detect', help='save results to project/name')parser.add_argument('--name', default='exp', help='save results to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')opt = parser.parse_args()print(opt)check_requirements(exclude=('tensorboard', 'thop'))detect(**vars(opt))

自己在测试的过程中还是存在一些问题的,主要是检测目标过大,裁剪框只裁剪到部分目标,裁剪方法并不使用与目标面积与原始图像面积比小的情况,另一个就是检测结果框的合并,NMS,感觉也不太好,有空再测测流行的SOFT-NMS WBF DIOU-NMS

训练样本裁剪,背景裁剪,yoloV5裁剪样本检测相关推荐

  1. css 裁剪背景图片,CSS裁剪背景图片的歪招

    标题的背景图片.png 背景图片左右不对称怎么办?(ㄒoㄒ)此处由于其他限制不能裁剪并使用绝对定位. [语法] ①background-clip 属性规定背景的绘制区域. 默认值:border-box ...

  2. yolov5负样本构造:标注区域内随机裁剪等大子区域

    在做目标检测的时候,模型总是会学到一些局部信息,比如总把红色的东西识别成灭火器.为了构造对抗样本,考虑在标注范围内随机裁剪子区域作为负样本. name = 'test'label_path = pat ...

  3. 使用JCrop进行图片裁剪,裁剪js说明,裁剪预览,裁剪上传,裁剪设计的图片处理的工具类和代码

     1.要想制作图片裁剪功能,可以使用网上的裁剪工具JCrop,网址是:https://github.com/tapmodo/Jcrop/ 案例效果如下: 2.引入JCrop的js代码,具体要引入那 ...

  4. php一篇文零基础到制作在线图片编辑网站赚钱(gif压缩、九宫格裁剪、等比裁剪、大小变换)【php华为云实战】

    注意本篇文适用于: 零基础小白想要了解一下php开发或者网站开发的同学(但是注意,零基础你可以通过本篇完成,但是由于是速成会有一些难度,本篇内容由于是速成,有一些额外知识点,不会可以来问我1_bit) ...

  5. PDF如何裁剪页面,PDF裁剪页面的方法

    一个PDF文件的页面有很多的内容,有时候有些内容我们不一定会用到,这个时候就需要裁剪页面了,大家都使用过PDF文件了,那么编辑PDF文件呢,今天小编就来跟大家都来分享一下PDF裁剪页面的方法.有需要的 ...

  6. 如何裁剪音频文件?裁剪音频的方法有什么?

    通常我们在剪辑视频时,为了让视频更加有感染力,我们会加上各种各样的音频丰富视频的内容,而且在选取音频时,一般都是会采用它的高潮部分.那么如何裁剪音频文件来达到想要的效果呢?裁剪音频的方法又有什么?接下 ...

  7. PPT导入视频裁剪后,如何裁剪后的视频另存为保存下来?

    PPT导入视频裁剪后,如何裁剪后的视频另存为保存下来? 步骤: 在PPT中插入视频 鼠标放在视频上,右键–> 剪裁 拖动进度条,选择裁剪的部分 依次选择: 文件–> 信息 --> 压 ...

  8. 如何对GIF动图进行裁剪?GIF怎么裁剪大小?

    相信小伙伴有很多图片裁剪的处理方法,现在随便一款智能手机都可以进行裁剪,但是GIF动图裁剪就需要专门的操作工具了.现在市面上GIF动图工具有很多,到底哪款才好用?今天小编给大家强烈推荐的一款GIF裁剪 ...

  9. php 裁剪图片代码,php裁剪图片代码示例

    一般用户上传头像时,都会让用户自行裁剪图片.那么php怎么实现这个功能呢?php中裁剪图片主要使用gd库的imagecopyresampled方法. 裁剪示例: 图片裁剪区域 其中虚线框内就是要裁剪出 ...

  10. 视频裁剪没声音?解决视频裁剪没声音问题,实现快速裁剪,只需裁剪时间,文件源,一切简单

    这阵子项目上线了,但是更大的麻烦来了..那就是要做视频处理啊....先来解决视频裁剪吧,之前有看过一些视频裁剪的,但是基本上都是没用的,但是还是有了思路,那就是用google推出的mp4parser, ...

最新文章

  1. OSChina 周六乱弹 —— 小明和网关超经典的故事~
  2. 人脸识别技术的那些前世今生
  3. 24、Java并发性和多线程-信号量
  4. ERP的风险及其预防
  5. 服务器建立共享后无法写入文件,Win7 局域网共享问题,XP访问Win7复制或写入一会文件之后出现无法访问,您没有权限,或者说服务器空间不足...
  6. 深入JVM虚拟机(四) Java GC收集器
  7. 非 GUI 模式运行 JMeter 压力测试
  8. 浏览器执行机制探究,图解最直观
  9. python爬虫案例-乌托家家具公司数据爬取
  10. cdr自动排版插件_CDR ymxkDoc插件 支持X72020到以后版本
  11. Openlayer:学习笔记之解析地图组成
  12. 星环inceptor建表公式以及各个表的区别联系
  13. js 中实现 汉字按拼音排序
  14. fan4801开关电源原理图_开关电源各模块原理实图讲解精编版
  15. 办公局域网网络速度变慢分析
  16. aruba AP密码忘记恢复出厂设定
  17. flea-jersey使用之Flea RESTful接口客户端接入
  18. 亚太融媒+ | APEC数据+:“鲸确数集”环保熊猫“小保保”2022拜年 | APEC产业+
  19. phalcon mysql in_phalcon:跟踪sql语句
  20. python计算2的平方代码_Python练习实例46 | 求输入数字的平方,如果平方运算后小于 50 则退出。...

热门文章

  1. 物联网的体系结构和关键技术
  2. html absolute溢出,position:absolute用法(隐藏溢出部分)
  3. 国内缺少一个slideshare
  4. linux mysql backdoor_Mysql BackDoor
  5. 刺猬猫服务器维护2020,刺猬猫杂谈:我认真起来连老板的号都敢封!
  6. 【反思】写在腾讯电话面试之后
  7. 主机耳机没声音win10
  8. 经典作品推荐CLANNAD(含下载、汉化、周边和攻略,真正全语音)
  9. 玩寻仙一个月之我感受
  10. python str转为list,dict,tuple等 eval,exec,