Python如何实现随机从图像中获取多个patch
导读:本文共3853.5字符,通常情况下阅读需要13分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要:接下来,请跟着小编一起来学习吧!经常有一些图像任务需要从一张大图中截取固定大小的patch来进行训练。这里面常常存在下面几个问题:patch的位置尽可能随机,不然数据丰富性可能不够,容易引起过拟合如果原图较大,读图带来的IO开销可能会非常大,影响训练速度,所以最好一次能够截取多个patch我们经常不太希望因为随机性的存在而使得图像中某些区域没有被覆盖到,所以还需要注意patch位置的覆盖程度基于以... ...
目录
(为您整理了一些要点),点击可以直达。接下来,请跟着小编一起来学习吧!
经常有一些图像任务需要从一张大图中截取固定大小的patch来进行训练。这里面常常存在下面几个问题:
patch的位置尽可能随机,不然数据丰富性可能不够,容易引起过拟合
如果原图较大,读图带来的IO开销可能会非常大,影响训练速度,所以最好一次能够截取多个patch
我们经常不太希望因为随机性的存在而使得图像中某些区域没有被覆盖到,所以还需要注意patch位置的覆盖程度
基于以上问题,我们可以使用下面的策略从图像中获取位置随机的多个patch:
以固定的stride获取所有patch的左上角坐标
对左上角坐标进行随机扰动
对patch的左上角坐标加上宽和高得到右下角坐标
检查patch的坐标是否超出图像边界,如果超出则将其收进来,收的过程应保证patch尺寸不变
加入ROI(Region Of Interest)功能,也就是说patch不一定非要在整张图中获取,而是可以指定ROI区域
下面是实现代码和例子:
注意下面代码只是获取了patch的bounding box,并没有把patch截取出来。
#--coding:utf-8--
importcv2
importnumpyasnpdefget_random_patch_bboxes(image,bbox_size,stride,jitter,roi_bbox=None):
"""
GeneraterandompatchboundingboxesforaimagearoundROIregionParameters
image:imagedatareadbyopencv,shapeis[H,W,C]
bbox_size:sizeofpatchbbox,onedigitoralist/tuplecontainingtwo
digits,definedby(width,height)
stride:stridebetweenadjacentbboxes(beforejitter),onedigitora
list/tuplecontainingtwodigits,definedby(x,y)
jitter:jittersizeforevenlydistributedbboxes,onedigitora
list/tuplecontainingtwodigits,definedby(x,y)
roi_bbox:roiregion,definedby[xmin,ymin,xmax,ymax],defaultiswhole
imageregionReturns
patch_bboxes:randomlydistributedpatchboundingboxes,nx4numpyarray.
Eachboundingboxisdefinedby[xmin,ymin,xmax,ymax]
"""
height,width=image.shape[:2]
bbox_size=_process_geometry_param(bbox_size,min_value=1)
stride=_process_geometry_param(stride,min_value=1)
jitter=_process_geometry_param(jitter,min_value=0)ifbbox_size[0]>widthorbbox_size[1]>height:
raiseValueError('box_sizemustbe<=imagesize')ifroi_bboxisNone:
roi_bbox=[0,0,width,height]tlisfortop-left,brisforbottom-right
tl_x,tl_y=_get_top_left_points(roi_bbox,bbox_size,stride,jitter)
br_x=tl_x+bbox_size[0]
br_y=tl_y+bbox_size[1]shrinkbottom-rightpointstoavoidexceedingimageborder
br_x[br_x>width]=width
br_y[br_y>height]=heightshrinktop-leftpointstoavoidexceedingimageborder
tl_x=br_x-bbox_size[0]
tl_y=br_y-bbox_size[1]
tl_x[tl_x<0]=0
tl_y[tl_y<0]=0computebottom-rightpointsagain
br_x=tl_x+bbox_size[0]
br_y=tl_y+bbox_size[1]patch_bboxes=np.concatenate((tl_x,tl_y,br_x,br_y),axis=1)
returnpatch_bboxesdef_process_geometry_param(param,min_value):
"""
Processandcheckparam,whichmustbeonedigitoralist/tuplecontaining
twodigits,anditsvaluemustbe>=min_valueParameters
param:parametertobeprocessed
min_value:minvalueforparamReturns
param:paramafterprocessing
"""
ifisinstance(param,(int,float))or\
isinstance(param,np.ndarray)andparam.size==1:
param=int(np.round(param))
param=[param,param]
else:
iflen(param)!=2:
raiseValueError('parammustbeonedigitortwodigits')
param=[int(np.round(param[0])),int(np.round(param[1]))]checkdatarangeusingmin_value
ifnot(param[0]>=min_valueandparam[1]>=min_value):
raiseValueError('parammustbe>=min_value(%d)'%min_value)
returnparamdef_get_top_left_points(roi_bbox,bbox_size,stride,jitter):
"""
Generatetop-leftpointsforboundingboxesParameters
roi_bbox:roiregion,definedby[xmin,ymin,xmax,ymax]
bbox_size:sizeofpatchbbox,alist/tuplecontainingtwodigits,defined
by(width,height)
stride:stridebetweenadjacentbboxes(beforejitter),alist/tuple
containingtwodigits,definedby(x,y)
jitter:jittersizeforevenlydistributedbboxes,alist/tuplecontaining
twodigits,definedby(x,y)Returns
tl_x:xcoordinatesoftop-leftpoints,nx1numpyarray
tl_y:ycoordinatesoftop-leftpoints,nx1numpyarray
"""
xmin,ymin,xmax,ymax=roi_bbox
roi_width=xmax-xmin
roi_height=ymax-ymingettheoffsetbetweenthefirsttop-leftpointofpatchboxandthe
top-leftpointofroi_bbox
offset_x=np.arange(0,roi_width,stride[0])[-1]+bbox_size[0]
offset_y=np.arange(0,roi_height,stride[1])[-1]+bbox_size[1]
offset_x=(offset_x-roi_width)//2
offset_y=(offset_y-roi_height)//2getthecoordinatesofalltop-leftpoints
tl_x=np.arange(xmin,xmax,stride[0])-offset_x
tl_y=np.arange(ymin,ymax,stride[1])-offset_y
tl_x,tl_y=np.meshgrid(tl_x,tl_y)
tl_x=np.reshape(tl_x,[-1,1])
tl_y=np.reshape(tl_y,[-1,1])jitterthecoordinatesofalltop-leftpoints
tl_x+=np.random.randint(-jitter[0],jitter[0]+1,size=tl_x.shape)
tl_y+=np.random.randint(-jitter[1],jitter[1]+1,size=tl_y.shape)
returntl_x,tl_yifname=='main':
image=cv2.imread('1.bmp')
patch_bboxes=get_random_patch_bboxes(
image,
bbox_size=[64,96],
stride=[128,128],
jitter=[32,32],
roi_bbox=[500,200,1500,800])colors=[
(255,0,0),
(0,255,0),
(0,0,255),
(255,255,0),
(255,0,255),
(0,255,255)]
color_idx=0forbboxinpatch_bboxes:
color_idx=color_idx%6
pt1=(bbox[0],bbox[1])
pt2=(bbox[2],bbox[3])
cv2.rectangle(image,pt1,pt2,color=colors[color_idx],thickness=2)
color_idx+=1cv2.namedWindow('image',0)
cv2.imshow('image',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('image.png',image)
在实际应用中可以进一步增加一些简单的功能:
1.根据位置增加一些过滤功能。比如说太靠近边缘的给剔除掉,有些算法可能有比较严重的边缘效应,所以此时我们可能不太想要边缘的数据加入训练
2.也可以根据某些简单的算法策略进行过滤。比如在超分辨率这样的任务中,我们可能一般不太关心面积非常大的平坦区域,比如纯色墙面,大片天空等,此时可以使用方差进行过滤
3.设置最多保留数目。有时候原图像的大小可能有很大差异,此时利用上述方法得到的patch数量也就随之有很大的差异,然而为了保持训练数据的均衡性,我们可以设置最多保留数目,为了确保覆盖程度,一般需要在截取之前对patch进行shuffle,或者计算stride
若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!Python如何实现随机从图像中获取多个patch的详细内容,希望对您有所帮助,信息来源于网络。