admin 管理员组文章数量: 1087131
滑动窗口切割图片并重定位标注框
在进行目标检测时候,尤其是小目标检测,将图片放大后再进行检测是一个常用的手段,但是方法的后的图像在输入网络的时候,有会被resize带一定得尺寸,这样的我们的放大就没有起到作用。所以有时候我们需要将图片放大后,使用滑动窗口切割产生多幅图像,然后再输入到网络中进行学习。在放大图像和切割图像的过程中,我们需要同时调整标注框。
下面分享一下我写的放大和滑动窗口切割图像的python代码:
#coding:utf-8
import cv2
import os
import codecsdef zomImg(impath, boxes, scale):#print(impath)img = cv2.imread(impath) #G:/head_dataset/head_train/images/UCSD/train_data/vidd1_33_018_f009.jpgheight,width,c = img.shaperesizeImg = cv2.resize(img,(int(width*scale),int(height*scale)),interpolation=cv2.INTER_LINEAR)for i in range(len(boxes)):nw = boxes[i][2] * scalenh = boxes[i][3] * scalecenterx = (boxes[i][0] + boxes[i][2] / 2)centery = (boxes[i][1] + boxes[i][3] / 2)boxes[i][0] = (centerx * scale - nw / 2) if (centerx * scale - nw / 2) > 0 else 0boxes[i][1] = (centery * scale - nh / 2) if (centery * scale - nh / 2) > 0 else 0boxes[i][2] = nwboxes[i][3] = nhreturn resizeImg, boxes#overlap_half=True滑动窗口切图,每次有一半区域重叠,这时候x方向的步长就是窗口宽度的一半,y方向的步长是窗口高度的一半,stridex和stridey参数将不再起作用
def slide_crop(img,kernelw,kernelh,overlap_half=True,stridex=0,stridey=0):height, width, _ = img.shapeif overlap_half:stridex = kernelw / 2stridey = kernelh / 2img_list = []corner_list = []stepx = int(width / stridex)stepy = int(height / stridey)for r in range(stepy-1):startx = 0starty = r * strideyfor c in range(stepx-1):startx = c*stridexcorner_list.append((startx,starty))img_list.append(img[starty:starty+kernelh,startx:startx+kernelw,:])return img_list,corner_listdef show_box(img,boxes):for box in boxes:cv2.rectangle(img, (box[0],box[1]), (box[0]+box[2],box[1]+box[3]), (0, 255, 0), 1)cv2.imshow('image',img)cv2.waitKey(0)def crop_dataset(imgpath, scale, annotation, cropAnno, savePath,dataset,sub=''):savePath = os.path.join(savePath, dataset+sub+'_crop_'+str(scale))if os.path.exists(savePath) is False:os.mkdir(savePath)with codecs.open(annotation,'r',encoding='utf-8') as f:annotationList = f.readlines()count = 0with codecs.open(os.path.join(cropAnno,'head_train_'+dataset+'_crop_'+str(scale)+'_bbx_gt.txt'),'w',encoding='utf-8') as f:while count < len(annotationList):name = annotationList[count].strip('\n')print(name)count += 1num = int(annotationList[count])count += 1boxes = []for i in range(num):box = []for point in annotationList[count].split(' ')[0:-1]:box.append(int(point))boxes.append(box)count += 1resizeImg, boxes = zomImg(imgpath +'/'+ name, boxes, scale)#show_box(resizeImg, boxes)height, width, _ = resizeImg.shapekernelw = width / scalekernelh = height / scaleimg_list, corner_list = slide_crop(resizeImg,kernelw,kernelh,overlap_half=True)boxes_list = [[] for i in range(len(corner_list))]for i, (x, y) in enumerate(corner_list):for box in boxes:if(box[0] >= x and box[1] >= y and (box[0]+box[2]) <= (x + kernelw) and (box[1]+box[3]) <= (y + kernelh)): #被切开的标注框过滤掉rescale_box = [] #注意python中引用rescale_box.append(box[0] - x)rescale_box.append(box[1] - y)rescale_box.append(box[2])rescale_box.append(box[3])boxes_list[i].append(rescale_box)name_split = name.split('/')i = 0name_list = []for img in img_list:img_name = name.split('/')[1] + '/' + name_split[2].split('.')[0] + '_' + str(i) + '.' + name_split[2].split('.')[-1]#print(savePath + '/' +name.split('/')[1]+ '/' + name_split[2].split('.')[0]+'_'+str(i)+'.'+name_split[2].split('.')[-1])#cv2.imwrite(savePath + '/'+name.split('/')[1]+'/' +name_split[2].split('.')[0]+'_'+str(i)+'.'+name_split[2].split('.')[-1],img)print(savePath + '/' + img_name)cv2.imwrite(savePath + '/' + img_name, img)name_list.append(dataset+'_crop_'+str(scale)+'/'+img_name)i += 1for i,img_name in enumerate(name_list):boxes = boxes_list[i]if len(boxes) == 0: #没有目标的图片不写标注文件continuef.write(img_name+'\n')f.write(str(len(boxes)) + '\n')for box in boxes:f.write(str(box[0])+' '+str(box[1])+' '+str(box[2])+' '+str(box[3])+'\n')if __name__ == '__main__':dataset = 'Part_A'scale = 2imgpath = 'G:/head_dataset/head_train/images'annotation = 'G:/head_dataset/head_split/head_train_' + dataset + '_bbx_gt.txt'cropAnno = 'G:/head_dataset/head_crop/split/'savePath = 'G:/head_dataset/head_crop/images/'crop_dataset(imgpath, scale, annotation, cropAnno, savePath, dataset, sub='')
原图的标注文件head_train_’ + dataset + '_bbx_gt.txt是这种形式的:
Part_B/val_data/IMG_335
23 #标注框的个数
0 540 96 96 # x,y,w,h
96 652 126 126
85 265 78 78
215 294 96 96
289 266 109 109
392 378 109 109
859 702 93 93
502 178 57 57
301 153 60 60
220 150 47 47
200 12 26 26
254 17 26 26
278 12 26 26
290 60 26 26
315 73 26 26
348 69 38 38
431 62 45 45
672 79 52 52
294 0 26 26
324 1 26 26
652 129 52 52
630 87 52 52
402 7 38 38
可视化后是这样的:
切割放大两倍后滑动切割,每次滑动重叠一半会产生9张图,产生的标注框是这样的:
本文标签: 滑动窗口切割图片并重定位标注框
版权声明:本文标题:滑动窗口切割图片并重定位标注框 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1687273019a83701.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论