生成anchor框,并剔除超出原图范围的无效框
def init_anchor ( img_size= 800 , sub_sample= 16 ) :
ratios = [ 0.5 , 1 , 2 ]
anchor_scales = [ 8 , 16 , 32 ]
feature_size = ( img_size // sub_sample)
ctr_x = np. arange( sub_sample, ( feature_size + 1 ) * sub_sample, sub_sample)
ctr_y = np. arange( sub_sample, ( feature_size + 1 ) * sub_sample, sub_sample)
index = 0
ctr = dict ( )
for x in range ( len ( ctr_x) ) :
for y in range ( len ( ctr_y) ) :
ctr[ index] = [ - 1 , - 1 ]
ctr[ index] [ 1 ] = ctr_x[ x] - 8
ctr[ index] [ 0 ] = ctr_y[ y] - 8
index += 1
anchors = np. zeros( ( ( feature_size * feature_size * 9 ) , 4 ) )
index = 0
for c in ctr:
ctr_y, ctr_x = ctr[ c]
for i in range ( len ( ratios) ) :
for j in range ( len ( anchor_scales) ) :
h = sub_sample * anchor_scales[ j] * np. sqrt( ratios[ i] )
w = sub_sample * anchor_scales[ j] * np. sqrt( 1 . / ratios[ i] )
anchors[ index, 0 ] = ctr_y - h / 2 .
anchors[ index, 1 ] = ctr_x - w / 2 .
anchors[ index, 2 ] = ctr_y + h / 2 .
anchors[ index, 3 ] = ctr_x + w / 2 .
index += 1
valid_anchor_index = np. where(
( anchors[ : , 0 ] >= 0 ) &
( anchors[ : , 1 ] >= 0 ) &
( anchors[ : , 2 ] <= 800 ) &
( anchors[ : , 3 ] <= 800 )
) [ 0 ]
valid_anchor_boxes = anchors[ valid_anchor_index]
return anchors, valid_anchor_boxes, valid_anchor_index
计算每个valid anchor boxes与每个bbox的IoU
def compute_iou ( valid_anchor_boxes, bbox) :
valid_anchor_num = len ( valid_anchor_boxes)
ious = np. empty( ( valid_anchor_num, 2 ) , dtype= np. float32)
ious. fill( 0 )
for num1, i in enumerate ( valid_anchor_boxes) :
ya1, xa1, ya2, xa2 = i
anchor_area = ( ya2 - ya1) * ( xa2 - xa1)
for num2, j in enumerate ( bbox) :
yb1, xb1, yb2, xb2 = j
box_area = ( yb2 - yb1) * ( xb2 - xb1)
inter_x1 = max ( [ xb1, xa1] )
inter_y1 = max ( [ yb1, ya1] )
inter_x2 = min ( [ xb2, xa2] )
inter_y2 = min ( [ yb2, ya2] )
if ( inter_x1 < inter_x2) and ( inter_y1 < inter_y2) :
iter_area = ( inter_y2 - inter_y1) * ( inter_x2 - inter_x1)
iou = iter_area / ( anchor_area + box_area - iter_area)
else :
iou = 0 .
ious[ num1, num2] = iou
return ious
enumerate使用
https://blog.csdn.net/churximi/article/details/51648388?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
分配正负样本
def get_pos_neg_sample ( ious, valid_anchor_len, pos_iou_threshold= 0.7 , neg_iou_threshold= 0.3 , pos_ratio= 0.5 , n_sample= 256 ) :
gt_argmax_ious = ious. argmax( axis= 0 )
gt_max_ious = ious[ gt_argmax_ious, np. arange( ious. shape[ 1 ] ) ]
argmax_ious = ious. argmax( axis= 1 )
max_ious = ious[ np. arange( valid_anchor_len) , argmax_ious]
gt_argmax_ious = np. where( ious == gt_max_ious) [ 0 ]
label = np. empty( ( valid_anchor_len, ) , dtype= np. int32)
label. fill( - 1 )
label[ max_ious < neg_iou_threshold] = 0
label[ gt_argmax_ious] = 1
label[ max_ious >= pos_iou_threshold] = 1
n_pos = pos_ratio * n_sample
pos_index = np. where( label == 1 ) [ 0 ]
if len ( pos_index) > n_pos:
disable_index = np. random. choice( pos_index, size= ( len ( pos_index) - n_pos) , replace= False )
label[ disable_index] = - 1
n_neg = n_sample - np. sum ( label == 1 )
neg_index = np. where( label == 0 ) [ 0 ]
if len ( neg_index) > n_neg:
disable_index = np. random. choice( neg_index, size= ( len ( neg_index) - n_neg) , replace= False )
label[ disable_index] = - 1
return label, argmax_ious
np.argmax使用
https://blog.csdn.net/zjm750617105/article/details/51318248?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158364929319725256755105%2522%252C%2522scm%2522%253A%252220140713.130056874…%2522%257D&request_id=158364929319725256755105&biz_id=0&utm_source=distribute.pc_search_result.none-task
np.where()使用
https://blog.csdn.net/sinat_41939868/article/details/89469803?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158365022819724846419015%2522%252C%2522scm%2522%253A%252220140713.130056874…%2522%257D&request_id=158365022819724846419015&biz_id=0&utm_source=distribute.pc_search_result.none-task
边框回归系数计算
def get_coefficient ( anchor, bbox) :
height = anchor[ : , 2 ] - anchor[ : , 0 ]
width = anchor[ : , 3 ] - anchor[ : , 1 ]
ctr_y = anchor[ : , 0 ] + 0.5 * height
ctr_x = anchor[ : , 1 ] + 0.5 * width
base_height = bbox[ : , 2 ] - bbox[ : , 0 ]
base_width = bbox[ : , 3 ] - bbox[ : , 1 ]
base_ctr_y = bbox[ : , 0 ] + 0.5 * base_height
base_ctr_x = bbox[ : , 1 ] + 0.5 * base_width
eps = np. finfo( height. dtype) . eps
height = np. maximum( height, eps)
width = np. maximum( width, eps)
dy = ( base_ctr_y - ctr_y) / height
dx = ( base_ctr_x - ctr_x) / width
dh = np. log( base_height / height)
dw = np. log( base_width / width)
gt_roi_locs = np. vstack( ( dy, dx, dh, dw) ) . transpose( )
return gt_roi_locs
np.vstack()和np.hstack()
https://blog.csdn.net/nanhuaibeian/article/details/100597342?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158366297919724846406649%2522%252C%2522scm%2522%253A%252220140713.130056874…%2522%257D&request_id=158366297919724846406649&biz_id=0&utm_source=distribute.pc_search_result.none-task
网络搭建make_layers()
def _make_layers ( self, cfg) :
layers = [ ]
in_channels = 3
for x in cfg:
if x == 'M' :
layers += [ nn. MaxPool2d( kernel_size= 2 , stride= 2 ) ]
else :
layers += [ nn. Conv2d( in_channels, x, kernel_size= 3 , padding= 1 ) ,
nn. BatchNorm2d( x) ,
nn. ReLU( inplace= True ) ]
in_channels = x
return nn. Sequential( * layers)
nn.Sequential(*layers)
https://blog.csdn.net/u013548568/article/details/80294708