@ -64,6 +64,7 @@ class RegionLayerImpl CV_FINAL : public RegionLayer
public :
int coords , classes , anchors , classfix ;
float thresh , nmsThreshold , scale_x_y ;
int new_coords ;
bool useSoftmax , useLogistic ;
# ifdef HAVE_OPENCL
UMat blob_umat ;
@ -83,6 +84,7 @@ public:
useLogistic = params . get < bool > ( " logistic " , false ) ;
nmsThreshold = params . get < float > ( " nms_threshold " , 0.4 ) ;
scale_x_y = params . get < float > ( " scale_x_y " , 1.0 ) ; // Yolov4
new_coords = params . get < int > ( " new_coords " , 0 ) ; // Yolov4x-mish
CV_Assert ( nmsThreshold > = 0. ) ;
CV_Assert ( coords = = 4 ) ;
@ -113,7 +115,7 @@ public:
{
# ifdef HAVE_DNN_NGRAPH
if ( backendId = = DNN_BACKEND_INFERENCE_ENGINE_NGRAPH )
return INF_ENGINE_VER_MAJOR_GE ( INF_ENGINE_RELEASE_2020_2 ) & & preferableTarget ! = DNN_TARGET_MYRIAD ;
return INF_ENGINE_VER_MAJOR_GE ( INF_ENGINE_RELEASE_2020_2 ) & & preferableTarget ! = DNN_TARGET_MYRIAD & & new_coords = = 0 ;
# endif
return backendId = = DNN_BACKEND_OPENCV ;
}
@ -259,26 +261,28 @@ public:
const float * srcData = inpBlob . ptr < float > ( ) ;
float * dstData = outBlob . ptr < float > ( ) ;
// logistic activation for t0, for each grid cell (X x Y x Anchor-index)
for ( int i = 0 ; i < batch_size * rows * cols * anchors ; + + i ) {
int index = cell_size * i ;
float x = srcData [ index + 4 ] ;
dstData [ index + 4 ] = logistic_activate ( x ) ; // logistic activation
}
if ( useSoftmax ) { // Yolo v2
if ( new_coords = = 0 ) {
// logistic activation for t0, for each grid cell (X x Y x Anchor-index)
for ( int i = 0 ; i < batch_size * rows * cols * anchors ; + + i ) {
int index = cell_size * i ;
softmax_activate ( srcData + index + 5 , classes , 1 , dstData + index + 5 ) ;
float x = srcData [ index + 4 ] ;
dstData [ index + 4 ] = logistic_activate ( x ) ; // logistic activation
}
}
else if ( useLogistic ) { // Yolo v3
for ( int i = 0 ; i < batch_size * rows * cols * anchors ; + + i ) {
int index = cell_size * i ;
const float * input = srcData + index + 5 ;
float * output = dstData + index + 5 ;
for ( int c = 0 ; c < classes ; + + c )
output [ c ] = logistic_activate ( input [ c ] ) ;
if ( useSoftmax ) { // Yolo v2
for ( int i = 0 ; i < batch_size * rows * cols * anchors ; + + i ) {
int index = cell_size * i ;
softmax_activate ( srcData + index + 5 , classes , 1 , dstData + index + 5 ) ;
}
}
else if ( useLogistic ) { // Yolo v3
for ( int i = 0 ; i < batch_size * rows * cols * anchors ; + + i ) {
int index = cell_size * i ;
const float * input = srcData + index + 5 ;
float * output = dstData + index + 5 ;
for ( int c = 0 ; c < classes ; + + c )
output [ c ] = logistic_activate ( input [ c ] ) ;
}
}
}
for ( int b = 0 ; b < batch_size ; + + b )
@ -290,20 +294,46 @@ public:
int index = ( y * cols + x ) * anchors + a ; // index for each grid-cell & anchor
int p_index = index_sample_offset + index * cell_size + 4 ;
float scale = dstData [ p_index ] ;
if ( classfix = = - 1 & & scale < .5 ) scale = 0 ; // if(t0 < 0.5) t0 = 0;
if ( classfix = = - 1 & & scale < .5 )
{
scale = 0 ; // if(t0 < 0.5) t0 = 0;
}
int box_index = index_sample_offset + index * cell_size ;
float x_tmp = ( logistic_activate ( srcData [ box_index + 0 ] ) - 0.5f ) * scale_x_y + 0.5f ;
float y_tmp = ( logistic_activate ( srcData [ box_index + 1 ] ) - 0.5f ) * scale_x_y + 0.5f ;
dstData [ box_index + 0 ] = ( x + x_tmp ) / cols ;
dstData [ box_index + 1 ] = ( y + y_tmp ) / rows ;
dstData [ box_index + 2 ] = exp ( srcData [ box_index + 2 ] ) * biasData [ 2 * a ] / wNorm ;
dstData [ box_index + 3 ] = exp ( srcData [ box_index + 3 ] ) * biasData [ 2 * a + 1 ] / hNorm ;
int class_index = index_sample_offset + index * cell_size + 5 ;
for ( int j = 0 ; j < classes ; + + j ) {
float prob = scale * dstData [ class_index + j ] ; // prob = IoU(box, object) = t0 * class-probability
dstData [ class_index + j ] = ( prob > thresh ) ? prob : 0 ; // if (IoU < threshold) IoU = 0;
if ( new_coords = = 1 ) {
float x_tmp = ( srcData [ box_index + 0 ] - 0.5f ) * scale_x_y + 0.5f ;
float y_tmp = ( srcData [ box_index + 1 ] - 0.5f ) * scale_x_y + 0.5f ;
dstData [ box_index + 0 ] = ( x + x_tmp ) / cols ;
dstData [ box_index + 1 ] = ( y + y_tmp ) / rows ;
dstData [ box_index + 2 ] = ( srcData [ box_index + 2 ] ) * ( srcData [ box_index + 2 ] ) * 4 * biasData [ 2 * a ] / wNorm ;
dstData [ box_index + 3 ] = ( srcData [ box_index + 3 ] ) * ( srcData [ box_index + 3 ] ) * 4 * biasData [ 2 * a + 1 ] / hNorm ;
scale = srcData [ p_index ] ;
if ( classfix = = - 1 & & scale < thresh )
{
scale = 0 ; // if(t0 < 0.5) t0 = 0;
}
int class_index = index_sample_offset + index * cell_size + 5 ;
for ( int j = 0 ; j < classes ; + + j ) {
float prob = scale * srcData [ class_index + j ] ; // prob = IoU(box, object) = t0 * class-probability
dstData [ class_index + j ] = ( prob > thresh ) ? prob : 0 ; // if (IoU < threshold) IoU = 0;
}
}
else
{
float x_tmp = ( logistic_activate ( srcData [ box_index + 0 ] ) - 0.5f ) * scale_x_y + 0.5f ;
float y_tmp = ( logistic_activate ( srcData [ box_index + 1 ] ) - 0.5f ) * scale_x_y + 0.5f ;
dstData [ box_index + 0 ] = ( x + x_tmp ) / cols ;
dstData [ box_index + 1 ] = ( y + y_tmp ) / rows ;
dstData [ box_index + 2 ] = exp ( srcData [ box_index + 2 ] ) * biasData [ 2 * a ] / wNorm ;
dstData [ box_index + 3 ] = exp ( srcData [ box_index + 3 ] ) * biasData [ 2 * a + 1 ] / hNorm ;
int class_index = index_sample_offset + index * cell_size + 5 ;
for ( int j = 0 ; j < classes ; + + j ) {
float prob = scale * dstData [ class_index + j ] ; // prob = IoU(box, object) = t0 * class-probability
dstData [ class_index + j ] = ( prob > thresh ) ? prob : 0 ; // if (IoU < threshold) IoU = 0;
}
}
}
if ( nmsThreshold > 0 ) {