@ -42,9 +42,8 @@
//M*/
# include "test_precomp.hpp"
# include "npy_blob.hpp"
# include <opencv2/dnn/shape_utils.hpp>
# include <opencv2/core/ocl.hpp>
# include <opencv2/ts/ocl_test.hpp>
namespace opencv_test { namespace {
@ -66,238 +65,125 @@ TEST(Test_Darknet, read_yolo_voc)
ASSERT_FALSE ( net . empty ( ) ) ;
}
OCL_TEST ( Reproducibility_TinyYoloVoc , Accuracy )
// Test object detection network from Darknet framework.
static void testDarknetModel ( const std : : string & cfg , const std : : string & weights ,
const std : : vector < cv : : String > & outNames ,
const std : : vector < int > & refClassIds ,
const std : : vector < float > & refConfidences ,
const std : : vector < Rect2d > & refBoxes ,
int targetId , float confThreshold = 0.24 )
{
Net net ;
{
const string cfg = findDataFile ( " dnn/tiny-yolo-voc.cfg " , false ) ;
const string model = findDataFile ( " dnn/tiny-yolo-voc.weights " , false ) ;
net = readNetFromDarknet ( cfg , model ) ;
ASSERT_FALSE ( net . empty ( ) ) ;
}
net . setPreferableBackend ( DNN_BACKEND_DEFAULT ) ;
net . setPreferableTarget ( DNN_TARGET_OPENCL ) ;
// dog416.png is dog.jpg that resized to 416x416 in the lossless PNG format
Mat sample = imread ( _tf ( " dog416.png " ) ) ;
ASSERT_TRUE ( ! sample . empty ( ) ) ;
Size inputSize ( 416 , 416 ) ;
if ( sample . size ( ) ! = inputSize )
resize ( sample , sample , inputSize ) ;
net . setInput ( blobFromImage ( sample , 1 / 255.F ) , " data " ) ;
Mat out = net . forward ( " detection_out " ) ;
Mat detection ;
const float confidenceThreshold = 0.24 ;
for ( int i = 0 ; i < out . rows ; i + + ) {
const int probability_index = 5 ;
const int probability_size = out . cols - probability_index ;
float * prob_array_ptr = & out . at < float > ( i , probability_index ) ;
size_t objectClass = std : : max_element ( prob_array_ptr , prob_array_ptr + probability_size ) - prob_array_ptr ;
float confidence = out . at < float > ( i , ( int ) objectClass + probability_index ) ;
if ( confidence > confidenceThreshold )
detection . push_back ( out . row ( i ) ) ;
Mat inp = blobFromImage ( sample , 1.0 / 255 , Size ( 416 , 416 ) , Scalar ( ) , true , false ) ;
Net net = readNet ( findDataFile ( " dnn/ " + cfg , false ) ,
findDataFile ( " dnn/ " + weights , false ) ) ;
net . setPreferableTarget ( targetId ) ;
net . setInput ( inp ) ;
std : : vector < Mat > outs ;
net . forward ( outs , outNames ) ;
std : : vector < int > classIds ;
std : : vector < float > confidences ;
std : : vector < Rect2d > boxes ;
for ( int i = 0 ; i < outs . size ( ) ; + + i )
{
Mat & out = outs [ i ] ;
for ( int j = 0 ; j < out . rows ; + + j )
{
Mat scores = out . row ( j ) . colRange ( 5 , out . cols ) ;
double confidence ;
Point maxLoc ;
minMaxLoc ( scores , 0 , & confidence , 0 , & maxLoc ) ;
float * detection = out . ptr < float > ( j ) ;
double centerX = detection [ 0 ] ;
double centerY = detection [ 1 ] ;
double width = detection [ 2 ] ;
double height = detection [ 3 ] ;
boxes . push_back ( Rect2d ( centerX - 0.5 * width , centerY - 0.5 * height ,
width , height ) ) ;
confidences . push_back ( confidence ) ;
classIds . push_back ( maxLoc . x ) ;
}
}
normAssertDetections ( refClassIds , refConfidences , refBoxes , classIds ,
confidences , boxes , " " , confThreshold , 8e-5 , 3e-5 ) ;
}
// obtained by: ./darknet detector test ./cfg/voc.data ./cfg/tiny-yolo-voc.cfg ./tiny-yolo-voc.weights -thresh 0.24 ./dog416.png
// There are 2 objects (6-car, 11-dog) with 25 values for each:
// { relative_center_x, relative_center_y, relative_width, relative_height, unused_t0, probability_for_each_class[20] }
float ref_array [ ] = {
0.736762F , 0.239551F , 0.315440F , 0.160779F , 0.761977F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.761967F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.287486F , 0.653731F , 0.315579F , 0.534527F , 0.782737F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.780595F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F
} ;
const int number_of_objects = 2 ;
Mat ref ( number_of_objects , sizeof ( ref_array ) / ( number_of_objects * sizeof ( float ) ) , CV_32FC1 , & ref_array ) ;
typedef testing : : TestWithParam < DNNTarget > Test_Darknet_nets ;
normAssert ( ref , detection ) ;
TEST_P ( Test_Darknet_nets , YoloVoc )
{
int targetId = GetParam ( ) ;
std : : vector < cv : : String > outNames ( 1 , " detection_out " ) ;
std : : vector < int > classIds ( 3 ) ;
std : : vector < float > confidences ( 3 ) ;
std : : vector < Rect2d > boxes ( 3 ) ;
classIds [ 0 ] = 6 ; confidences [ 0 ] = 0.750469f ; boxes [ 0 ] = Rect2d ( 0.577374 , 0.127391 , 0.325575 , 0.173418 ) ; // a car
classIds [ 1 ] = 1 ; confidences [ 1 ] = 0.780879f ; boxes [ 1 ] = Rect2d ( 0.270762 , 0.264102 , 0.461713 , 0.48131 ) ; // a bycicle
classIds [ 2 ] = 11 ; confidences [ 2 ] = 0.901615f ; boxes [ 2 ] = Rect2d ( 0.1386 , 0.338509 , 0.282737 , 0.60028 ) ; // a dog
testDarknetModel ( " yolo-voc.cfg " , " yolo-voc.weights " , outNames ,
classIds , confidences , boxes , targetId ) ;
}
TEST ( Reproducibility_TinyYoloVoc , Accuracy )
TEST_P ( Test_Darknet_nets , TinyYoloVoc )
{
Net net ;
{
const string cfg = findDataFile ( " dnn/tiny-yolo-voc.cfg " , false ) ;
const string model = findDataFile ( " dnn/tiny-yolo-voc.weights " , false ) ;
net = readNetFromDarknet ( cfg , model ) ;
ASSERT_FALSE ( net . empty ( ) ) ;
}
// dog416.png is dog.jpg that resized to 416x416 in the lossless PNG format
Mat sample = imread ( _tf ( " dog416.png " ) ) ;
ASSERT_TRUE ( ! sample . empty ( ) ) ;
Size inputSize ( 416 , 416 ) ;
if ( sample . size ( ) ! = inputSize )
resize ( sample , sample , inputSize ) ;
net . setInput ( blobFromImage ( sample , 1 / 255.F ) , " data " ) ;
Mat out = net . forward ( " detection_out " ) ;
Mat detection ;
const float confidenceThreshold = 0.24 ;
for ( int i = 0 ; i < out . rows ; i + + ) {
const int probability_index = 5 ;
const int probability_size = out . cols - probability_index ;
float * prob_array_ptr = & out . at < float > ( i , probability_index ) ;
size_t objectClass = std : : max_element ( prob_array_ptr , prob_array_ptr + probability_size ) - prob_array_ptr ;
float confidence = out . at < float > ( i , ( int ) objectClass + probability_index ) ;
if ( confidence > confidenceThreshold )
detection . push_back ( out . row ( i ) ) ;
}
// obtained by: ./darknet detector test ./cfg/voc.data ./cfg/tiny-yolo-voc.cfg ./tiny-yolo-voc.weights -thresh 0.24 ./dog416.png
// There are 2 objects (6-car, 11-dog) with 25 values for each:
// { relative_center_x, relative_center_y, relative_width, relative_height, unused_t0, probability_for_each_class[20] }
float ref_array [ ] = {
0.736762F , 0.239551F , 0.315440F , 0.160779F , 0.761977F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.761967F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.287486F , 0.653731F , 0.315579F , 0.534527F , 0.782737F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.780595F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F
} ;
const int number_of_objects = 2 ;
Mat ref ( number_of_objects , sizeof ( ref_array ) / ( number_of_objects * sizeof ( float ) ) , CV_32FC1 , & ref_array ) ;
normAssert ( ref , detection ) ;
int targetId = GetParam ( ) ;
std : : vector < cv : : String > outNames ( 1 , " detection_out " ) ;
std : : vector < int > classIds ( 2 ) ;
std : : vector < float > confidences ( 2 ) ;
std : : vector < Rect2d > boxes ( 2 ) ;
classIds [ 0 ] = 6 ; confidences [ 0 ] = 0.761967f ; boxes [ 0 ] = Rect2d ( 0.579042 , 0.159161 , 0.31544 , 0.160779 ) ; // a car
classIds [ 1 ] = 11 ; confidences [ 1 ] = 0.780595f ; boxes [ 1 ] = Rect2d ( 0.129696 , 0.386467 , 0.315579 , 0.534527 ) ; // a dog
testDarknetModel ( " tiny-yolo-voc.cfg " , " tiny-yolo-voc.weights " , outNames ,
classIds , confidences , boxes , targetId ) ;
}
OCL_TEST ( Reproducibility_YoloVoc , Accuracy )
TEST_P ( Test_Darknet_nets , YOLOv3 )
{
Net net ;
{
const string cfg = findDataFile ( " dnn/yolo-voc.cfg " , false ) ;
const string model = findDataFile ( " dnn/yolo-voc.weights " , false ) ;
net = readNetFromDarknet ( cfg , model ) ;
ASSERT_FALSE ( net . empty ( ) ) ;
}
net . setPreferableBackend ( DNN_BACKEND_DEFAULT ) ;
net . setPreferableTarget ( DNN_TARGET_OPENCL ) ;
// dog416.png is dog.jpg that resized to 416x416 in the lossless PNG format
Mat sample = imread ( _tf ( " dog416.png " ) ) ;
ASSERT_TRUE ( ! sample . empty ( ) ) ;
Size inputSize ( 416 , 416 ) ;
if ( sample . size ( ) ! = inputSize )
resize ( sample , sample , inputSize ) ;
net . setInput ( blobFromImage ( sample , 1 / 255.F ) , " data " ) ;
Mat out = net . forward ( " detection_out " ) ;
Mat detection ;
const float confidenceThreshold = 0.24 ;
for ( int i = 0 ; i < out . rows ; i + + ) {
const int probability_index = 5 ;
const int probability_size = out . cols - probability_index ;
float * prob_array_ptr = & out . at < float > ( i , probability_index ) ;
size_t objectClass = std : : max_element ( prob_array_ptr , prob_array_ptr + probability_size ) - prob_array_ptr ;
float confidence = out . at < float > ( i , ( int ) objectClass + probability_index ) ;
if ( confidence > confidenceThreshold )
detection . push_back ( out . row ( i ) ) ;
}
// obtained by: ./darknet detector test ./cfg/voc.data ./cfg/yolo-voc.cfg ./yolo-voc.weights -thresh 0.24 ./dog416.png
// There are 3 objects (6-car, 1-bicycle, 11-dog) with 25 values for each:
// { relative_center_x, relative_center_y, relative_width, relative_height, unused_t0, probability_for_each_class[20] }
float ref_array [ ] = {
0.740161F , 0.214100F , 0.325575F , 0.173418F , 0.750769F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.750469F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.501618F , 0.504757F , 0.461713F , 0.481310F , 0.783550F , 0.000000F , 0.780879F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.279968F , 0.638651F , 0.282737F , 0.600284F , 0.901864F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.901615F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F
} ;
int targetId = GetParam ( ) ;
std : : vector < cv : : String > outNames ( 3 ) ;
outNames [ 0 ] = " yolo_82 " ;
outNames [ 1 ] = " yolo_94 " ;
outNames [ 2 ] = " yolo_106 " ;
std : : vector < int > classIds ( 3 ) ;
std : : vector < float > confidences ( 3 ) ;
std : : vector < Rect2d > boxes ( 3 ) ;
classIds [ 0 ] = 7 ; confidences [ 0 ] = 0.952983f ; boxes [ 0 ] = Rect2d ( 0.614622 , 0.150257 , 0.286747 , 0.138994 ) ; // a truck
classIds [ 1 ] = 1 ; confidences [ 1 ] = 0.987908f ; boxes [ 1 ] = Rect2d ( 0.150913 , 0.221933 , 0.591342 , 0.524327 ) ; // a bycicle
classIds [ 2 ] = 16 ; confidences [ 2 ] = 0.998836f ; boxes [ 2 ] = Rect2d ( 0.160024 , 0.389964 , 0.257861 , 0.553752 ) ; // a dog (COCO)
testDarknetModel ( " yolov3.cfg " , " yolov3.weights " , outNames ,
classIds , confidences , boxes , targetId ) ;
}
const int number_of_objects = 3 ;
Mat ref ( number_of_objects , sizeof ( ref_array ) / ( number_of_objects * sizeof ( float ) ) , CV_32FC1 , & ref_array ) ;
INSTANTIATE_TEST_CASE_P ( /**/ , Test_Darknet_nets , availableDnnTargets ( ) ) ;
normAssert ( ref , detection ) ;
static void testDarknetLayer ( const std : : string & name , bool hasWeights = false )
{
std : : string cfg = findDataFile ( " dnn/darknet/ " + name + " .cfg " , false ) ;
std : : string model = " " ;
if ( hasWeights )
model = findDataFile ( " dnn/darknet/ " + name + " .weights " , false ) ;
Mat inp = blobFromNPY ( findDataFile ( " dnn/darknet/ " + name + " _in.npy " , false ) ) ;
Mat ref = blobFromNPY ( findDataFile ( " dnn/darknet/ " + name + " _out.npy " , false ) ) ;
Net net = readNet ( cfg , model ) ;
net . setInput ( inp ) ;
Mat out = net . forward ( ) ;
normAssert ( out , ref ) ;
}
TEST ( Reproducibility_YoloVoc , Accuracy )
TEST ( Test_Darknet , shortcut )
{
Net net ;
{
const string cfg = findDataFile ( " dnn/yolo-voc.cfg " , false ) ;
const string model = findDataFile ( " dnn/yolo-voc.weights " , false ) ;
net = readNetFromDarknet ( cfg , model ) ;
ASSERT_FALSE ( net . empty ( ) ) ;
}
// dog416.png is dog.jpg that resized to 416x416 in the lossless PNG format
Mat sample = imread ( _tf ( " dog416.png " ) ) ;
ASSERT_TRUE ( ! sample . empty ( ) ) ;
Size inputSize ( 416 , 416 ) ;
if ( sample . size ( ) ! = inputSize )
resize ( sample , sample , inputSize ) ;
net . setInput ( blobFromImage ( sample , 1 / 255.F ) , " data " ) ;
Mat out = net . forward ( " detection_out " ) ;
Mat detection ;
const float confidenceThreshold = 0.24 ;
for ( int i = 0 ; i < out . rows ; i + + ) {
const int probability_index = 5 ;
const int probability_size = out . cols - probability_index ;
float * prob_array_ptr = & out . at < float > ( i , probability_index ) ;
size_t objectClass = std : : max_element ( prob_array_ptr , prob_array_ptr + probability_size ) - prob_array_ptr ;
float confidence = out . at < float > ( i , ( int ) objectClass + probability_index ) ;
if ( confidence > confidenceThreshold )
detection . push_back ( out . row ( i ) ) ;
}
// obtained by: ./darknet detector test ./cfg/voc.data ./cfg/yolo-voc.cfg ./yolo-voc.weights -thresh 0.24 ./dog416.png
// There are 3 objects (6-car, 1-bicycle, 11-dog) with 25 values for each:
// { relative_center_x, relative_center_y, relative_width, relative_height, unused_t0, probability_for_each_class[20] }
float ref_array [ ] = {
0.740161F , 0.214100F , 0.325575F , 0.173418F , 0.750769F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.750469F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.501618F , 0.504757F , 0.461713F , 0.481310F , 0.783550F , 0.000000F , 0.780879F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.279968F , 0.638651F , 0.282737F , 0.600284F , 0.901864F , 0.000000F , 0.000000F , 0.000000F , 0.000000F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.901615F ,
0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F , 0.000000F
} ;
const int number_of_objects = 3 ;
Mat ref ( number_of_objects , sizeof ( ref_array ) / ( number_of_objects * sizeof ( float ) ) , CV_32FC1 , & ref_array ) ;
testDarknetLayer ( " shortcut " ) ;
}
normAssert ( ref , detection ) ;
TEST ( Test_Darknet , upsample )
{
testDarknetLayer ( " upsample " ) ;
}
} } // namespace