feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
140
3rdparty/opencv-4.5.4/modules/dnn/test/cityscapes_semsegm_test_enet.py
vendored
Normal file
140
3rdparty/opencv-4.5.4/modules/dnn/test/cityscapes_semsegm_test_enet.py
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import fnmatch
|
||||
import argparse
|
||||
|
||||
try:
|
||||
import cv2 as cv
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find OpenCV Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "opencv_build_dir/lib" directory (with "python3" subdirectory if required)')
|
||||
try:
|
||||
import torch
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find pytorch. Please install it by following instructions on the official site')
|
||||
|
||||
from torch.utils.serialization import load_lua
|
||||
from pascal_semsegm_test_fcn import eval_segm_result, get_conf_mat, get_metrics, DatasetImageFetch, SemSegmEvaluation
|
||||
from imagenet_cls_test_alexnet import Framework, DnnCaffeModel
|
||||
|
||||
|
||||
class NormalizePreproc:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def process(img):
|
||||
image_data = np.array(img).transpose(2, 0, 1).astype(np.float32)
|
||||
image_data = np.expand_dims(image_data, 0)
|
||||
image_data /= 255.0
|
||||
return image_data
|
||||
|
||||
|
||||
class CityscapesDataFetch(DatasetImageFetch):
|
||||
img_dir = ''
|
||||
segm_dir = ''
|
||||
segm_files = []
|
||||
colors = []
|
||||
i = 0
|
||||
|
||||
def __init__(self, img_dir, segm_dir, preproc):
|
||||
self.img_dir = img_dir
|
||||
self.segm_dir = segm_dir
|
||||
self.segm_files = sorted([img for img in self.locate('*_color.png', segm_dir)])
|
||||
self.colors = self.get_colors()
|
||||
self.data_prepoc = preproc
|
||||
self.i = 0
|
||||
|
||||
@staticmethod
|
||||
def get_colors():
|
||||
result = []
|
||||
colors_list = (
|
||||
(0, 0, 0), (128, 64, 128), (244, 35, 232), (70, 70, 70), (102, 102, 156), (190, 153, 153), (153, 153, 153),
|
||||
(250, 170, 30), (220, 220, 0), (107, 142, 35), (152, 251, 152), (70, 130, 180), (220, 20, 60), (255, 0, 0),
|
||||
(0, 0, 142), (0, 0, 70), (0, 60, 100), (0, 80, 100), (0, 0, 230), (119, 11, 32))
|
||||
|
||||
for c in colors_list:
|
||||
result.append(DatasetImageFetch.pix_to_c(c))
|
||||
return result
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if self.i < len(self.segm_files):
|
||||
segm_file = self.segm_files[self.i]
|
||||
segm = cv.imread(segm_file, cv.IMREAD_COLOR)[:, :, ::-1]
|
||||
segm = cv.resize(segm, (1024, 512), interpolation=cv.INTER_NEAREST)
|
||||
|
||||
img_file = self.rreplace(self.img_dir + segm_file[len(self.segm_dir):], 'gtFine_color', 'leftImg8bit')
|
||||
assert os.path.exists(img_file)
|
||||
img = cv.imread(img_file, cv.IMREAD_COLOR)[:, :, ::-1]
|
||||
img = cv.resize(img, (1024, 512))
|
||||
|
||||
self.i += 1
|
||||
gt = self.color_to_gt(segm, self.colors)
|
||||
img = self.data_prepoc.process(img)
|
||||
return img, gt
|
||||
else:
|
||||
self.i = 0
|
||||
raise StopIteration
|
||||
|
||||
def get_num_classes(self):
|
||||
return len(self.colors)
|
||||
|
||||
@staticmethod
|
||||
def locate(pattern, root_path):
|
||||
for path, dirs, files in os.walk(os.path.abspath(root_path)):
|
||||
for filename in fnmatch.filter(files, pattern):
|
||||
yield os.path.join(path, filename)
|
||||
|
||||
@staticmethod
|
||||
def rreplace(s, old, new, occurrence=1):
|
||||
li = s.rsplit(old, occurrence)
|
||||
return new.join(li)
|
||||
|
||||
|
||||
class TorchModel(Framework):
|
||||
net = object
|
||||
|
||||
def __init__(self, model_file):
|
||||
self.net = load_lua(model_file)
|
||||
|
||||
def get_name(self):
|
||||
return 'Torch'
|
||||
|
||||
def get_output(self, input_blob):
|
||||
tensor = torch.FloatTensor(input_blob)
|
||||
out = self.net.forward(tensor).numpy()
|
||||
return out
|
||||
|
||||
|
||||
class DnnTorchModel(DnnCaffeModel):
|
||||
net = cv.dnn.Net()
|
||||
|
||||
def __init__(self, model_file):
|
||||
self.net = cv.dnn.readNetFromTorch(model_file)
|
||||
|
||||
def get_output(self, input_blob):
|
||||
self.net.setBlob("", input_blob)
|
||||
self.net.forward()
|
||||
return self.net.getBlob(self.net.getLayerNames()[-1])
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--imgs_dir", help="path to Cityscapes validation images dir, imgsfine/leftImg8bit/val")
|
||||
parser.add_argument("--segm_dir", help="path to Cityscapes dir with segmentation, gtfine/gtFine/val")
|
||||
parser.add_argument("--model", help="path to torch model, download it here: "
|
||||
"https://www.dropbox.com/sh/dywzk3gyb12hpe5/AAD5YkUa8XgMpHs2gCRgmCVCa")
|
||||
parser.add_argument("--log", help="path to logging file")
|
||||
args = parser.parse_args()
|
||||
|
||||
prep = NormalizePreproc()
|
||||
df = CityscapesDataFetch(args.imgs_dir, args.segm_dir, prep)
|
||||
|
||||
fw = [TorchModel(args.model),
|
||||
DnnTorchModel(args.model)]
|
||||
|
||||
segm_eval = SemSegmEvaluation(args.log)
|
||||
segm_eval.process(fw, df)
|
247
3rdparty/opencv-4.5.4/modules/dnn/test/imagenet_cls_test_alexnet.py
vendored
Normal file
247
3rdparty/opencv-4.5.4/modules/dnn/test/imagenet_cls_test_alexnet.py
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
from __future__ import print_function
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
|
||||
try:
|
||||
import caffe
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find Caffe Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "git/caffe/python" directory')
|
||||
try:
|
||||
import cv2 as cv
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find OpenCV Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "opencv_build_dir/lib" directory (with "python3" subdirectory if required)')
|
||||
|
||||
try:
|
||||
xrange # Python 2
|
||||
except NameError:
|
||||
xrange = range # Python 3
|
||||
|
||||
|
||||
class DataFetch(object):
|
||||
imgs_dir = ''
|
||||
frame_size = 0
|
||||
bgr_to_rgb = False
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abstractmethod
|
||||
def preprocess(self, img):
|
||||
pass
|
||||
|
||||
def get_batch(self, imgs_names):
|
||||
assert type(imgs_names) is list
|
||||
batch = np.zeros((len(imgs_names), 3, self.frame_size, self.frame_size)).astype(np.float32)
|
||||
for i in range(len(imgs_names)):
|
||||
img_name = imgs_names[i]
|
||||
img_file = self.imgs_dir + img_name
|
||||
assert os.path.exists(img_file)
|
||||
img = cv.imread(img_file, cv.IMREAD_COLOR)
|
||||
min_dim = min(img.shape[-3], img.shape[-2])
|
||||
resize_ratio = self.frame_size / float(min_dim)
|
||||
img = cv.resize(img, (0, 0), fx=resize_ratio, fy=resize_ratio)
|
||||
cols = img.shape[1]
|
||||
rows = img.shape[0]
|
||||
y1 = (rows - self.frame_size) / 2
|
||||
y2 = y1 + self.frame_size
|
||||
x1 = (cols - self.frame_size) / 2
|
||||
x2 = x1 + self.frame_size
|
||||
img = img[y1:y2, x1:x2]
|
||||
if self.bgr_to_rgb:
|
||||
img = img[..., ::-1]
|
||||
image_data = img[:, :, 0:3].transpose(2, 0, 1)
|
||||
batch[i] = self.preprocess(image_data)
|
||||
return batch
|
||||
|
||||
|
||||
class MeanBlobFetch(DataFetch):
|
||||
mean_blob = np.ndarray(())
|
||||
|
||||
def __init__(self, frame_size, mean_blob_path, imgs_dir):
|
||||
self.imgs_dir = imgs_dir
|
||||
self.frame_size = frame_size
|
||||
blob = caffe.proto.caffe_pb2.BlobProto()
|
||||
data = open(mean_blob_path, 'rb').read()
|
||||
blob.ParseFromString(data)
|
||||
self.mean_blob = np.array(caffe.io.blobproto_to_array(blob))
|
||||
start = (self.mean_blob.shape[2] - self.frame_size) / 2
|
||||
stop = start + self.frame_size
|
||||
self.mean_blob = self.mean_blob[:, :, start:stop, start:stop][0]
|
||||
|
||||
def preprocess(self, img):
|
||||
return img - self.mean_blob
|
||||
|
||||
|
||||
class MeanChannelsFetch(MeanBlobFetch):
|
||||
def __init__(self, frame_size, imgs_dir):
|
||||
self.imgs_dir = imgs_dir
|
||||
self.frame_size = frame_size
|
||||
self.mean_blob = np.ones((3, self.frame_size, self.frame_size)).astype(np.float32)
|
||||
self.mean_blob[0] *= 104
|
||||
self.mean_blob[1] *= 117
|
||||
self.mean_blob[2] *= 123
|
||||
|
||||
|
||||
class MeanValueFetch(MeanBlobFetch):
|
||||
def __init__(self, frame_size, imgs_dir, bgr_to_rgb):
|
||||
self.imgs_dir = imgs_dir
|
||||
self.frame_size = frame_size
|
||||
self.mean_blob = np.ones((3, self.frame_size, self.frame_size)).astype(np.float32)
|
||||
self.mean_blob *= 117
|
||||
self.bgr_to_rgb = bgr_to_rgb
|
||||
|
||||
|
||||
def get_correct_answers(img_list, img_classes, net_output_blob):
|
||||
correct_answers = 0
|
||||
for i in range(len(img_list)):
|
||||
indexes = np.argsort(net_output_blob[i])[-5:]
|
||||
correct_index = img_classes[img_list[i]]
|
||||
if correct_index in indexes:
|
||||
correct_answers += 1
|
||||
return correct_answers
|
||||
|
||||
|
||||
class Framework(object):
|
||||
in_blob_name = ''
|
||||
out_blob_name = ''
|
||||
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abstractmethod
|
||||
def get_name(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_output(self, input_blob):
|
||||
pass
|
||||
|
||||
|
||||
class CaffeModel(Framework):
|
||||
net = caffe.Net
|
||||
need_reshape = False
|
||||
|
||||
def __init__(self, prototxt, caffemodel, in_blob_name, out_blob_name, need_reshape=False):
|
||||
caffe.set_mode_cpu()
|
||||
self.net = caffe.Net(prototxt, caffemodel, caffe.TEST)
|
||||
self.in_blob_name = in_blob_name
|
||||
self.out_blob_name = out_blob_name
|
||||
self.need_reshape = need_reshape
|
||||
|
||||
def get_name(self):
|
||||
return 'Caffe'
|
||||
|
||||
def get_output(self, input_blob):
|
||||
if self.need_reshape:
|
||||
self.net.blobs[self.in_blob_name].reshape(*input_blob.shape)
|
||||
return self.net.forward_all(**{self.in_blob_name: input_blob})[self.out_blob_name]
|
||||
|
||||
|
||||
class DnnCaffeModel(Framework):
|
||||
net = object
|
||||
|
||||
def __init__(self, prototxt, caffemodel, in_blob_name, out_blob_name):
|
||||
self.net = cv.dnn.readNetFromCaffe(prototxt, caffemodel)
|
||||
self.in_blob_name = in_blob_name
|
||||
self.out_blob_name = out_blob_name
|
||||
|
||||
def get_name(self):
|
||||
return 'DNN'
|
||||
|
||||
def get_output(self, input_blob):
|
||||
self.net.setInput(input_blob, self.in_blob_name)
|
||||
return self.net.forward(self.out_blob_name)
|
||||
|
||||
|
||||
class ClsAccEvaluation:
|
||||
log = sys.stdout
|
||||
img_classes = {}
|
||||
batch_size = 0
|
||||
|
||||
def __init__(self, log_path, img_classes_file, batch_size):
|
||||
self.log = open(log_path, 'w')
|
||||
self.img_classes = self.read_classes(img_classes_file)
|
||||
self.batch_size = batch_size
|
||||
|
||||
@staticmethod
|
||||
def read_classes(img_classes_file):
|
||||
result = {}
|
||||
with open(img_classes_file) as file:
|
||||
for l in file.readlines():
|
||||
result[l.split()[0]] = int(l.split()[1])
|
||||
return result
|
||||
|
||||
def process(self, frameworks, data_fetcher):
|
||||
sorted_imgs_names = sorted(self.img_classes.keys())
|
||||
correct_answers = [0] * len(frameworks)
|
||||
samples_handled = 0
|
||||
blobs_l1_diff = [0] * len(frameworks)
|
||||
blobs_l1_diff_count = [0] * len(frameworks)
|
||||
blobs_l_inf_diff = [sys.float_info.min] * len(frameworks)
|
||||
inference_time = [0.0] * len(frameworks)
|
||||
|
||||
for x in xrange(0, len(sorted_imgs_names), self.batch_size):
|
||||
sublist = sorted_imgs_names[x:x + self.batch_size]
|
||||
batch = data_fetcher.get_batch(sublist)
|
||||
|
||||
samples_handled += len(sublist)
|
||||
|
||||
frameworks_out = []
|
||||
fw_accuracy = []
|
||||
for i in range(len(frameworks)):
|
||||
start = time.time()
|
||||
out = frameworks[i].get_output(batch)
|
||||
end = time.time()
|
||||
correct_answers[i] += get_correct_answers(sublist, self.img_classes, out)
|
||||
fw_accuracy.append(100 * correct_answers[i] / float(samples_handled))
|
||||
frameworks_out.append(out)
|
||||
inference_time[i] += end - start
|
||||
print(samples_handled, 'Accuracy for', frameworks[i].get_name() + ':', fw_accuracy[i], file=self.log)
|
||||
print("Inference time, ms ", \
|
||||
frameworks[i].get_name(), inference_time[i] / samples_handled * 1000, file=self.log)
|
||||
|
||||
for i in range(1, len(frameworks)):
|
||||
log_str = frameworks[0].get_name() + " vs " + frameworks[i].get_name() + ':'
|
||||
diff = np.abs(frameworks_out[0] - frameworks_out[i])
|
||||
l1_diff = np.sum(diff) / diff.size
|
||||
print(samples_handled, "L1 difference", log_str, l1_diff, file=self.log)
|
||||
blobs_l1_diff[i] += l1_diff
|
||||
blobs_l1_diff_count[i] += 1
|
||||
if np.max(diff) > blobs_l_inf_diff[i]:
|
||||
blobs_l_inf_diff[i] = np.max(diff)
|
||||
print(samples_handled, "L_INF difference", log_str, blobs_l_inf_diff[i], file=self.log)
|
||||
|
||||
self.log.flush()
|
||||
|
||||
for i in range(1, len(blobs_l1_diff)):
|
||||
log_str = frameworks[0].get_name() + " vs " + frameworks[i].get_name() + ':'
|
||||
print('Final l1 diff', log_str, blobs_l1_diff[i] / blobs_l1_diff_count[i], file=self.log)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--imgs_dir", help="path to ImageNet validation subset images dir, ILSVRC2012_img_val dir")
|
||||
parser.add_argument("--img_cls_file", help="path to file with classes ids for images, val.txt file from this "
|
||||
"archive: http://dl.caffe.berkeleyvision.org/caffe_ilsvrc12.tar.gz")
|
||||
parser.add_argument("--prototxt", help="path to caffe prototxt, download it here: "
|
||||
"https://github.com/BVLC/caffe/blob/master/models/bvlc_alexnet/deploy.prototxt")
|
||||
parser.add_argument("--caffemodel", help="path to caffemodel file, download it here: "
|
||||
"http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel")
|
||||
parser.add_argument("--log", help="path to logging file")
|
||||
parser.add_argument("--mean", help="path to ImageNet mean blob caffe file, imagenet_mean.binaryproto file from"
|
||||
"this archive: http://dl.caffe.berkeleyvision.org/caffe_ilsvrc12.tar.gz")
|
||||
parser.add_argument("--batch_size", help="size of images in batch", default=1000)
|
||||
parser.add_argument("--frame_size", help="size of input image", default=227)
|
||||
parser.add_argument("--in_blob", help="name for input blob", default='data')
|
||||
parser.add_argument("--out_blob", help="name for output blob", default='prob')
|
||||
args = parser.parse_args()
|
||||
|
||||
data_fetcher = MeanBlobFetch(args.frame_size, args.mean, args.imgs_dir)
|
||||
|
||||
frameworks = [CaffeModel(args.prototxt, args.caffemodel, args.in_blob, args.out_blob),
|
||||
DnnCaffeModel(args.prototxt, args.caffemodel, '', args.out_blob)]
|
||||
|
||||
acc_eval = ClsAccEvaluation(args.log, args.img_cls_file, args.batch_size)
|
||||
acc_eval.process(frameworks, data_fetcher)
|
39
3rdparty/opencv-4.5.4/modules/dnn/test/imagenet_cls_test_googlenet.py
vendored
Normal file
39
3rdparty/opencv-4.5.4/modules/dnn/test/imagenet_cls_test_googlenet.py
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
from imagenet_cls_test_alexnet import MeanChannelsFetch, CaffeModel, DnnCaffeModel, ClsAccEvaluation
|
||||
try:
|
||||
import caffe
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find Caffe Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "git/caffe/python" directory')
|
||||
try:
|
||||
import cv2 as cv
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find OpenCV Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "opencv_build_dir/lib" directory (with "python3" subdirectory if required)')
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--imgs_dir", help="path to ImageNet validation subset images dir, ILSVRC2012_img_val dir")
|
||||
parser.add_argument("--img_cls_file", help="path to file with classes ids for images, val.txt file from this "
|
||||
"archive: http://dl.caffe.berkeleyvision.org/caffe_ilsvrc12.tar.gz")
|
||||
parser.add_argument("--prototxt", help="path to caffe prototxt, download it here: "
|
||||
"https://github.com/BVLC/caffe/blob/master/models/bvlc_alexnet/deploy.prototxt")
|
||||
parser.add_argument("--caffemodel", help="path to caffemodel file, download it here: "
|
||||
"http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel")
|
||||
parser.add_argument("--log", help="path to logging file")
|
||||
parser.add_argument("--batch_size", help="size of images in batch", default=500, type=int)
|
||||
parser.add_argument("--frame_size", help="size of input image", default=224, type=int)
|
||||
parser.add_argument("--in_blob", help="name for input blob", default='data')
|
||||
parser.add_argument("--out_blob", help="name for output blob", default='prob')
|
||||
args = parser.parse_args()
|
||||
|
||||
data_fetcher = MeanChannelsFetch(args.frame_size, args.imgs_dir)
|
||||
|
||||
frameworks = [CaffeModel(args.prototxt, args.caffemodel, args.in_blob, args.out_blob),
|
||||
DnnCaffeModel(args.prototxt, args.caffemodel, '', args.out_blob)]
|
||||
|
||||
acc_eval = ClsAccEvaluation(args.log, args.img_cls_file, args.batch_size)
|
||||
acc_eval.process(frameworks, data_fetcher)
|
77
3rdparty/opencv-4.5.4/modules/dnn/test/imagenet_cls_test_inception.py
vendored
Normal file
77
3rdparty/opencv-4.5.4/modules/dnn/test/imagenet_cls_test_inception.py
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import tensorflow as tf
|
||||
from tensorflow.python.platform import gfile
|
||||
from imagenet_cls_test_alexnet import MeanValueFetch, DnnCaffeModel, Framework, ClsAccEvaluation
|
||||
try:
|
||||
import cv2 as cv
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find OpenCV Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "opencv_build_dir/lib" directory (with "python3" subdirectory if required)')
|
||||
|
||||
# If you've got an exception "Cannot load libmkl_avx.so or libmkl_def.so" or similar, try to export next variable
|
||||
# before running the script:
|
||||
# LD_PRELOAD=/opt/intel/mkl/lib/intel64/libmkl_core.so:/opt/intel/mkl/lib/intel64/libmkl_sequential.so
|
||||
|
||||
|
||||
class TensorflowModel(Framework):
|
||||
sess = tf.Session
|
||||
output = tf.Graph
|
||||
|
||||
def __init__(self, model_file, in_blob_name, out_blob_name):
|
||||
self.in_blob_name = in_blob_name
|
||||
self.sess = tf.Session()
|
||||
with gfile.FastGFile(model_file, 'rb') as f:
|
||||
graph_def = tf.GraphDef()
|
||||
graph_def.ParseFromString(f.read())
|
||||
self.sess.graph.as_default()
|
||||
tf.import_graph_def(graph_def, name='')
|
||||
self.output = self.sess.graph.get_tensor_by_name(out_blob_name + ":0")
|
||||
|
||||
def get_name(self):
|
||||
return 'Tensorflow'
|
||||
|
||||
def get_output(self, input_blob):
|
||||
assert len(input_blob.shape) == 4
|
||||
batch_tf = input_blob.transpose(0, 2, 3, 1)
|
||||
out = self.sess.run(self.output,
|
||||
{self.in_blob_name+':0': batch_tf})
|
||||
out = out[..., 1:1001]
|
||||
return out
|
||||
|
||||
|
||||
class DnnTfInceptionModel(DnnCaffeModel):
|
||||
net = cv.dnn.Net()
|
||||
|
||||
def __init__(self, model_file, in_blob_name, out_blob_name):
|
||||
self.net = cv.dnn.readNetFromTensorflow(model_file)
|
||||
self.in_blob_name = in_blob_name
|
||||
self.out_blob_name = out_blob_name
|
||||
|
||||
def get_output(self, input_blob):
|
||||
return super(DnnTfInceptionModel, self).get_output(input_blob)[..., 1:1001]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--imgs_dir", help="path to ImageNet validation subset images dir, ILSVRC2012_img_val dir")
|
||||
parser.add_argument("--img_cls_file", help="path to file with classes ids for images, download it here:"
|
||||
"https://github.com/opencv/opencv_extra/tree/master/testdata/dnn/img_classes_inception.txt")
|
||||
parser.add_argument("--model", help="path to tensorflow model, download it here:"
|
||||
"https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip")
|
||||
parser.add_argument("--log", help="path to logging file")
|
||||
parser.add_argument("--batch_size", help="size of images in batch", default=1)
|
||||
parser.add_argument("--frame_size", help="size of input image", default=224)
|
||||
parser.add_argument("--in_blob", help="name for input blob", default='input')
|
||||
parser.add_argument("--out_blob", help="name for output blob", default='softmax2')
|
||||
args = parser.parse_args()
|
||||
|
||||
data_fetcher = MeanValueFetch(args.frame_size, args.imgs_dir, True)
|
||||
|
||||
frameworks = [TensorflowModel(args.model, args.in_blob, args.out_blob),
|
||||
DnnTfInceptionModel(args.model, '', args.out_blob)]
|
||||
|
||||
acc_eval = ClsAccEvaluation(args.log, args.img_cls_file, args.batch_size)
|
||||
acc_eval.process(frameworks, data_fetcher)
|
94
3rdparty/opencv-4.5.4/modules/dnn/test/npy_blob.cpp
vendored
Normal file
94
3rdparty/opencv-4.5.4/modules/dnn/test/npy_blob.cpp
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
static std::string getType(const std::string& header)
|
||||
{
|
||||
std::string field = "'descr':";
|
||||
int idx = header.find(field);
|
||||
CV_Assert(idx != -1);
|
||||
|
||||
int from = header.find('\'', idx + field.size()) + 1;
|
||||
int to = header.find('\'', from);
|
||||
return header.substr(from, to - from);
|
||||
}
|
||||
|
||||
static std::string getFortranOrder(const std::string& header)
|
||||
{
|
||||
std::string field = "'fortran_order':";
|
||||
int idx = header.find(field);
|
||||
CV_Assert(idx != -1);
|
||||
|
||||
int from = header.find_last_of(' ', idx + field.size()) + 1;
|
||||
int to = header.find(',', from);
|
||||
return header.substr(from, to - from);
|
||||
}
|
||||
|
||||
static std::vector<int> getShape(const std::string& header)
|
||||
{
|
||||
std::string field = "'shape':";
|
||||
int idx = header.find(field);
|
||||
CV_Assert(idx != -1);
|
||||
|
||||
int from = header.find('(', idx + field.size()) + 1;
|
||||
int to = header.find(')', from);
|
||||
|
||||
std::string shapeStr = header.substr(from, to - from);
|
||||
if (shapeStr.empty())
|
||||
return std::vector<int>(1, 1);
|
||||
|
||||
// Remove all commas.
|
||||
shapeStr.erase(std::remove(shapeStr.begin(), shapeStr.end(), ','),
|
||||
shapeStr.end());
|
||||
|
||||
std::istringstream ss(shapeStr);
|
||||
int value;
|
||||
|
||||
std::vector<int> shape;
|
||||
while (ss >> value)
|
||||
{
|
||||
shape.push_back(value);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
Mat blobFromNPY(const std::string& path)
|
||||
{
|
||||
std::ifstream ifs(path.c_str(), std::ios::binary);
|
||||
CV_Assert(ifs.is_open());
|
||||
|
||||
std::string magic(6, '*');
|
||||
ifs.read(&magic[0], magic.size());
|
||||
CV_Assert(magic == "\x93NUMPY");
|
||||
|
||||
ifs.ignore(1); // Skip major version byte.
|
||||
ifs.ignore(1); // Skip minor version byte.
|
||||
|
||||
unsigned short headerSize;
|
||||
ifs.read((char*)&headerSize, sizeof(headerSize));
|
||||
|
||||
std::string header(headerSize, '*');
|
||||
ifs.read(&header[0], header.size());
|
||||
|
||||
// Extract data type.
|
||||
CV_Assert(getType(header) == "<f4");
|
||||
CV_Assert(getFortranOrder(header) == "False");
|
||||
std::vector<int> shape = getShape(header);
|
||||
|
||||
Mat blob(shape, CV_32F);
|
||||
ifs.read((char*)blob.data, blob.total() * blob.elemSize());
|
||||
CV_Assert((size_t)ifs.gcount() == blob.total() * blob.elemSize());
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
} // namespace cv
|
20
3rdparty/opencv-4.5.4/modules/dnn/test/npy_blob.hpp
vendored
Normal file
20
3rdparty/opencv-4.5.4/modules/dnn/test/npy_blob.hpp
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#ifndef __OPENCV_DNN_TEST_NPY_BLOB_HPP__
|
||||
#define __OPENCV_DNN_TEST_NPY_BLOB_HPP__
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// Parse serialized NumPy array by np.save(...)
|
||||
// Based on specification of .npy data format.
|
||||
Mat blobFromNPY(const std::string& path);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
225
3rdparty/opencv-4.5.4/modules/dnn/test/pascal_semsegm_test_fcn.py
vendored
Normal file
225
3rdparty/opencv-4.5.4/modules/dnn/test/pascal_semsegm_test_fcn.py
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
from __future__ import print_function
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import numpy as np
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
|
||||
from imagenet_cls_test_alexnet import CaffeModel, DnnCaffeModel
|
||||
try:
|
||||
import cv2 as cv
|
||||
except ImportError:
|
||||
raise ImportError('Can\'t find OpenCV Python module. If you\'ve built it from sources without installation, '
|
||||
'configure environment variable PYTHONPATH to "opencv_build_dir/lib" directory (with "python3" subdirectory if required)')
|
||||
|
||||
|
||||
def get_metrics(conf_mat):
|
||||
pix_accuracy = np.trace(conf_mat) / np.sum(conf_mat)
|
||||
t = np.sum(conf_mat, 1)
|
||||
num_cl = np.count_nonzero(t)
|
||||
assert num_cl
|
||||
mean_accuracy = np.sum(np.nan_to_num(np.divide(np.diagonal(conf_mat), t))) / num_cl
|
||||
col_sum = np.sum(conf_mat, 0)
|
||||
mean_iou = np.sum(
|
||||
np.nan_to_num(np.divide(np.diagonal(conf_mat), (t + col_sum - np.diagonal(conf_mat))))) / num_cl
|
||||
return pix_accuracy, mean_accuracy, mean_iou
|
||||
|
||||
|
||||
def eval_segm_result(net_out):
|
||||
assert type(net_out) is np.ndarray
|
||||
assert len(net_out.shape) == 4
|
||||
|
||||
channels_dim = 1
|
||||
y_dim = channels_dim + 1
|
||||
x_dim = y_dim + 1
|
||||
res = np.zeros(net_out.shape).astype(np.int)
|
||||
for i in range(net_out.shape[y_dim]):
|
||||
for j in range(net_out.shape[x_dim]):
|
||||
max_ch = np.argmax(net_out[..., i, j])
|
||||
res[0, max_ch, i, j] = 1
|
||||
return res
|
||||
|
||||
|
||||
def get_conf_mat(gt, prob):
|
||||
assert type(gt) is np.ndarray
|
||||
assert type(prob) is np.ndarray
|
||||
|
||||
conf_mat = np.zeros((gt.shape[0], gt.shape[0]))
|
||||
for ch_gt in range(conf_mat.shape[0]):
|
||||
gt_channel = gt[ch_gt, ...]
|
||||
for ch_pr in range(conf_mat.shape[1]):
|
||||
prob_channel = prob[ch_pr, ...]
|
||||
conf_mat[ch_gt][ch_pr] = np.count_nonzero(np.multiply(gt_channel, prob_channel))
|
||||
return conf_mat
|
||||
|
||||
|
||||
class MeanChannelsPreproc:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def process(img):
|
||||
image_data = np.array(img).transpose(2, 0, 1).astype(np.float32)
|
||||
mean = np.ones(image_data.shape)
|
||||
mean[0] *= 104
|
||||
mean[1] *= 117
|
||||
mean[2] *= 123
|
||||
image_data -= mean
|
||||
image_data = np.expand_dims(image_data, 0)
|
||||
return image_data
|
||||
|
||||
|
||||
class DatasetImageFetch(object):
|
||||
__metaclass__ = ABCMeta
|
||||
data_prepoc = object
|
||||
|
||||
@abstractmethod
|
||||
def __iter__(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def next(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def pix_to_c(pix):
|
||||
return pix[0] * 256 * 256 + pix[1] * 256 + pix[2]
|
||||
|
||||
@staticmethod
|
||||
def color_to_gt(color_img, colors):
|
||||
num_classes = len(colors)
|
||||
gt = np.zeros((num_classes, color_img.shape[0], color_img.shape[1])).astype(np.int)
|
||||
for img_y in range(color_img.shape[0]):
|
||||
for img_x in range(color_img.shape[1]):
|
||||
c = DatasetImageFetch.pix_to_c(color_img[img_y][img_x])
|
||||
if c in colors:
|
||||
cls = colors.index(c)
|
||||
gt[cls][img_y][img_x] = 1
|
||||
return gt
|
||||
|
||||
|
||||
class PASCALDataFetch(DatasetImageFetch):
|
||||
img_dir = ''
|
||||
segm_dir = ''
|
||||
names = []
|
||||
colors = []
|
||||
i = 0
|
||||
|
||||
def __init__(self, img_dir, segm_dir, names_file, segm_cls_colors_file, preproc):
|
||||
self.img_dir = img_dir
|
||||
self.segm_dir = segm_dir
|
||||
self.colors = self.read_colors(segm_cls_colors_file)
|
||||
self.data_prepoc = preproc
|
||||
self.i = 0
|
||||
|
||||
with open(names_file) as f:
|
||||
for l in f.readlines():
|
||||
self.names.append(l.rstrip())
|
||||
|
||||
@staticmethod
|
||||
def read_colors(img_classes_file):
|
||||
result = []
|
||||
with open(img_classes_file) as f:
|
||||
for l in f.readlines():
|
||||
color = np.array(map(int, l.split()[1:]))
|
||||
result.append(DatasetImageFetch.pix_to_c(color))
|
||||
return result
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if self.i < len(self.names):
|
||||
name = self.names[self.i]
|
||||
self.i += 1
|
||||
segm_file = self.segm_dir + name + ".png"
|
||||
img_file = self.img_dir + name + ".jpg"
|
||||
gt = self.color_to_gt(cv.imread(segm_file, cv.IMREAD_COLOR)[:, :, ::-1], self.colors)
|
||||
img = self.data_prepoc.process(cv.imread(img_file, cv.IMREAD_COLOR)[:, :, ::-1])
|
||||
return img, gt
|
||||
else:
|
||||
self.i = 0
|
||||
raise StopIteration
|
||||
|
||||
def get_num_classes(self):
|
||||
return len(self.colors)
|
||||
|
||||
|
||||
class SemSegmEvaluation:
|
||||
log = sys.stdout
|
||||
|
||||
def __init__(self, log_path,):
|
||||
self.log = open(log_path, 'w')
|
||||
|
||||
def process(self, frameworks, data_fetcher):
|
||||
samples_handled = 0
|
||||
|
||||
conf_mats = [np.zeros((data_fetcher.get_num_classes(), data_fetcher.get_num_classes())) for i in range(len(frameworks))]
|
||||
blobs_l1_diff = [0] * len(frameworks)
|
||||
blobs_l1_diff_count = [0] * len(frameworks)
|
||||
blobs_l_inf_diff = [sys.float_info.min] * len(frameworks)
|
||||
inference_time = [0.0] * len(frameworks)
|
||||
|
||||
for in_blob, gt in data_fetcher:
|
||||
frameworks_out = []
|
||||
samples_handled += 1
|
||||
for i in range(len(frameworks)):
|
||||
start = time.time()
|
||||
out = frameworks[i].get_output(in_blob)
|
||||
end = time.time()
|
||||
segm = eval_segm_result(out)
|
||||
conf_mats[i] += get_conf_mat(gt, segm[0])
|
||||
frameworks_out.append(out)
|
||||
inference_time[i] += end - start
|
||||
|
||||
pix_acc, mean_acc, miou = get_metrics(conf_mats[i])
|
||||
|
||||
name = frameworks[i].get_name()
|
||||
print(samples_handled, 'Pixel accuracy, %s:' % name, 100 * pix_acc, file=self.log)
|
||||
print(samples_handled, 'Mean accuracy, %s:' % name, 100 * mean_acc, file=self.log)
|
||||
print(samples_handled, 'Mean IOU, %s:' % name, 100 * miou, file=self.log)
|
||||
print("Inference time, ms ", \
|
||||
frameworks[i].get_name(), inference_time[i] / samples_handled * 1000, file=self.log)
|
||||
|
||||
for i in range(1, len(frameworks)):
|
||||
log_str = frameworks[0].get_name() + " vs " + frameworks[i].get_name() + ':'
|
||||
diff = np.abs(frameworks_out[0] - frameworks_out[i])
|
||||
l1_diff = np.sum(diff) / diff.size
|
||||
print(samples_handled, "L1 difference", log_str, l1_diff, file=self.log)
|
||||
blobs_l1_diff[i] += l1_diff
|
||||
blobs_l1_diff_count[i] += 1
|
||||
if np.max(diff) > blobs_l_inf_diff[i]:
|
||||
blobs_l_inf_diff[i] = np.max(diff)
|
||||
print(samples_handled, "L_INF difference", log_str, blobs_l_inf_diff[i], file=self.log)
|
||||
|
||||
self.log.flush()
|
||||
|
||||
for i in range(1, len(blobs_l1_diff)):
|
||||
log_str = frameworks[0].get_name() + " vs " + frameworks[i].get_name() + ':'
|
||||
print('Final l1 diff', log_str, blobs_l1_diff[i] / blobs_l1_diff_count[i], file=self.log)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--imgs_dir", help="path to PASCAL VOC 2012 images dir, data/VOC2012/JPEGImages")
|
||||
parser.add_argument("--segm_dir", help="path to PASCAL VOC 2012 segmentation dir, data/VOC2012/SegmentationClass/")
|
||||
parser.add_argument("--val_names", help="path to file with validation set image names, download it here: "
|
||||
"https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/data/pascal/seg11valid.txt")
|
||||
parser.add_argument("--cls_file", help="path to file with colors for classes, download it here: "
|
||||
"https://github.com/opencv/opencv/blob/master/samples/data/dnn/pascal-classes.txt")
|
||||
parser.add_argument("--prototxt", help="path to caffe prototxt, download it here: "
|
||||
"https://github.com/opencv/opencv/blob/master/samples/data/dnn/fcn8s-heavy-pascal.prototxt")
|
||||
parser.add_argument("--caffemodel", help="path to caffemodel file, download it here: "
|
||||
"http://dl.caffe.berkeleyvision.org/fcn8s-heavy-pascal.caffemodel")
|
||||
parser.add_argument("--log", help="path to logging file")
|
||||
parser.add_argument("--in_blob", help="name for input blob", default='data')
|
||||
parser.add_argument("--out_blob", help="name for output blob", default='score')
|
||||
args = parser.parse_args()
|
||||
|
||||
prep = MeanChannelsPreproc()
|
||||
df = PASCALDataFetch(args.imgs_dir, args.segm_dir, args.val_names, args.cls_file, prep)
|
||||
|
||||
fw = [CaffeModel(args.prototxt, args.caffemodel, args.in_blob, args.out_blob, True),
|
||||
DnnCaffeModel(args.prototxt, args.caffemodel, '', args.out_blob)]
|
||||
|
||||
segm_eval = SemSegmEvaluation(args.log)
|
||||
segm_eval.process(fw, df)
|
544
3rdparty/opencv-4.5.4/modules/dnn/test/test_backends.cpp
vendored
Normal file
544
3rdparty/opencv-4.5.4/modules/dnn/test/test_backends.cpp
vendored
Normal file
@ -0,0 +1,544 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
class DNNTestNetwork : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
void processNet(const std::string& weights, const std::string& proto,
|
||||
Size inpSize, const std::string& outputLayer = "",
|
||||
const std::string& halideScheduler = "",
|
||||
double l1 = 0.0, double lInf = 0.0)
|
||||
{
|
||||
// Create a common input blob.
|
||||
int blobSize[] = {1, 3, inpSize.height, inpSize.width};
|
||||
Mat inp(4, blobSize, CV_32FC1);
|
||||
randu(inp, 0.0f, 1.0f);
|
||||
|
||||
processNet(weights, proto, inp, outputLayer, halideScheduler, l1, lInf);
|
||||
}
|
||||
|
||||
void processNet(std::string weights, std::string proto,
|
||||
Mat inp, const std::string& outputLayer = "",
|
||||
std::string halideScheduler = "",
|
||||
double l1 = 0.0, double lInf = 0.0, double detectionConfThresh = 0.2)
|
||||
{
|
||||
checkBackend();
|
||||
l1 = l1 ? l1 : default_l1;
|
||||
lInf = lInf ? lInf : default_lInf;
|
||||
|
||||
weights = findDataFile(weights, false);
|
||||
if (!proto.empty())
|
||||
proto = findDataFile(proto);
|
||||
|
||||
// Create two networks - with default backend and target and a tested one.
|
||||
Net netDefault = readNet(weights, proto);
|
||||
netDefault.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
netDefault.setInput(inp);
|
||||
Mat outDefault = netDefault.forward(outputLayer).clone();
|
||||
|
||||
net = readNet(weights, proto);
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
if (backend == DNN_BACKEND_HALIDE && !halideScheduler.empty())
|
||||
{
|
||||
halideScheduler = findDataFile(halideScheduler);
|
||||
net.setHalideScheduler(halideScheduler);
|
||||
}
|
||||
Mat out = net.forward(outputLayer).clone();
|
||||
|
||||
check(outDefault, out, outputLayer, l1, lInf, detectionConfThresh, "First run");
|
||||
|
||||
// Test 2: change input.
|
||||
float* inpData = (float*)inp.data;
|
||||
for (int i = 0; i < inp.size[0] * inp.size[1]; ++i)
|
||||
{
|
||||
Mat slice(inp.size[2], inp.size[3], CV_32F, inpData);
|
||||
cv::flip(slice, slice, 1);
|
||||
inpData += slice.total();
|
||||
}
|
||||
netDefault.setInput(inp);
|
||||
net.setInput(inp);
|
||||
outDefault = netDefault.forward(outputLayer).clone();
|
||||
out = net.forward(outputLayer).clone();
|
||||
check(outDefault, out, outputLayer, l1, lInf, detectionConfThresh, "Second run");
|
||||
}
|
||||
|
||||
void check(Mat& ref, Mat& out, const std::string& outputLayer, double l1, double lInf,
|
||||
double detectionConfThresh, const char* msg)
|
||||
{
|
||||
if (outputLayer == "detection_out")
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
// Inference Engine produces detections terminated by a row which starts from -1.
|
||||
out = out.reshape(1, out.total() / 7);
|
||||
int numDetections = 0;
|
||||
while (numDetections < out.rows && out.at<float>(numDetections, 0) != -1)
|
||||
{
|
||||
numDetections += 1;
|
||||
}
|
||||
out = out.rowRange(0, numDetections);
|
||||
}
|
||||
normAssertDetections(ref, out, msg, detectionConfThresh, l1, lInf);
|
||||
}
|
||||
else
|
||||
normAssert(ref, out, msg, l1, lInf);
|
||||
}
|
||||
|
||||
Net net;
|
||||
};
|
||||
|
||||
TEST_P(DNNTestNetwork, AlexNet)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE) // Realization contains wrong number of Images (1) for realizing pipeline with 2 outputs
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
processNet("dnn/bvlc_alexnet.caffemodel", "dnn/bvlc_alexnet.prototxt",
|
||||
Size(227, 227), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_alexnet.yml" :
|
||||
"dnn/halide_scheduler_alexnet.yml");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, ResNet_50)
|
||||
{
|
||||
applyTestTag(
|
||||
(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
|
||||
CV_TEST_TAG_DEBUG_LONG
|
||||
);
|
||||
if (backend == DNN_BACKEND_HALIDE) // Realization contains wrong number of Images (1) for realizing pipeline with 2 outputs
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
processNet("dnn/ResNet-50-model.caffemodel", "dnn/ResNet-50-deploy.prototxt",
|
||||
Size(224, 224), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_resnet_50.yml" :
|
||||
"dnn/halide_scheduler_resnet_50.yml");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, SqueezeNet_v1_1)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE) // Realization contains wrong number of Images (1) for realizing pipeline with 2 outputs
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
processNet("dnn/squeezenet_v1.1.caffemodel", "dnn/squeezenet_v1.1.prototxt",
|
||||
Size(227, 227), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_squeezenet_v1_1.yml" :
|
||||
"dnn/halide_scheduler_squeezenet_v1_1.yml");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, GoogLeNet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE) // Realization contains wrong number of Images (1) for realizing pipeline with 2 outputs
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
processNet("dnn/bvlc_googlenet.caffemodel", "dnn/bvlc_googlenet.prototxt",
|
||||
Size(224, 224), "prob");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, Inception_5h)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE) // Realization contains wrong number of Images (1) for realizing pipeline with 2 outputs
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
double l1 = default_l1, lInf = default_lInf;
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_CPU || target == DNN_TARGET_OPENCL))
|
||||
{
|
||||
l1 = 1.72e-5;
|
||||
lInf = 8e-4;
|
||||
}
|
||||
processNet("dnn/tensorflow_inception_graph.pb", "", Size(224, 224), "softmax2",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_inception_5h.yml" :
|
||||
"dnn/halide_scheduler_inception_5h.yml",
|
||||
l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, ENet)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE) // Realization contains wrong number of Images (1) for realizing pipeline with 2 outputs
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
|
||||
processNet("dnn/Enet-model-best.net", "", Size(512, 512), "l367_Deconvolution",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_enet.yml" :
|
||||
"dnn/halide_scheduler_enet.yml",
|
||||
2e-5, 0.15);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
|
||||
float scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 1.5e-2 : 0.0;
|
||||
float iouDiff = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0;
|
||||
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.262 : FLT_MIN;
|
||||
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff, detectionConfThresh);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 560), Scalar(127.5, 127.5, 127.5), false);
|
||||
float scoreDiff = 0.0, iouDiff = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.029;
|
||||
iouDiff = 0.09;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.03;
|
||||
iouDiff = 0.08;
|
||||
}
|
||||
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.216 : 0.2;
|
||||
float scoreDiff = 0.0, iouDiff = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.095;
|
||||
iouDiff = 0.09;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.007;
|
||||
iouDiff = 0.08;
|
||||
}
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff, detectionConfThresh);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 560), Scalar(), false);
|
||||
float scoreDiff = 0.0, iouDiff = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.013;
|
||||
iouDiff = 0.06;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.007;
|
||||
iouDiff = 0.06;
|
||||
}
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float scoreDiff = 2e-5, iouDiff = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.013;
|
||||
iouDiff = 0.062;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.02;
|
||||
iouDiff = 0.07;
|
||||
}
|
||||
processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "dnn/ssd_mobilenet_v2_coco_2018_03_29.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff, 0.25);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE); // TODO HALIDE_CPU
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float scoreDiff = 0.0, iouDiff = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
scoreDiff = 0.0325;
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.0325;
|
||||
iouDiff = 0.032;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.03;
|
||||
iouDiff = 0.13;
|
||||
}
|
||||
|
||||
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel",
|
||||
"dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_LONG);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.009 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
|
||||
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt",
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
// output range: [-0.001, 0.97]
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.02 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.2 : 0.0;
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
// The same .caffemodel but modified .prototxt
|
||||
// See https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/pose/poseParameters.cpp
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi_faster_4_stages.prototxt",
|
||||
Size(46, 46));
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenFace)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0024 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.0071 : 0.0;
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "", "", l1, lInf);
|
||||
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, opencv_face_detector)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
|
||||
Mat inp = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
|
||||
processNet("dnn/opencv_face_detector.caffemodel", "dnn/opencv_face_detector.prototxt",
|
||||
inp, "detection_out");
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
{
|
||||
applyTestTag(
|
||||
(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
|
||||
CV_TEST_TAG_DEBUG_LONG
|
||||
);
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float scoreDiff = 0.0, iouDiff = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.015;
|
||||
iouDiff = 0.0731;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.015;
|
||||
iouDiff = 0.08;
|
||||
}
|
||||
processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "dnn/ssd_inception_v2_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
// Reference output values are in range [-3.807, 4.605]
|
||||
float l1 = 0.0, lInf = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 2e-2;
|
||||
lInf = 9e-2;
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
lInf = 0.1f;
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.1;
|
||||
lInf = 0.6;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.008;
|
||||
lInf = 0.05;
|
||||
}
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", Size(224, 224), "", "", l1, lInf);
|
||||
if (target != DNN_TARGET_MYRIAD || getInferenceEngineVPUType() != CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB, CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
#if INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Mat img = imread(findDataFile("dnn/googlenet_1.png"));
|
||||
Mat inp = blobFromImage(img, 1.0, Size(320, 240), Scalar(103.939, 116.779, 123.68), false, false);
|
||||
// Output image has values in range [-143.526, 148.539].
|
||||
float l1 = 4e-5, lInf = 2e-3;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.4;
|
||||
lInf = 7.45;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.3;
|
||||
lInf = 7.6;
|
||||
}
|
||||
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", inp, "", "", l1, lInf);
|
||||
#if defined(HAVE_INF_ENGINE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
expectNoFallbacksFromIE(net);
|
||||
#endif
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets(true, true, false, true, true));
|
||||
|
||||
}} // namespace
|
761
3rdparty/opencv-4.5.4/modules/dnn/test/test_caffe_importer.cpp
vendored
Normal file
761
3rdparty/opencv-4.5.4/modules/dnn/test/test_caffe_importer.cpp
vendored
Normal file
@ -0,0 +1,761 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
template<typename TString>
|
||||
static std::string _tf(TString filename)
|
||||
{
|
||||
return findDataFile(std::string("dnn/") + filename);
|
||||
}
|
||||
|
||||
class Test_Caffe_nets : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
void testFaster(const std::string& proto, const std::string& model, const Mat& ref,
|
||||
double scoreDiff = 0.0, double iouDiff = 0.0)
|
||||
{
|
||||
checkBackend();
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/" + proto),
|
||||
findDataFile("dnn/" + model, false));
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
Mat img = imread(findDataFile("dnn/dog416.png"));
|
||||
resize(img, img, Size(800, 600));
|
||||
Mat blob = blobFromImage(img, 1.0, Size(), Scalar(102.9801, 115.9465, 122.7717), false, false);
|
||||
Mat imInfo = (Mat_<float>(1, 3) << img.rows, img.cols, 1.6f);
|
||||
|
||||
net.setInput(blob, "data");
|
||||
net.setInput(imInfo, "im_info");
|
||||
// Output has shape 1x1xNx7 where N - number of detections.
|
||||
// An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
|
||||
Mat out = net.forward();
|
||||
scoreDiff = scoreDiff ? scoreDiff : default_l1;
|
||||
iouDiff = iouDiff ? iouDiff : default_lInf;
|
||||
normAssertDetections(ref, out, ("model name: " + model).c_str(), 0.8, scoreDiff, iouDiff);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Test_Caffe, memory_read)
|
||||
{
|
||||
const string proto = findDataFile("dnn/bvlc_googlenet.prototxt");
|
||||
const string model = findDataFile("dnn/bvlc_googlenet.caffemodel", false);
|
||||
|
||||
std::vector<char> dataProto;
|
||||
readFileContent(proto, dataProto);
|
||||
|
||||
std::vector<char> dataModel;
|
||||
readFileContent(model, dataModel);
|
||||
|
||||
Net net = readNetFromCaffe(dataProto.data(), dataProto.size());
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
ASSERT_FALSE(net.empty());
|
||||
|
||||
Net net2 = readNetFromCaffe(dataProto.data(), dataProto.size(),
|
||||
dataModel.data(), dataModel.size());
|
||||
ASSERT_FALSE(net2.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Caffe, read_gtsrb)
|
||||
{
|
||||
Net net = readNetFromCaffe(_tf("gtsrb.prototxt"));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Caffe, read_googlenet)
|
||||
{
|
||||
Net net = readNetFromCaffe(_tf("bvlc_googlenet.prototxt"));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST_P(Test_Caffe_nets, Axpy)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
String proto = _tf("axpy.prototxt");
|
||||
Net net = readNetFromCaffe(proto);
|
||||
|
||||
checkBackend();
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
int size[] = {1, 2, 3, 4};
|
||||
int scale_size[] = {1, 2, 1, 1};
|
||||
Mat scale(4, &scale_size[0], CV_32F);
|
||||
Mat shift(4, &size[0], CV_32F);
|
||||
Mat inp(4, &size[0], CV_32F);
|
||||
randu(scale, -1.0f, 1.0f);
|
||||
randu(shift, -1.0f, 1.0f);
|
||||
randu(inp, -1.0f, 1.0f);
|
||||
|
||||
net.setInput(scale, "scale");
|
||||
net.setInput(shift, "shift");
|
||||
net.setInput(inp, "data");
|
||||
|
||||
Mat out = net.forward();
|
||||
|
||||
Mat ref(4, &size[0], inp.type());
|
||||
for (int i = 0; i < inp.size[1]; i++) {
|
||||
for (int h = 0; h < inp.size[2]; h++) {
|
||||
for (int w = 0; w < inp.size[3]; w++) {
|
||||
int idx[] = {0, i, h, w};
|
||||
int scale_idx[] = {0, i, 0, 0};
|
||||
ref.at<float>(idx) = inp.at<float>(idx) * scale.at<float>(scale_idx) +
|
||||
shift.at<float>(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
float l1 = 1e-5, lInf = 1e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 2e-4;
|
||||
lInf = 1e-3;
|
||||
}
|
||||
else if(target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.0002;
|
||||
lInf = 0.0007;
|
||||
}
|
||||
normAssert(ref, out, "", l1, lInf);
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<tuple<bool, Target> > Reproducibility_AlexNet;
|
||||
TEST_P(Reproducibility_AlexNet, Accuracy)
|
||||
{
|
||||
Target targetId = get<1>(GetParam());
|
||||
#if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_2GB);
|
||||
#else
|
||||
applyTestTag(targetId == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
#endif
|
||||
ASSERT_TRUE(ocl::useOpenCL() || targetId == DNN_TARGET_CPU);
|
||||
|
||||
bool readFromMemory = get<0>(GetParam());
|
||||
Net net;
|
||||
{
|
||||
const string proto = findDataFile("dnn/bvlc_alexnet.prototxt");
|
||||
const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false);
|
||||
if (readFromMemory)
|
||||
{
|
||||
std::vector<char> dataProto;
|
||||
readFileContent(proto, dataProto);
|
||||
std::vector<char> dataModel;
|
||||
readFileContent(model, dataModel);
|
||||
|
||||
net = readNetFromCaffe(dataProto.data(), dataProto.size(),
|
||||
dataModel.data(), dataModel.size());
|
||||
}
|
||||
else
|
||||
net = readNetFromCaffe(proto, model);
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
// Test input layer size
|
||||
std::vector<MatShape> inLayerShapes;
|
||||
std::vector<MatShape> outLayerShapes;
|
||||
net.getLayerShapes(MatShape(), 0, inLayerShapes, outLayerShapes);
|
||||
ASSERT_FALSE(inLayerShapes.empty());
|
||||
ASSERT_EQ(inLayerShapes[0].size(), 4);
|
||||
ASSERT_EQ(inLayerShapes[0][0], 1);
|
||||
ASSERT_EQ(inLayerShapes[0][1], 3);
|
||||
ASSERT_EQ(inLayerShapes[0][2], 227);
|
||||
ASSERT_EQ(inLayerShapes[0][3], 227);
|
||||
|
||||
const float l1 = 1e-5;
|
||||
const float lInf = (targetId == DNN_TARGET_OPENCL_FP16) ? 3e-3 : 1e-4;
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
Mat sample = imread(_tf("grace_hopper_227.png"));
|
||||
ASSERT_TRUE(!sample.empty());
|
||||
|
||||
net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar(), false), "data");
|
||||
Mat out = net.forward("prob");
|
||||
Mat ref = blobFromNPY(_tf("caffe_alexnet_prob.npy"));
|
||||
normAssert(ref, out, "", l1, lInf);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_AlexNet, Combine(testing::Bool(),
|
||||
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV))));
|
||||
|
||||
TEST(Reproducibility_FCN, Accuracy)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_DEBUG_VERYLONG, CV_TEST_TAG_MEMORY_2GB);
|
||||
|
||||
Net net;
|
||||
{
|
||||
const string proto = findDataFile("dnn/fcn8s-heavy-pascal.prototxt");
|
||||
const string model = findDataFile("dnn/fcn8s-heavy-pascal.caffemodel", false);
|
||||
net = readNetFromCaffe(proto, model);
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
Mat sample = imread(_tf("street.png"));
|
||||
ASSERT_TRUE(!sample.empty());
|
||||
|
||||
std::vector<int> layerIds;
|
||||
std::vector<size_t> weights, blobs;
|
||||
net.getMemoryConsumption(shape(1,3,227,227), layerIds, weights, blobs);
|
||||
|
||||
net.setInput(blobFromImage(sample, 1.0f, Size(500, 500), Scalar(), false), "data");
|
||||
Mat out = net.forward("score");
|
||||
|
||||
Mat refData = imread(_tf("caffe_fcn8s_prob.png"), IMREAD_ANYDEPTH);
|
||||
int shape[] = {1, 21, 500, 500};
|
||||
Mat ref(4, shape, CV_32FC1, refData.data);
|
||||
|
||||
normAssert(ref, out);
|
||||
}
|
||||
|
||||
TEST(Reproducibility_SSD, Accuracy)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB, CV_TEST_TAG_DEBUG_LONG);
|
||||
Net net;
|
||||
{
|
||||
const string proto = findDataFile("dnn/ssd_vgg16.prototxt");
|
||||
const string model = findDataFile("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", false);
|
||||
net = readNetFromCaffe(proto, model);
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
Mat sample = imread(_tf("street.png"));
|
||||
ASSERT_TRUE(!sample.empty());
|
||||
|
||||
if (sample.channels() == 4)
|
||||
cvtColor(sample, sample, COLOR_BGRA2BGR);
|
||||
|
||||
Mat in_blob = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
net.setInput(in_blob, "data");
|
||||
Mat out = net.forward("detection_out");
|
||||
|
||||
Mat ref = blobFromNPY(_tf("ssd_out.npy"));
|
||||
normAssertDetections(ref, out, "", FLT_MIN);
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<tuple<Backend, Target> > Reproducibility_MobileNet_SSD;
|
||||
TEST_P(Reproducibility_MobileNet_SSD, Accuracy)
|
||||
{
|
||||
const string proto = findDataFile("dnn/MobileNetSSD_deploy.prototxt", false);
|
||||
const string model = findDataFile("dnn/MobileNetSSD_deploy.caffemodel", false);
|
||||
Net net = readNetFromCaffe(proto, model);
|
||||
int backendId = get<0>(GetParam());
|
||||
int targetId = get<1>(GetParam());
|
||||
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
Mat sample = imread(_tf("street.png"));
|
||||
|
||||
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward().clone();
|
||||
|
||||
ASSERT_EQ(out.size[2], 100);
|
||||
|
||||
float scores_diff = 1e-5, boxes_iou_diff = 1e-4;
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scores_diff = 1.5e-2;
|
||||
boxes_iou_diff = 6.3e-2;
|
||||
}
|
||||
else if (targetId == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scores_diff = 0.015;
|
||||
boxes_iou_diff = 0.07;
|
||||
}
|
||||
Mat ref = blobFromNPY(_tf("mobilenet_ssd_caffe_out.npy"));
|
||||
normAssertDetections(ref, out, "", FLT_MIN, scores_diff, boxes_iou_diff);
|
||||
|
||||
// Check that detections aren't preserved.
|
||||
inp.setTo(0.0f);
|
||||
net.setInput(inp);
|
||||
Mat zerosOut = net.forward();
|
||||
zerosOut = zerosOut.reshape(1, zerosOut.total() / 7);
|
||||
|
||||
const int numDetections = zerosOut.rows;
|
||||
// TODO: fix it
|
||||
if (targetId != DNN_TARGET_MYRIAD ||
|
||||
getInferenceEngineVPUType() != CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
ASSERT_NE(numDetections, 0);
|
||||
for (int i = 0; i < numDetections; ++i)
|
||||
{
|
||||
float confidence = zerosOut.ptr<float>(i)[2];
|
||||
ASSERT_EQ(confidence, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// There is something wrong with Reshape layer in Myriad plugin.
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019
|
||||
|| backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH
|
||||
)
|
||||
{
|
||||
if (targetId == DNN_TARGET_MYRIAD || targetId == DNN_TARGET_OPENCL_FP16)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check batching mode.
|
||||
inp = blobFromImages(std::vector<Mat>(2, sample), 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
|
||||
net.setInput(inp);
|
||||
Mat outBatch = net.forward();
|
||||
|
||||
// Output blob has a shape 1x1x2Nx7 where N is a number of detection for
|
||||
// a single sample in batch. The first numbers of detection vectors are batch id.
|
||||
// For Inference Engine backend there is -1 delimiter which points the end of detections.
|
||||
const int numRealDetections = ref.size[2];
|
||||
EXPECT_EQ(outBatch.size[2], 2 * numDetections);
|
||||
out = out.reshape(1, numDetections).rowRange(0, numRealDetections);
|
||||
outBatch = outBatch.reshape(1, 2 * numDetections);
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
Mat pred = outBatch.rowRange(i * numRealDetections, (i + 1) * numRealDetections);
|
||||
EXPECT_EQ(countNonZero(pred.col(0) != i), 0);
|
||||
normAssert(pred.colRange(1, 7), out.colRange(1, 7));
|
||||
}
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_MobileNet_SSD, dnnBackendsAndTargets());
|
||||
|
||||
typedef testing::TestWithParam<Target> Reproducibility_ResNet50;
|
||||
TEST_P(Reproducibility_ResNet50, Accuracy)
|
||||
{
|
||||
Target targetId = GetParam();
|
||||
applyTestTag(targetId == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
ASSERT_TRUE(ocl::useOpenCL() || targetId == DNN_TARGET_CPU);
|
||||
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt"),
|
||||
findDataFile("dnn/ResNet-50-model.caffemodel", false));
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
float l1 = (targetId == DNN_TARGET_OPENCL_FP16) ? 3e-5 : 1e-5;
|
||||
float lInf = (targetId == DNN_TARGET_OPENCL_FP16) ? 6e-3 : 1e-4;
|
||||
|
||||
Mat input = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(224,224), Scalar(), false);
|
||||
ASSERT_TRUE(!input.empty());
|
||||
|
||||
net.setInput(input);
|
||||
Mat out = net.forward();
|
||||
|
||||
Mat ref = blobFromNPY(_tf("resnet50_prob.npy"));
|
||||
normAssert(ref, out, "", l1, lInf);
|
||||
|
||||
if (targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
UMat out_umat;
|
||||
net.forward(out_umat);
|
||||
normAssert(ref, out_umat, "out_umat", l1, lInf);
|
||||
|
||||
std::vector<UMat> out_umats;
|
||||
net.forward(out_umats);
|
||||
normAssert(ref, out_umats[0], "out_umat_vector", l1, lInf);
|
||||
}
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_ResNet50,
|
||||
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
|
||||
|
||||
typedef testing::TestWithParam<Target> Reproducibility_SqueezeNet_v1_1;
|
||||
TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy)
|
||||
{
|
||||
int targetId = GetParam();
|
||||
if(targetId == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt"),
|
||||
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
Mat input = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(227,227), Scalar(), false, true);
|
||||
ASSERT_TRUE(!input.empty());
|
||||
|
||||
Mat out;
|
||||
if (targetId == DNN_TARGET_OPENCL)
|
||||
{
|
||||
// Firstly set a wrong input blob and run the model to receive a wrong output.
|
||||
// Then set a correct input blob to check CPU->GPU synchronization is working well.
|
||||
net.setInput(input * 2.0f);
|
||||
out = net.forward();
|
||||
}
|
||||
net.setInput(input);
|
||||
out = net.forward();
|
||||
|
||||
Mat ref = blobFromNPY(_tf("squeezenet_v1.1_prob.npy"));
|
||||
normAssert(ref, out);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1,
|
||||
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
|
||||
|
||||
TEST(Reproducibility_AlexNet_fp16, Accuracy)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
const float l1 = 1e-5;
|
||||
const float lInf = 3e-3;
|
||||
|
||||
const string proto = findDataFile("dnn/bvlc_alexnet.prototxt");
|
||||
const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false);
|
||||
|
||||
shrinkCaffeModel(model, "bvlc_alexnet.caffemodel_fp16");
|
||||
Net net = readNetFromCaffe(proto, "bvlc_alexnet.caffemodel_fp16");
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/grace_hopper_227.png"));
|
||||
|
||||
net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar()));
|
||||
Mat out = net.forward();
|
||||
Mat ref = blobFromNPY(findDataFile("dnn/caffe_alexnet_prob.npy"));
|
||||
normAssert(ref, out, "", l1, lInf);
|
||||
}
|
||||
|
||||
TEST(Reproducibility_GoogLeNet_fp16, Accuracy)
|
||||
{
|
||||
const float l1 = 1e-5;
|
||||
const float lInf = 3e-3;
|
||||
|
||||
const string proto = findDataFile("dnn/bvlc_googlenet.prototxt");
|
||||
const string model = findDataFile("dnn/bvlc_googlenet.caffemodel", false);
|
||||
|
||||
shrinkCaffeModel(model, "bvlc_googlenet.caffemodel_fp16");
|
||||
Net net = readNetFromCaffe(proto, "bvlc_googlenet.caffemodel_fp16");
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
std::vector<Mat> inpMats;
|
||||
inpMats.push_back( imread(_tf("googlenet_0.png")) );
|
||||
inpMats.push_back( imread(_tf("googlenet_1.png")) );
|
||||
ASSERT_TRUE(!inpMats[0].empty() && !inpMats[1].empty());
|
||||
|
||||
net.setInput(blobFromImages(inpMats, 1.0f, Size(), Scalar(), false), "data");
|
||||
Mat out = net.forward("prob");
|
||||
|
||||
Mat ref = blobFromNPY(_tf("googlenet_prob.npy"));
|
||||
normAssert(out, ref, "", l1, lInf);
|
||||
}
|
||||
|
||||
// https://github.com/richzhang/colorization
|
||||
TEST_P(Test_Caffe_nets, Colorization)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
checkBackend();
|
||||
|
||||
Mat inp = blobFromNPY(_tf("colorization_inp.npy"));
|
||||
Mat ref = blobFromNPY(_tf("colorization_out.npy"));
|
||||
Mat kernel = blobFromNPY(_tf("colorization_pts_in_hull.npy"));
|
||||
|
||||
const string proto = findDataFile("dnn/colorization_deploy_v2.prototxt", false);
|
||||
const string model = findDataFile("dnn/colorization_release_v2.caffemodel", false);
|
||||
Net net = readNetFromCaffe(proto, model);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
net.getLayer(net.getLayerId("class8_ab"))->blobs.push_back(kernel);
|
||||
net.getLayer(net.getLayerId("conv8_313_rh"))->blobs.push_back(Mat(1, 313, CV_32F, 2.606));
|
||||
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
|
||||
// Reference output values are in range [-29.1, 69.5]
|
||||
double l1 = 4e-4, lInf = 3e-3;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.25;
|
||||
lInf = 5.3;
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) ? 0.5 : 0.25;
|
||||
lInf = (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) ? 11 : 5.3;
|
||||
}
|
||||
else if(target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.21;
|
||||
lInf = 4.5;
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.26; lInf = 6.5;
|
||||
}
|
||||
|
||||
normAssert(out, ref, "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(Test_Caffe_nets, DenseNet_121)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
checkBackend();
|
||||
const string proto = findDataFile("dnn/DenseNet_121.prototxt", false);
|
||||
const string weights = findDataFile("dnn/DenseNet_121.caffemodel", false);
|
||||
|
||||
Mat inp = imread(_tf("dog416.png"));
|
||||
Model model(proto, weights);
|
||||
model.setInputScale(1.0 / 255).setInputSwapRB(true).setInputCrop(true);
|
||||
std::vector<Mat> outs;
|
||||
Mat ref = blobFromNPY(_tf("densenet_121_output.npy"));
|
||||
|
||||
model.setPreferableBackend(backend);
|
||||
model.setPreferableTarget(target);
|
||||
model.predict(inp, outs);
|
||||
|
||||
// Reference is an array of 1000 values from a range [-6.16, 7.9]
|
||||
float l1 = default_l1, lInf = default_lInf;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019020000)
|
||||
l1 = 0.045; lInf = 0.21;
|
||||
#else
|
||||
l1 = 0.017; lInf = 0.0795;
|
||||
#endif
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.11; lInf = 0.5;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.04; lInf = 0.2;
|
||||
}
|
||||
normAssert(outs[0], ref, "", l1, lInf);
|
||||
if (target != DNN_TARGET_MYRIAD || getInferenceEngineVPUType() != CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
expectNoFallbacksFromIE(model.getNetwork_());
|
||||
}
|
||||
|
||||
TEST(Test_Caffe, multiple_inputs)
|
||||
{
|
||||
const string proto = findDataFile("dnn/layers/net_input.prototxt");
|
||||
Net net = readNetFromCaffe(proto);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
Mat first_image(10, 11, CV_32FC3);
|
||||
Mat second_image(10, 11, CV_32FC3);
|
||||
randu(first_image, -1, 1);
|
||||
randu(second_image, -1, 1);
|
||||
|
||||
first_image = blobFromImage(first_image);
|
||||
second_image = blobFromImage(second_image);
|
||||
|
||||
Mat first_image_blue_green = slice(first_image, Range::all(), Range(0, 2), Range::all(), Range::all());
|
||||
Mat first_image_red = slice(first_image, Range::all(), Range(2, 3), Range::all(), Range::all());
|
||||
Mat second_image_blue_green = slice(second_image, Range::all(), Range(0, 2), Range::all(), Range::all());
|
||||
Mat second_image_red = slice(second_image, Range::all(), Range(2, 3), Range::all(), Range::all());
|
||||
|
||||
net.setInput(first_image_blue_green, "old_style_input_blue_green");
|
||||
net.setInput(first_image_red, "different_name_for_red");
|
||||
net.setInput(second_image_blue_green, "input_layer_blue_green");
|
||||
net.setInput(second_image_red, "old_style_input_red");
|
||||
Mat out = net.forward();
|
||||
|
||||
normAssert(out, first_image + second_image);
|
||||
}
|
||||
|
||||
TEST(Test_Caffe, shared_weights)
|
||||
{
|
||||
const string proto = findDataFile("dnn/layers/shared_weights.prototxt");
|
||||
const string model = findDataFile("dnn/layers/shared_weights.caffemodel");
|
||||
|
||||
Net net = readNetFromCaffe(proto, model);
|
||||
|
||||
Mat input_1 = (Mat_<float>(2, 2) << 0., 2., 4., 6.);
|
||||
Mat input_2 = (Mat_<float>(2, 2) << 1., 3., 5., 7.);
|
||||
|
||||
Mat blob_1 = blobFromImage(input_1);
|
||||
Mat blob_2 = blobFromImage(input_2);
|
||||
|
||||
net.setInput(blob_1, "input_1");
|
||||
net.setInput(blob_2, "input_2");
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
Mat sum = net.forward();
|
||||
|
||||
EXPECT_EQ(sum.at<float>(0,0), 12.);
|
||||
EXPECT_EQ(sum.at<float>(0,1), 16.);
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<tuple<std::string, Target> > opencv_face_detector;
|
||||
TEST_P(opencv_face_detector, Accuracy)
|
||||
{
|
||||
std::string proto = findDataFile("dnn/opencv_face_detector.prototxt");
|
||||
std::string model = findDataFile(get<0>(GetParam()), false);
|
||||
dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam());
|
||||
|
||||
Net net = readNetFromCaffe(proto, model);
|
||||
Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
|
||||
Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
net.setInput(blob);
|
||||
// Output has shape 1x1xNx7 where N - number of detections.
|
||||
// An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
|
||||
Mat out = net.forward();
|
||||
Mat ref = (Mat_<float>(6, 7) << 0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631,
|
||||
0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168,
|
||||
0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290,
|
||||
0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
|
||||
0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
|
||||
0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
|
||||
normAssertDetections(ref, out, "", 0.5, 1e-5, 2e-4);
|
||||
}
|
||||
|
||||
// False positives bug for large faces: https://github.com/opencv/opencv/issues/15106
|
||||
TEST_P(opencv_face_detector, issue_15106)
|
||||
{
|
||||
std::string proto = findDataFile("dnn/opencv_face_detector.prototxt");
|
||||
std::string model = findDataFile(get<0>(GetParam()), false);
|
||||
dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam());
|
||||
|
||||
Net net = readNetFromCaffe(proto, model);
|
||||
Mat img = imread(findDataFile("cv/shared/lena.png"));
|
||||
img = img.rowRange(img.rows / 4, 3 * img.rows / 4).colRange(img.cols / 4, 3 * img.cols / 4);
|
||||
Mat blob = blobFromImage(img, 1.0, Size(300, 300), Scalar(104.0, 177.0, 123.0), false, false);
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
net.setInput(blob);
|
||||
// Output has shape 1x1xNx7 where N - number of detections.
|
||||
// An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
|
||||
Mat out = net.forward();
|
||||
Mat ref = (Mat_<float>(1, 7) << 0, 1, 0.9149431, 0.30424616, 0.26964942, 0.88733053, 0.99815309);
|
||||
normAssertDetections(ref, out, "", 0.2, 6e-5, 1e-4);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
|
||||
Combine(
|
||||
Values("dnn/opencv_face_detector.caffemodel",
|
||||
"dnn/opencv_face_detector_fp16.caffemodel"),
|
||||
Values(DNN_TARGET_CPU, DNN_TARGET_OPENCL)
|
||||
)
|
||||
);
|
||||
|
||||
TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
|
||||
{
|
||||
applyTestTag(
|
||||
#if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
|
||||
CV_TEST_TAG_MEMORY_2GB, // utilizes ~1Gb, but huge blobs may not be allocated on 32-bit systems due memory fragmentation
|
||||
#else
|
||||
(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
#endif
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
#endif
|
||||
|
||||
static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.949398, 99.2454, 210.141, 601.205, 462.849,
|
||||
0, 7, 0.997022, 481.841, 92.3218, 722.685, 175.953,
|
||||
0, 12, 0.993028, 133.221, 189.377, 350.994, 563.166);
|
||||
testFaster("faster_rcnn_vgg16.prototxt", "VGG16_faster_rcnn_final.caffemodel", ref);
|
||||
}
|
||||
|
||||
TEST_P(Test_Caffe_nets, FasterRCNN_zf)
|
||||
{
|
||||
applyTestTag(
|
||||
#if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
#else
|
||||
(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
|
||||
#endif
|
||||
CV_TEST_TAG_DEBUG_LONG
|
||||
);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
|
||||
static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.90121, 120.407, 115.83, 570.586, 528.395,
|
||||
0, 7, 0.988779, 469.849, 75.1756, 718.64, 186.762,
|
||||
0, 12, 0.967198, 138.588, 206.843, 329.766, 553.176);
|
||||
testFaster("faster_rcnn_zf.prototxt", "ZF_faster_rcnn_final.caffemodel", ref);
|
||||
}
|
||||
|
||||
TEST_P(Test_Caffe_nets, RFCN)
|
||||
{
|
||||
applyTestTag(
|
||||
(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_LONG,
|
||||
CV_TEST_TAG_DEBUG_VERYLONG
|
||||
);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
float scoreDiff = default_l1, iouDiff = default_lInf;
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
scoreDiff = 4e-3;
|
||||
iouDiff = 8e-2;
|
||||
}
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.0034;
|
||||
iouDiff = 0.12;
|
||||
}
|
||||
static Mat ref = (Mat_<float>(2, 7) << 0, 7, 0.991359, 491.822, 81.1668, 702.573, 178.234,
|
||||
0, 12, 0.94786, 132.093, 223.903, 338.077, 566.16);
|
||||
testFaster("rfcn_pascal_voc_resnet50.prototxt", "resnet50_rfcn_final.caffemodel", ref, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Caffe_nets, dnnBackendsAndTargets());
|
||||
|
||||
}} // namespace
|
6
3rdparty/opencv-4.5.4/modules/dnn/test/test_common.cpp
vendored
Normal file
6
3rdparty/opencv-4.5.4/modules/dnn/test/test_common.cpp
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "test_common.impl.hpp" // shared with perf tests
|
234
3rdparty/opencv-4.5.4/modules/dnn/test/test_common.hpp
vendored
Normal file
234
3rdparty/opencv-4.5.4/modules/dnn/test/test_common.hpp
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef __OPENCV_TEST_COMMON_HPP__
|
||||
#define __OPENCV_TEST_COMMON_HPP__
|
||||
|
||||
#include "opencv2/dnn/utils/inference_engine.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#endif
|
||||
|
||||
// src/op_inf_engine.hpp
|
||||
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_GE(ver) (((INF_ENGINE_RELEASE) / 10000) >= ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_LT(ver) (((INF_ENGINE_RELEASE) / 10000) < ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_LE(ver) (((INF_ENGINE_RELEASE) / 10000) <= ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
|
||||
|
||||
|
||||
#define CV_TEST_TAG_DNN_SKIP_HALIDE "dnn_skip_halide"
|
||||
#define CV_TEST_TAG_DNN_SKIP_OPENCL "dnn_skip_ocl"
|
||||
#define CV_TEST_TAG_DNN_SKIP_OPENCL_FP16 "dnn_skip_ocl_fp16"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER "dnn_skip_ie_nn_builder"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_NGRAPH "dnn_skip_ie_ngraph"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE "dnn_skip_ie"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_2018R5 "dnn_skip_ie_2018r5"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_2019R1 "dnn_skip_ie_2019r1"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_2019R1_1 "dnn_skip_ie_2019r1_1"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_2019R2 "dnn_skip_ie_2019r2"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_2019R3 "dnn_skip_ie_2019r3"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_CPU "dnn_skip_ie_cpu"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_OPENCL "dnn_skip_ie_ocl"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16 "dnn_skip_ie_ocl_fp16"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2 "dnn_skip_ie_myriad2"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X "dnn_skip_ie_myriadx"
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X
|
||||
#define CV_TEST_TAG_DNN_SKIP_IE_ARM_CPU "dnn_skip_ie_arm_cpu"
|
||||
|
||||
#define CV_TEST_TAG_DNN_SKIP_VULKAN "dnn_skip_vulkan"
|
||||
|
||||
#define CV_TEST_TAG_DNN_SKIP_CUDA "dnn_skip_cuda"
|
||||
#define CV_TEST_TAG_DNN_SKIP_CUDA_FP16 "dnn_skip_cuda_fp16"
|
||||
#define CV_TEST_TAG_DNN_SKIP_CUDA_FP32 "dnn_skip_cuda_fp32"
|
||||
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2018R5
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2019010000)
|
||||
# if INF_ENGINE_RELEASE < 2019010100
|
||||
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1
|
||||
# else
|
||||
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1_1
|
||||
# endif
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2019020000)
|
||||
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2019030000)
|
||||
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R3
|
||||
#endif
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
#ifndef CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE
|
||||
#endif
|
||||
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
void PrintTo(const cv::dnn::Backend& v, std::ostream* os);
|
||||
void PrintTo(const cv::dnn::Target& v, std::ostream* os);
|
||||
using opencv_test::tuple;
|
||||
using opencv_test::get;
|
||||
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os);
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace cv::dnn
|
||||
|
||||
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
void initDNNTests();
|
||||
|
||||
using namespace cv::dnn;
|
||||
|
||||
static inline const std::string &getOpenCVExtraDir()
|
||||
{
|
||||
return cvtest::TS::ptr()->get_data_path();
|
||||
}
|
||||
|
||||
void normAssert(
|
||||
cv::InputArray ref, cv::InputArray test, const char *comment = "",
|
||||
double l1 = 0.00001, double lInf = 0.0001);
|
||||
|
||||
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m);
|
||||
|
||||
void normAssertDetections(
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refScores,
|
||||
const std::vector<cv::Rect2d>& refBoxes,
|
||||
const std::vector<int>& testClassIds,
|
||||
const std::vector<float>& testScores,
|
||||
const std::vector<cv::Rect2d>& testBoxes,
|
||||
const char *comment = "", double confThreshold = 0.0,
|
||||
double scores_diff = 1e-5, double boxes_iou_diff = 1e-4);
|
||||
|
||||
// For SSD-based object detection networks which produce output of shape 1x1xNx7
|
||||
// where N is a number of detections and an every detection is represented by
|
||||
// a vector [batchId, classId, confidence, left, top, right, bottom].
|
||||
void normAssertDetections(
|
||||
cv::Mat ref, cv::Mat out, const char *comment = "",
|
||||
double confThreshold = 0.0, double scores_diff = 1e-5,
|
||||
double boxes_iou_diff = 1e-4);
|
||||
|
||||
// For text detection networks
|
||||
// Curved text polygon is not supported in the current version.
|
||||
// (concave polygon is invalid input to intersectConvexConvex)
|
||||
void normAssertTextDetections(
|
||||
const std::vector<std::vector<Point>>& gtPolys,
|
||||
const std::vector<std::vector<Point>>& testPolys,
|
||||
const char *comment = "", double boxes_iou_diff = 1e-4);
|
||||
|
||||
void readFileContent(const std::string& filename, CV_OUT std::vector<char>& content);
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
bool validateVPUType();
|
||||
#endif
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine = true,
|
||||
bool withHalide = false,
|
||||
bool withCpuOCV = true,
|
||||
bool withVkCom = true,
|
||||
bool withCUDA = true,
|
||||
bool withNgraph = true
|
||||
);
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargetsIE();
|
||||
|
||||
|
||||
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
|
||||
{
|
||||
public:
|
||||
dnn::Backend backend;
|
||||
dnn::Target target;
|
||||
double default_l1, default_lInf;
|
||||
|
||||
DNNTestLayer()
|
||||
{
|
||||
backend = (dnn::Backend)(int)get<0>(GetParam());
|
||||
target = (dnn::Target)(int)get<1>(GetParam());
|
||||
getDefaultThresholds(backend, target, &default_l1, &default_lInf);
|
||||
}
|
||||
|
||||
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
|
||||
{
|
||||
if (target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
*l1 = 4e-3;
|
||||
*lInf = 2e-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*l1 = 1e-5;
|
||||
*lInf = 1e-4;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
&& target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
|
||||
inp->size[0] != 1 && inp->size[0] != ref->size[0])
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void expectNoFallbacks(Net& net, bool raiseError = true)
|
||||
{
|
||||
// Check if all the layers are supported with current backend and target.
|
||||
// Some layers might be fused so their timings equal to zero.
|
||||
std::vector<double> timings;
|
||||
net.getPerfProfile(timings);
|
||||
std::vector<String> names = net.getLayerNames();
|
||||
CV_Assert(names.size() == timings.size());
|
||||
|
||||
bool hasFallbacks = false;
|
||||
for (int i = 0; i < names.size(); ++i)
|
||||
{
|
||||
Ptr<dnn::Layer> l = net.getLayer(net.getLayerId(names[i]));
|
||||
bool fused = !timings[i];
|
||||
if ((!l->supportBackend(backend) || l->preferableTarget != target) && !fused)
|
||||
{
|
||||
hasFallbacks = true;
|
||||
std::cout << "FALLBACK: Layer [" << l->type << "]:[" << l->name << "] is expected to has backend implementation" << endl;
|
||||
}
|
||||
}
|
||||
if (hasFallbacks && raiseError)
|
||||
CV_Error(Error::StsNotImplemented, "Implementation fallbacks are not expected in this test");
|
||||
}
|
||||
|
||||
void expectNoFallbacksFromIE(Net& net)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
expectNoFallbacks(net);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
expectNoFallbacks(net, false);
|
||||
}
|
||||
|
||||
void expectNoFallbacksFromCUDA(Net& net)
|
||||
{
|
||||
if (backend == DNN_BACKEND_CUDA)
|
||||
expectNoFallbacks(net);
|
||||
}
|
||||
|
||||
protected:
|
||||
void checkBackend(Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
checkBackend(backend, target, inp, ref);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif
|
476
3rdparty/opencv-4.5.4/modules/dnn/test/test_common.impl.hpp
vendored
Normal file
476
3rdparty/opencv-4.5.4/modules/dnn/test/test_common.impl.hpp
vendored
Normal file
@ -0,0 +1,476 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Used in accuracy and perf tests as a content of .cpp file
|
||||
// Note: don't use "precomp.hpp" here
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/ts/ts_perf.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
|
||||
#include "opencv2/dnn.hpp"
|
||||
#include "test_common.hpp"
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
|
||||
case DNN_BACKEND_HALIDE: *os << "HALIDE"; return;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE*"; return;
|
||||
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
|
||||
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
|
||||
case DNN_BACKEND_CUDA: *os << "CUDA"; return;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019: *os << "DLIE"; return;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE_NGRAPH: *os << "NGRAPH"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
void PrintTo(const cv::dnn::Target& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_TARGET_CPU: *os << "CPU"; return;
|
||||
case DNN_TARGET_OPENCL: *os << "OCL"; return;
|
||||
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
|
||||
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
|
||||
case DNN_TARGET_HDDL: *os << "HDDL"; return;
|
||||
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
|
||||
case DNN_TARGET_FPGA: *os << "FPGA"; return;
|
||||
case DNN_TARGET_CUDA: *os << "CUDA"; return;
|
||||
case DNN_TARGET_CUDA_FP16: *os << "CUDA_FP16"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
|
||||
{
|
||||
PrintTo(get<0>(v), os);
|
||||
*os << "/";
|
||||
PrintTo(get<1>(v), os);
|
||||
}
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace
|
||||
|
||||
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
void normAssert(
|
||||
cv::InputArray ref, cv::InputArray test, const char *comment /*= ""*/,
|
||||
double l1 /*= 0.00001*/, double lInf /*= 0.0001*/)
|
||||
{
|
||||
double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
|
||||
EXPECT_LE(normL1, l1) << comment << " |ref| = " << cvtest::norm(ref, cv::NORM_INF);
|
||||
|
||||
double normInf = cvtest::norm(ref, test, cv::NORM_INF);
|
||||
EXPECT_LE(normInf, lInf) << comment << " |ref| = " << cvtest::norm(ref, cv::NORM_INF);
|
||||
}
|
||||
|
||||
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m)
|
||||
{
|
||||
EXPECT_EQ(m.type(), CV_32FC1);
|
||||
EXPECT_EQ(m.dims, 2);
|
||||
EXPECT_EQ(m.cols, 4);
|
||||
|
||||
std::vector<cv::Rect2d> boxes(m.rows);
|
||||
for (int i = 0; i < m.rows; ++i)
|
||||
{
|
||||
CV_Assert(m.row(i).isContinuous());
|
||||
const float* data = m.ptr<float>(i);
|
||||
double l = data[0], t = data[1], r = data[2], b = data[3];
|
||||
boxes[i] = cv::Rect2d(l, t, r - l, b - t);
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
|
||||
void normAssertDetections(
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refScores,
|
||||
const std::vector<cv::Rect2d>& refBoxes,
|
||||
const std::vector<int>& testClassIds,
|
||||
const std::vector<float>& testScores,
|
||||
const std::vector<cv::Rect2d>& testBoxes,
|
||||
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
|
||||
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
|
||||
{
|
||||
ASSERT_FALSE(testClassIds.empty()) << "No detections";
|
||||
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
|
||||
std::vector<double> refBoxesIoUDiff(refBoxes.size(), 1.0);
|
||||
for (int i = 0; i < testBoxes.size(); ++i)
|
||||
{
|
||||
//cout << "Test[i=" << i << "]: score=" << testScores[i] << " id=" << testClassIds[i] << " box " << testBoxes[i] << endl;
|
||||
double testScore = testScores[i];
|
||||
if (testScore < confThreshold)
|
||||
continue;
|
||||
|
||||
int testClassId = testClassIds[i];
|
||||
const cv::Rect2d& testBox = testBoxes[i];
|
||||
bool matched = false;
|
||||
double topIoU = 0;
|
||||
for (int j = 0; j < refBoxes.size() && !matched; ++j)
|
||||
{
|
||||
if (!matchedRefBoxes[j] && testClassId == refClassIds[j] &&
|
||||
std::abs(testScore - refScores[j]) < scores_diff)
|
||||
{
|
||||
double interArea = (testBox & refBoxes[j]).area();
|
||||
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
|
||||
topIoU = std::max(topIoU, iou);
|
||||
refBoxesIoUDiff[j] = std::min(refBoxesIoUDiff[j], 1.0f - iou);
|
||||
if (1.0 - iou < boxes_iou_diff)
|
||||
{
|
||||
matched = true;
|
||||
matchedRefBoxes[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched)
|
||||
{
|
||||
std::cout << cv::format("Unmatched prediction: class %d score %f box ",
|
||||
testClassId, testScore) << testBox << std::endl;
|
||||
std::cout << "Highest IoU: " << topIoU << std::endl;
|
||||
}
|
||||
EXPECT_TRUE(matched) << comment;
|
||||
}
|
||||
|
||||
// Check unmatched reference detections.
|
||||
for (int i = 0; i < refBoxes.size(); ++i)
|
||||
{
|
||||
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
|
||||
{
|
||||
std::cout << cv::format("Unmatched reference: class %d score %f box ",
|
||||
refClassIds[i], refScores[i]) << refBoxes[i]
|
||||
<< " IoU diff: " << refBoxesIoUDiff[i]
|
||||
<< std::endl;
|
||||
EXPECT_LE(refScores[i], confThreshold) << comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For SSD-based object detection networks which produce output of shape 1x1xNx7
|
||||
// where N is a number of detections and an every detection is represented by
|
||||
// a vector [batchId, classId, confidence, left, top, right, bottom].
|
||||
void normAssertDetections(
|
||||
cv::Mat ref, cv::Mat out, const char *comment /*= ""*/,
|
||||
double confThreshold /*= 0.0*/, double scores_diff /*= 1e-5*/,
|
||||
double boxes_iou_diff /*= 1e-4*/)
|
||||
{
|
||||
CV_Assert(ref.total() % 7 == 0);
|
||||
CV_Assert(out.total() % 7 == 0);
|
||||
ref = ref.reshape(1, ref.total() / 7);
|
||||
out = out.reshape(1, out.total() / 7);
|
||||
|
||||
cv::Mat refClassIds, testClassIds;
|
||||
ref.col(1).convertTo(refClassIds, CV_32SC1);
|
||||
out.col(1).convertTo(testClassIds, CV_32SC1);
|
||||
std::vector<float> refScores(ref.col(2)), testScores(out.col(2));
|
||||
std::vector<cv::Rect2d> refBoxes = matToBoxes(ref.colRange(3, 7));
|
||||
std::vector<cv::Rect2d> testBoxes = matToBoxes(out.colRange(3, 7));
|
||||
normAssertDetections(refClassIds, refScores, refBoxes, testClassIds, testScores,
|
||||
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
|
||||
}
|
||||
|
||||
// For text detection networks
|
||||
// Curved text polygon is not supported in the current version.
|
||||
// (concave polygon is invalid input to intersectConvexConvex)
|
||||
void normAssertTextDetections(
|
||||
const std::vector<std::vector<Point>>& gtPolys,
|
||||
const std::vector<std::vector<Point>>& testPolys,
|
||||
const char *comment /*= ""*/, double boxes_iou_diff /*= 1e-4*/)
|
||||
{
|
||||
std::vector<bool> matchedRefBoxes(gtPolys.size(), false);
|
||||
for (uint i = 0; i < testPolys.size(); ++i)
|
||||
{
|
||||
const std::vector<Point>& testPoly = testPolys[i];
|
||||
bool matched = false;
|
||||
double topIoU = 0;
|
||||
for (uint j = 0; j < gtPolys.size() && !matched; ++j)
|
||||
{
|
||||
if (!matchedRefBoxes[j])
|
||||
{
|
||||
std::vector<Point> intersectionPolygon;
|
||||
float intersectArea = intersectConvexConvex(testPoly, gtPolys[j], intersectionPolygon, true);
|
||||
double iou = intersectArea / (contourArea(testPoly) + contourArea(gtPolys[j]) - intersectArea);
|
||||
topIoU = std::max(topIoU, iou);
|
||||
if (1.0 - iou < boxes_iou_diff)
|
||||
{
|
||||
matched = true;
|
||||
matchedRefBoxes[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
std::cout << cv::format("Unmatched-det:") << testPoly << std::endl;
|
||||
std::cout << "Highest IoU: " << topIoU << std::endl;
|
||||
}
|
||||
EXPECT_TRUE(matched) << comment;
|
||||
}
|
||||
|
||||
// Check unmatched groundtruth.
|
||||
for (uint i = 0; i < gtPolys.size(); ++i)
|
||||
{
|
||||
if (!matchedRefBoxes[i]) {
|
||||
std::cout << cv::format("Unmatched-gt:") << gtPolys[i] << std::endl;
|
||||
}
|
||||
EXPECT_TRUE(matchedRefBoxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void readFileContent(const std::string& filename, CV_OUT std::vector<char>& content)
|
||||
{
|
||||
const std::ios::openmode mode = std::ios::in | std::ios::binary;
|
||||
std::ifstream ifs(filename.c_str(), mode);
|
||||
ASSERT_TRUE(ifs.is_open());
|
||||
|
||||
content.clear();
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
const size_t sz = ifs.tellg();
|
||||
content.resize(sz);
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
ifs.read((char*)content.data(), sz);
|
||||
ASSERT_FALSE(ifs.fail());
|
||||
}
|
||||
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine /*= true*/,
|
||||
bool withHalide /*= false*/,
|
||||
bool withCpuOCV /*= true*/,
|
||||
bool withVkCom /*= true*/,
|
||||
bool withCUDA /*= true*/,
|
||||
bool withNgraph /*= true*/
|
||||
)
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
bool withVPU = validateVPUType();
|
||||
#endif
|
||||
|
||||
std::vector< tuple<Backend, Target> > targets;
|
||||
std::vector< Target > available;
|
||||
if (withHalide)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_HALIDE);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
|
||||
}
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (withInferenceEngine)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019, *i));
|
||||
}
|
||||
}
|
||||
if (withNgraph)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, *i));
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(withInferenceEngine);
|
||||
#endif
|
||||
if (withVkCom)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_VKCOM);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_VKCOM, *i));
|
||||
}
|
||||
|
||||
#ifdef HAVE_CUDA
|
||||
if(withCUDA)
|
||||
{
|
||||
for (auto target : getAvailableTargets(DNN_BACKEND_CUDA))
|
||||
targets.push_back(make_tuple(DNN_BACKEND_CUDA, target));
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_OPENCV);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if (!withCpuOCV && *i == DNN_TARGET_CPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
|
||||
}
|
||||
}
|
||||
if (targets.empty()) // validate at least CPU mode
|
||||
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
|
||||
return testing::ValuesIn(targets);
|
||||
}
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargetsIE()
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
bool withVPU = validateVPUType();
|
||||
|
||||
std::vector< tuple<Backend, Target> > targets;
|
||||
std::vector< Target > available;
|
||||
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019, *i));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, *i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return testing::ValuesIn(targets);
|
||||
#else
|
||||
return testing::ValuesIn(std::vector< tuple<Backend, Target> >());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
static std::string getTestInferenceEngineVPUType()
|
||||
{
|
||||
static std::string param_vpu_type = utils::getConfigurationParameterString("OPENCV_TEST_DNN_IE_VPU_TYPE", "");
|
||||
return param_vpu_type;
|
||||
}
|
||||
|
||||
static bool validateVPUType_()
|
||||
{
|
||||
std::string test_vpu_type = getTestInferenceEngineVPUType();
|
||||
if (test_vpu_type == "DISABLED" || test_vpu_type == "disabled")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Target> available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
bool have_vpu_target = false;
|
||||
for (std::vector<Target>::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if (*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL)
|
||||
{
|
||||
have_vpu_target = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (test_vpu_type.empty())
|
||||
{
|
||||
if (have_vpu_target)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "OpenCV-DNN-Test: VPU type for testing is not specified via 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter.")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!have_vpu_target)
|
||||
{
|
||||
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter requires VPU of type = '" << test_vpu_type << "', but VPU is not detected. STOP.");
|
||||
exit(1);
|
||||
}
|
||||
std::string dnn_vpu_type = getInferenceEngineVPUType();
|
||||
if (dnn_vpu_type != test_vpu_type)
|
||||
{
|
||||
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'testing' and 'detected' VPU types mismatch: '" << test_vpu_type << "' vs '" << dnn_vpu_type << "'. STOP.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (have_vpu_target)
|
||||
{
|
||||
std::string dnn_vpu_type = getInferenceEngineVPUType();
|
||||
if (dnn_vpu_type == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2)
|
||||
registerGlobalSkipTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
|
||||
if (dnn_vpu_type == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
registerGlobalSkipTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateVPUType()
|
||||
{
|
||||
static bool result = validateVPUType_();
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
|
||||
void initDNNTests()
|
||||
{
|
||||
const char* extraTestDataPath =
|
||||
#ifdef WINRT
|
||||
NULL;
|
||||
#else
|
||||
getenv("OPENCV_DNN_TEST_DATA_PATH");
|
||||
#endif
|
||||
if (extraTestDataPath)
|
||||
cvtest::addDataSearchPath(extraTestDataPath);
|
||||
|
||||
registerGlobalSkipTag(
|
||||
CV_TEST_TAG_DNN_SKIP_HALIDE,
|
||||
CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16
|
||||
);
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
registerGlobalSkipTag(
|
||||
CV_TEST_TAG_DNN_SKIP_IE,
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
CV_TEST_TAG_DNN_SKIP_IE_2018R5,
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2019010000)
|
||||
CV_TEST_TAG_DNN_SKIP_IE_2019R1,
|
||||
# if INF_ENGINE_RELEASE == 2019010100
|
||||
CV_TEST_TAG_DNN_SKIP_IE_2019R1_1,
|
||||
# endif
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2019020000)
|
||||
CV_TEST_TAG_DNN_SKIP_IE_2019R2,
|
||||
#elif INF_ENGINE_VER_MAJOR_EQ(2019030000)
|
||||
CV_TEST_TAG_DNN_SKIP_IE_2019R3,
|
||||
#endif
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH,
|
||||
#endif
|
||||
#ifdef HAVE_DNN_IE_NN_BUILDER_2019
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER,
|
||||
#endif
|
||||
CV_TEST_TAG_DNN_SKIP_IE_CPU
|
||||
);
|
||||
registerGlobalSkipTag(
|
||||
// see validateVPUType(): CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X
|
||||
CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16
|
||||
);
|
||||
#endif
|
||||
#ifdef HAVE_VULKAN
|
||||
registerGlobalSkipTag(
|
||||
CV_TEST_TAG_DNN_SKIP_VULKAN
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CUDA
|
||||
registerGlobalSkipTag(
|
||||
CV_TEST_TAG_DNN_SKIP_CUDA, CV_TEST_TAG_DNN_SKIP_CUDA_FP32, CV_TEST_TAG_DNN_SKIP_CUDA_FP16
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
895
3rdparty/opencv-4.5.4/modules/dnn/test/test_darknet_importer.cpp
vendored
Normal file
895
3rdparty/opencv-4.5.4/modules/dnn/test/test_darknet_importer.cpp
vendored
Normal file
@ -0,0 +1,895 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
// (3-clause BSD License)
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the names of the copyright holders nor the names of the contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
template<typename TString>
|
||||
static std::string _tf(TString filename)
|
||||
{
|
||||
return (getOpenCVExtraDir() + "/dnn/") + filename;
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_tiny_yolo_voc)
|
||||
{
|
||||
Net net = readNetFromDarknet(_tf("tiny-yolo-voc.cfg"));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_yolo_voc)
|
||||
{
|
||||
Net net = readNetFromDarknet(_tf("yolo-voc.cfg"));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(Test_Darknet, read_yolo_voc_stream)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_1GB);
|
||||
Mat ref;
|
||||
Mat sample = imread(_tf("dog416.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0/255, Size(416, 416), Scalar(), true, false);
|
||||
const std::string cfgFile = findDataFile("dnn/yolo-voc.cfg");
|
||||
const std::string weightsFile = findDataFile("dnn/yolo-voc.weights", false);
|
||||
// Import by paths.
|
||||
{
|
||||
Net net = readNetFromDarknet(cfgFile, weightsFile);
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
ref = net.forward();
|
||||
}
|
||||
// Import from bytes array.
|
||||
{
|
||||
std::vector<char> cfg, weights;
|
||||
readFileContent(cfgFile, cfg);
|
||||
readFileContent(weightsFile, weights);
|
||||
|
||||
Net net = readNetFromDarknet(cfg.data(), cfg.size(), weights.data(), weights.size());
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
Mat out = net.forward();
|
||||
normAssert(ref, out);
|
||||
}
|
||||
}
|
||||
|
||||
class Test_Darknet_layers : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
void testDarknetLayer(const std::string& name, bool hasWeights = false, bool testBatchProcessing = true)
|
||||
{
|
||||
SCOPED_TRACE(name);
|
||||
Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy"));
|
||||
Mat ref = blobFromNPY(findDataFile("dnn/darknet/" + name + "_out.npy"));
|
||||
|
||||
std::string cfg = findDataFile("dnn/darknet/" + name + ".cfg");
|
||||
std::string model = "";
|
||||
if (hasWeights)
|
||||
model = findDataFile("dnn/darknet/" + name + ".weights");
|
||||
|
||||
checkBackend(&inp, &ref);
|
||||
|
||||
Net net = readNet(cfg, model);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
normAssert(out, ref, "", default_l1, default_lInf);
|
||||
|
||||
if (inp.size[0] == 1 && testBatchProcessing) // test handling of batch size
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD && name == "shortcut")
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
#endif
|
||||
|
||||
std::vector<int> sz2 = shape(inp);
|
||||
sz2[0] = 2;
|
||||
|
||||
Net net2 = readNet(cfg, model);
|
||||
net2.setPreferableBackend(backend);
|
||||
net2.setPreferableTarget(target);
|
||||
Range ranges0[4] = { Range(0, 1), Range::all(), Range::all(), Range::all() };
|
||||
Range ranges1[4] = { Range(1, 2), Range::all(), Range::all(), Range::all() };
|
||||
Mat inp2(sz2, inp.type(), Scalar::all(0));
|
||||
inp.copyTo(inp2(ranges0));
|
||||
inp.copyTo(inp2(ranges1));
|
||||
net2.setInput(inp2);
|
||||
Mat out2 = net2.forward();
|
||||
EXPECT_EQ(0, cv::norm(out2(ranges0), out2(ranges1), NORM_INF)) << "Batch result is not equal: " << name;
|
||||
|
||||
Mat ref2 = ref;
|
||||
if (ref.dims == 2 && out2.dims == 3)
|
||||
{
|
||||
int ref_3d_sizes[3] = {1, ref.rows, ref.cols};
|
||||
ref2 = Mat(3, ref_3d_sizes, ref.type(), (void*)ref.data);
|
||||
}
|
||||
/*else if (ref.dims == 3 && out2.dims == 4)
|
||||
{
|
||||
int ref_4d_sizes[4] = {1, ref.size[0], ref.size[1], ref.size[2]};
|
||||
ref2 = Mat(4, ref_4d_sizes, ref.type(), (void*)ref.data);
|
||||
}*/
|
||||
ASSERT_EQ(out2.dims, ref2.dims) << ref.dims;
|
||||
|
||||
normAssert(out2(ranges0), ref2, "", default_l1, default_lInf);
|
||||
normAssert(out2(ranges1), ref2, "", default_l1, default_lInf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Test_Darknet_nets : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
// Test object detection network from Darknet framework.
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const std::vector<std::vector<int> >& refClassIds,
|
||||
const std::vector<std::vector<float> >& refConfidences,
|
||||
const std::vector<std::vector<Rect2d> >& refBoxes,
|
||||
double scoreDiff, double iouDiff, float confThreshold = 0.24, float nmsThreshold = 0.4)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat img1 = imread(_tf("dog416.png"));
|
||||
Mat img2 = imread(_tf("street.png"));
|
||||
std::vector<Mat> samples(2);
|
||||
samples[0] = img1; samples[1] = img2;
|
||||
|
||||
// determine test type, whether batch or single img
|
||||
int batch_size = refClassIds.size();
|
||||
CV_Assert(batch_size == 1 || batch_size == 2);
|
||||
samples.resize(batch_size);
|
||||
|
||||
Mat inp = blobFromImages(samples, 1.0/255, Size(416, 416), Scalar(), true, false);
|
||||
|
||||
Net net = readNet(findDataFile("dnn/" + cfg),
|
||||
findDataFile("dnn/" + weights, false));
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.setInput(inp);
|
||||
std::vector<Mat> outs;
|
||||
net.forward(outs, net.getUnconnectedOutLayersNames());
|
||||
|
||||
for (int b = 0; b < batch_size; ++b)
|
||||
{
|
||||
std::vector<int> classIds;
|
||||
std::vector<float> confidences;
|
||||
std::vector<Rect2d> boxes;
|
||||
for (int i = 0; i < outs.size(); ++i)
|
||||
{
|
||||
Mat out;
|
||||
if (batch_size > 1){
|
||||
// get the sample slice from 3D matrix (batch, box, classes+5)
|
||||
Range ranges[3] = {Range(b, b+1), Range::all(), Range::all()};
|
||||
out = outs[i](ranges).reshape(1, outs[i].size[1]);
|
||||
}else{
|
||||
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);
|
||||
|
||||
if (confidence > confThreshold) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// here we need NMS of boxes
|
||||
std::vector<int> indices;
|
||||
NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);
|
||||
|
||||
std::vector<int> nms_classIds;
|
||||
std::vector<float> nms_confidences;
|
||||
std::vector<Rect2d> nms_boxes;
|
||||
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
{
|
||||
int idx = indices[i];
|
||||
Rect2d box = boxes[idx];
|
||||
float conf = confidences[idx];
|
||||
int class_id = classIds[idx];
|
||||
nms_boxes.push_back(box);
|
||||
nms_confidences.push_back(conf);
|
||||
nms_classIds.push_back(class_id);
|
||||
#if 0 // use to update test reference data
|
||||
std::cout << b << ", " << class_id << ", " << conf << "f, "
|
||||
<< box.x << "f, " << box.y << "f, "
|
||||
<< box.x + box.width << "f, " << box.y + box.height << "f,"
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (cvIsNaN(iouDiff))
|
||||
{
|
||||
if (b == 0)
|
||||
std::cout << "Skip accuracy checks" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds,
|
||||
nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refConfidences,
|
||||
const std::vector<Rect2d>& refBoxes,
|
||||
double scoreDiff, double iouDiff, float confThreshold = 0.24, float nmsThreshold = 0.4)
|
||||
{
|
||||
testDarknetModel(cfg, weights,
|
||||
std::vector<std::vector<int> >(1, refClassIds),
|
||||
std::vector<std::vector<float> >(1, refConfidences),
|
||||
std::vector<std::vector<Rect2d> >(1, refBoxes),
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold);
|
||||
}
|
||||
|
||||
void testDarknetModel(const std::string& cfg, const std::string& weights,
|
||||
const cv::Mat& ref, double scoreDiff, double iouDiff,
|
||||
float confThreshold = 0.24, float nmsThreshold = 0.4)
|
||||
{
|
||||
CV_Assert(ref.cols == 7);
|
||||
std::vector<std::vector<int> > refClassIds;
|
||||
std::vector<std::vector<float> > refScores;
|
||||
std::vector<std::vector<Rect2d> > refBoxes;
|
||||
for (int i = 0; i < ref.rows; ++i)
|
||||
{
|
||||
int batchId = static_cast<int>(ref.at<float>(i, 0));
|
||||
int classId = static_cast<int>(ref.at<float>(i, 1));
|
||||
float score = ref.at<float>(i, 2);
|
||||
float left = ref.at<float>(i, 3);
|
||||
float top = ref.at<float>(i, 4);
|
||||
float right = ref.at<float>(i, 5);
|
||||
float bottom = ref.at<float>(i, 6);
|
||||
Rect2d box(left, top, right - left, bottom - top);
|
||||
if (batchId >= refClassIds.size())
|
||||
{
|
||||
refClassIds.resize(batchId + 1);
|
||||
refScores.resize(batchId + 1);
|
||||
refBoxes.resize(batchId + 1);
|
||||
}
|
||||
refClassIds[batchId].push_back(classId);
|
||||
refScores[batchId].push_back(score);
|
||||
refBoxes[batchId].push_back(box);
|
||||
}
|
||||
testDarknetModel(cfg, weights, refClassIds, refScores, refBoxes,
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
{
|
||||
applyTestTag(
|
||||
#if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
|
||||
CV_TEST_TAG_MEMORY_2GB,
|
||||
#else
|
||||
CV_TEST_TAG_MEMORY_1GB,
|
||||
#endif
|
||||
CV_TEST_TAG_LONG
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); // need to update check function
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(6, 7) << 0, 6, 0.750469f, 0.577374f, 0.127391f, 0.902949f, 0.300809f, // a car
|
||||
0, 1, 0.780879f, 0.270762f, 0.264102f, 0.732475f, 0.745412f, // a bicycle
|
||||
0, 11, 0.901615f, 0.1386f, 0.338509f, 0.421337f, 0.938789f, // a dog
|
||||
1, 14, 0.623813f, 0.183179f, 0.381921f, 0.247726f, 0.625847f, // a person
|
||||
1, 6, 0.667770f, 0.446555f, 0.453578f, 0.499986f, 0.519167f, // a car
|
||||
1, 6, 0.844947f, 0.637058f, 0.460398f, 0.828508f, 0.66427f); // a car
|
||||
|
||||
double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.397 : 0.4;
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 1e-2;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.03;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
|
||||
std::string config_file = "yolo-voc.cfg";
|
||||
std::string weights_file = "yolo-voc.weights";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, nmsThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); // need to update check function
|
||||
#endif
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(4, 7) << 0, 6, 0.761967f, 0.579042f, 0.159161f, 0.894482f, 0.31994f, // a car
|
||||
0, 11, 0.780595f, 0.129696f, 0.386467f, 0.445275f, 0.920994f, // a dog
|
||||
1, 6, 0.651450f, 0.460526f, 0.458019f, 0.522527f, 0.5341f, // a car
|
||||
1, 6, 0.928758f, 0.651024f, 0.463539f, 0.823784f, 0.654998f); // a car
|
||||
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 8e-3;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
else if(target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.008;
|
||||
iouDiff = 0.02;
|
||||
}
|
||||
|
||||
std::string config_file = "tiny-yolo-voc.cfg";
|
||||
std::string weights_file = "tiny-yolo-voc.weights";
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
static const std::chrono::milliseconds async_timeout(10000);
|
||||
|
||||
typedef testing::TestWithParam<tuple<std::string, tuple<Backend, Target> > > Test_Darknet_nets_async;
|
||||
TEST_P(Test_Darknet_nets_async, Accuracy)
|
||||
{
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
if (INF_ENGINE_VER_MAJOR_LT(2019020000) && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
std::string prefix = get<0>(GetParam());
|
||||
|
||||
if (targetId == DNN_TARGET_MYRIAD && prefix == "yolov4") // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
|
||||
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("No support for async forward");
|
||||
|
||||
const int numInputs = 2;
|
||||
std::vector<Mat> inputs(numInputs);
|
||||
int blobSize[] = {1, 3, 416, 416};
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
inputs[i].create(4, &blobSize[0], CV_32F);
|
||||
randu(inputs[i], 0, 1);
|
||||
}
|
||||
|
||||
Net netSync = readNet(findDataFile("dnn/" + prefix + ".cfg"),
|
||||
findDataFile("dnn/" + prefix + ".weights", false));
|
||||
netSync.setPreferableBackend(backendId);
|
||||
netSync.setPreferableTarget(targetId);
|
||||
|
||||
// Run synchronously.
|
||||
std::vector<Mat> refs(numInputs);
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
netSync.setInput(inputs[i]);
|
||||
refs[i] = netSync.forward().clone();
|
||||
}
|
||||
|
||||
Net netAsync = readNet(findDataFile("dnn/" + prefix + ".cfg"),
|
||||
findDataFile("dnn/" + prefix + ".weights", false));
|
||||
netAsync.setPreferableBackend(backendId);
|
||||
netAsync.setPreferableTarget(targetId);
|
||||
|
||||
// Run asynchronously. To make test more robust, process inputs in the reversed order.
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
netAsync.setInput(inputs[i]);
|
||||
|
||||
AsyncArray out = netAsync.forwardAsync();
|
||||
ASSERT_TRUE(out.valid());
|
||||
Mat result;
|
||||
EXPECT_TRUE(out.get(result, async_timeout));
|
||||
normAssert(refs[i], result, format("Index: %d", i).c_str(), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine(
|
||||
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4", "yolov4-tiny"),
|
||||
dnnBackendsAndTargets()
|
||||
));
|
||||
|
||||
#endif
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv3)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 6;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 16, 0.998836f, 0.160024f, 0.389964f, 0.417885f, 0.943716f,
|
||||
0, 1, 0.987908f, 0.150913f, 0.221933f, 0.742255f, 0.746261f,
|
||||
0, 7, 0.952983f, 0.614621f, 0.150257f, 0.901368f, 0.289251f,
|
||||
|
||||
1, 2, 0.997412f, 0.647584f, 0.459939f, 0.821037f, 0.663947f,
|
||||
1, 2, 0.989633f, 0.450719f, 0.463353f, 0.496306f, 0.522258f,
|
||||
1, 0, 0.980053f, 0.195856f, 0.378454f, 0.258626f, 0.629257f,
|
||||
1, 9, 0.785341f, 0.665503f, 0.373543f, 0.688893f, 0.439244f,
|
||||
1, 9, 0.733275f, 0.376029f, 0.315694f, 0.401776f, 0.395165f,
|
||||
1, 9, 0.384815f, 0.659824f, 0.372389f, 0.673927f, 0.429412f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = 8e-5, iouDiff = 3e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 0.006;
|
||||
iouDiff = 0.042;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.03;
|
||||
}
|
||||
std::string config_file = "yolov3.cfg";
|
||||
std::string weights_file = "yolov3.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.2;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 7;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 16, 0.992194f, 0.172375f, 0.402458f, 0.403918f, 0.932801f,
|
||||
0, 1, 0.988326f, 0.166708f, 0.228236f, 0.737208f, 0.735803f,
|
||||
0, 7, 0.94639f, 0.602523f, 0.130399f, 0.901623f, 0.298452f,
|
||||
|
||||
1, 2, 0.99761f, 0.646556f, 0.45985f, 0.816041f, 0.659067f,
|
||||
1, 0, 0.988913f, 0.201726f, 0.360282f, 0.266181f, 0.631728f,
|
||||
1, 2, 0.98233f, 0.452007f, 0.462217f, 0.495612f, 0.521687f,
|
||||
1, 9, 0.919195f, 0.374642f, 0.316524f, 0.398126f, 0.393714f,
|
||||
1, 9, 0.856303f, 0.666842f, 0.372215f, 0.685539f, 0.44141f,
|
||||
1, 9, 0.313516f, 0.656791f, 0.374734f, 0.671959f, 0.438371f,
|
||||
1, 9, 0.256625f, 0.940232f, 0.326931f, 0.967586f, 0.374002f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.006 : 8e-5;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.042 : 3e-4;
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.008;
|
||||
iouDiff = 0.03;
|
||||
}
|
||||
|
||||
std::string config_file = "yolov4.cfg";
|
||||
std::string weights_file = "yolov4.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.2;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
#endif
|
||||
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4_tiny)
|
||||
{
|
||||
applyTestTag(
|
||||
target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2021010000) // nGraph compilation failure
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
const double confThreshold = 0.5;
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 2;
|
||||
const int N1 = 3;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 7, 0.85935f, 0.593484f, 0.141211f, 0.920356f, 0.291593f,
|
||||
0, 16, 0.795188f, 0.169207f, 0.386886f, 0.423753f, 0.933004f,
|
||||
|
||||
1, 2, 0.996832f, 0.653802f, 0.464573f, 0.815193f, 0.653292f,
|
||||
1, 2, 0.963325f, 0.451151f, 0.458915f, 0.496255f, 0.52241f,
|
||||
1, 0, 0.926244f, 0.194851f, 0.361743f, 0.260277f, 0.632364f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = 0.01f;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.15 : 0.01f;
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
iouDiff = 0.02;
|
||||
|
||||
std::string config_file = "yolov4-tiny.cfg";
|
||||
std::string weights_file = "yolov4-tiny.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // bad accuracy
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
iouDiff = std::numeric_limits<double>::quiet_NaN();
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // bad accuracy
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv4x_mish)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD) // NC_OUT_OF_MEMORY
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
const int N0 = 3;
|
||||
const int N1 = 5;
|
||||
static const float ref_[/* (N0 + N1) * 7 */] = {
|
||||
0, 16, 0.925536f, 0.17188f, 0.386832f, 0.406138f, 0.941696f,
|
||||
0, 1, 0.912028f, 0.162125f, 0.208863f, 0.741316f, 0.729332f,
|
||||
0, 7, 0.841018f, 0.608953f, 0.128653f, 0.900692f, 0.295657f,
|
||||
|
||||
1, 2, 0.925697f, 0.650438f, 0.458118f, 0.813927f, 0.661775f,
|
||||
1, 0, 0.882156f, 0.203644f, 0.365763f, 0.265473f, 0.632195f,
|
||||
1, 2, 0.848857f, 0.451044f, 0.462997f, 0.496629f, 0.522719f,
|
||||
1, 9, 0.736015f, 0.374503f, 0.316029f, 0.399358f, 0.392883f,
|
||||
1, 9, 0.727129f, 0.662469f, 0.373687f, 0.687877f, 0.441335f,
|
||||
};
|
||||
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
|
||||
|
||||
double scoreDiff = 8e-5;
|
||||
double iouDiff = 3e-4;
|
||||
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.006;
|
||||
iouDiff = 0.042;
|
||||
}
|
||||
|
||||
std::string config_file = "yolov4x-mish.cfg";
|
||||
std::string weights_file = "yolov4x-mish.weights";
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
scoreDiff = 0.04;
|
||||
iouDiff = 0.2;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
else if (target == DNN_TARGET_MYRIAD &&
|
||||
getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
#endif
|
||||
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets());
|
||||
|
||||
TEST_P(Test_Darknet_layers, shortcut)
|
||||
{
|
||||
testDarknetLayer("shortcut");
|
||||
testDarknetLayer("shortcut_leaky");
|
||||
testDarknetLayer("shortcut_unequal");
|
||||
testDarknetLayer("shortcut_unequal_2");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, upsample)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
|
||||
#endif
|
||||
testDarknetLayer("upsample");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, mish)
|
||||
{
|
||||
testDarknetLayer("mish", true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, tanh)
|
||||
{
|
||||
testDarknetLayer("tanh");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, avgpool_softmax)
|
||||
{
|
||||
testDarknetLayer("avgpool_softmax");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, region)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && INF_ENGINE_VER_MAJOR_GE(2020020000))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
testDarknetLayer("region");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, reorg)
|
||||
{
|
||||
testDarknetLayer("reorg");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, route)
|
||||
{
|
||||
testDarknetLayer("route");
|
||||
testDarknetLayer("route_multi");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, maxpool)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
testDarknetLayer("maxpool");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, convolutional)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
default_l1 = 0.01f;
|
||||
}
|
||||
testDarknetLayer("convolutional", true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, scale_channels)
|
||||
{
|
||||
bool testBatches = backend == DNN_BACKEND_CUDA;
|
||||
testDarknetLayer("scale_channels", false, testBatches);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, connected)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
testDarknetLayer("connected", true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, relu)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
testDarknetLayer("relu");
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_layers, sam)
|
||||
{
|
||||
testDarknetLayer("sam", true);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_layers, dnnBackendsAndTargets());
|
||||
|
||||
}} // namespace
|
155
3rdparty/opencv-4.5.4/modules/dnn/test/test_googlenet.cpp
vendored
Normal file
155
3rdparty/opencv-4.5.4/modules/dnn/test/test_googlenet.cpp
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/core/ocl.hpp>
|
||||
#include <opencv2/ts/ocl_test.hpp>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
template<typename TString>
|
||||
static std::string _tf(TString filename)
|
||||
{
|
||||
return (getOpenCVExtraDir() + "/dnn/") + filename;
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<Target> Reproducibility_GoogLeNet;
|
||||
TEST_P(Reproducibility_GoogLeNet, Batching)
|
||||
{
|
||||
const int targetId = GetParam();
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt"),
|
||||
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
if (targetId == DNN_TARGET_OPENCL)
|
||||
{
|
||||
// Initialize network for a single image in the batch but test with batch size=2.
|
||||
Mat inp = Mat(224, 224, CV_8UC3);
|
||||
randu(inp, -1, 1);
|
||||
net.setInput(blobFromImage(inp));
|
||||
net.forward();
|
||||
}
|
||||
|
||||
std::vector<Mat> inpMats;
|
||||
inpMats.push_back( imread(_tf("googlenet_0.png")) );
|
||||
inpMats.push_back( imread(_tf("googlenet_1.png")) );
|
||||
ASSERT_TRUE(!inpMats[0].empty() && !inpMats[1].empty());
|
||||
|
||||
net.setInput(blobFromImages(inpMats, 1.0f, Size(), Scalar(), false), "data");
|
||||
Mat out = net.forward("prob");
|
||||
|
||||
Mat ref = blobFromNPY(_tf("googlenet_prob.npy"));
|
||||
normAssert(out, ref);
|
||||
}
|
||||
|
||||
TEST_P(Reproducibility_GoogLeNet, IntermediateBlobs)
|
||||
{
|
||||
const int targetId = GetParam();
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt"),
|
||||
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
std::vector<String> blobsNames;
|
||||
blobsNames.push_back("conv1/7x7_s2");
|
||||
blobsNames.push_back("conv1/relu_7x7");
|
||||
blobsNames.push_back("inception_4c/1x1");
|
||||
blobsNames.push_back("inception_4c/relu_1x1");
|
||||
std::vector<Mat> outs;
|
||||
Mat in = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(), Scalar(), false);
|
||||
net.setInput(in, "data");
|
||||
net.forward(outs, blobsNames);
|
||||
CV_Assert(outs.size() == blobsNames.size());
|
||||
|
||||
for (size_t i = 0; i < blobsNames.size(); i++)
|
||||
{
|
||||
std::string filename = blobsNames[i];
|
||||
std::replace( filename.begin(), filename.end(), '/', '#');
|
||||
Mat ref = blobFromNPY(_tf("googlenet_" + filename + ".npy"));
|
||||
|
||||
normAssert(outs[i], ref, "", 1E-4, 1E-2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Reproducibility_GoogLeNet, SeveralCalls)
|
||||
{
|
||||
const int targetId = GetParam();
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
Net net = readNetFromCaffe(findDataFile("dnn/bvlc_googlenet.prototxt"),
|
||||
findDataFile("dnn/bvlc_googlenet.caffemodel", false));
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
std::vector<Mat> inpMats;
|
||||
inpMats.push_back( imread(_tf("googlenet_0.png")) );
|
||||
inpMats.push_back( imread(_tf("googlenet_1.png")) );
|
||||
ASSERT_TRUE(!inpMats[0].empty() && !inpMats[1].empty());
|
||||
|
||||
net.setInput(blobFromImages(inpMats, 1.0f, Size(), Scalar(), false), "data");
|
||||
Mat out = net.forward();
|
||||
|
||||
Mat ref = blobFromNPY(_tf("googlenet_prob.npy"));
|
||||
normAssert(out, ref);
|
||||
|
||||
std::vector<String> blobsNames;
|
||||
blobsNames.push_back("conv1/7x7_s2");
|
||||
std::vector<Mat> outs;
|
||||
Mat in = blobFromImage(inpMats[0], 1.0f, Size(), Scalar(), false);
|
||||
net.setInput(in, "data");
|
||||
net.forward(outs, blobsNames);
|
||||
CV_Assert(outs.size() == blobsNames.size());
|
||||
|
||||
ref = blobFromNPY(_tf("googlenet_conv1#7x7_s2.npy"));
|
||||
|
||||
normAssert(outs[0], ref, "", 1E-4, 1E-2);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_GoogLeNet,
|
||||
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
|
||||
|
||||
}} // namespace
|
950
3rdparty/opencv-4.5.4/modules/dnn/test/test_halide_layers.cpp
vendored
Normal file
950
3rdparty/opencv-4.5.4/modules/dnn/test/test_halide_layers.cpp
vendored
Normal file
@ -0,0 +1,950 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
// This tests doesn't require any external data. They just compare outputs of
|
||||
// layers using different computation backends. Input and parameters are random.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
using namespace testing;
|
||||
|
||||
static void test(Mat& input, Net& net, Backend backendId, Target targetId, bool skipCheck = false, bool randInput = true, double l1 = 0.0, double lInf = 0.0)
|
||||
{
|
||||
DNNTestLayer::checkBackend(backendId, targetId);
|
||||
if (randInput)
|
||||
randu(input, -1.0f, 1.0f);
|
||||
|
||||
net.setInput(input);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
Mat outputDefault = net.forward().clone();
|
||||
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
Mat outputHalide = net.forward().clone();
|
||||
|
||||
if (skipCheck)
|
||||
return;
|
||||
|
||||
double default_l1, default_lInf;
|
||||
DNNTestLayer::getDefaultThresholds(backendId, targetId, &default_l1, &default_lInf);
|
||||
if (l1 == 0.0)
|
||||
l1 = default_l1;
|
||||
if (lInf == 0.0)
|
||||
lInf = default_lInf;
|
||||
#if 0
|
||||
std::cout << "l1=" << l1 << " lInf=" << lInf << std::endl;
|
||||
std::cout << outputDefault.reshape(1, outputDefault.total()).t() << std::endl;
|
||||
std::cout << outputHalide.reshape(1, outputDefault.total()).t() << std::endl;
|
||||
#endif
|
||||
normAssert(outputDefault, outputHalide, "", l1, lInf);
|
||||
}
|
||||
|
||||
static void test(LayerParams& params, Mat& input, Backend backendId, Target targetId, bool skipCheck = false, double l1 = 0.0, double lInf = 0.0)
|
||||
{
|
||||
Net net;
|
||||
net.addLayerToPrev(params.name, params.type, params);
|
||||
test(input, net, backendId, targetId, skipCheck, true, l1, lInf);
|
||||
}
|
||||
|
||||
static inline testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargetsWithHalide()
|
||||
{
|
||||
return dnnBackendsAndTargets(true, true, false); // OpenCV/CPU is used as reference
|
||||
}
|
||||
|
||||
class Test_Halide_layers : public DNNTestLayer {};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Padding
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST_P(Test_Halide_layers, Padding)
|
||||
{
|
||||
static const int kNumRuns = 10;
|
||||
std::vector<int> paddings(8);
|
||||
cv::RNG& rng = cv::theRNG();
|
||||
for (int t = 0; t < kNumRuns; ++t)
|
||||
{
|
||||
for (int i = 0; i < paddings.size(); ++i)
|
||||
paddings[i] = rng(5);
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("paddings", DictValue::arrayInt<int*>(&paddings[0], paddings.size()));
|
||||
lp.type = "Padding";
|
||||
lp.name = "testLayer";
|
||||
|
||||
int sz[] = {1 + (int)rng(10), 1 + (int)rng(10), 1 + (int)rng(10), 1 + (int)rng(10)};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(lp, input, backend, target);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Convolution
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<Vec3i, Size, Size, Size, Size, Size, bool, tuple<Backend, Target> > > Convolution;
|
||||
TEST_P(Convolution, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam())[0];
|
||||
int outChannels = get<0>(GetParam())[1];
|
||||
int group = get<0>(GetParam())[2];
|
||||
Size inSize = get<1>(GetParam());
|
||||
Size kernel = get<2>(GetParam());
|
||||
Size stride = get<3>(GetParam());
|
||||
Size pad = get<4>(GetParam());
|
||||
Size dilation = get<5>(GetParam());
|
||||
bool hasBias = get<6>(GetParam());
|
||||
Backend backendId = get<0>(get<7>(GetParam()));
|
||||
Target targetId = get<1>(get<7>(GetParam()));
|
||||
|
||||
bool skipCheck = false;
|
||||
|
||||
int sz[] = {outChannels, inChannels / group, kernel.height, kernel.width};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("kernel_w", kernel.width);
|
||||
lp.set("kernel_h", kernel.height);
|
||||
lp.set("pad_w", pad.width);
|
||||
lp.set("pad_h", pad.height);
|
||||
lp.set("stride_w", stride.width);
|
||||
lp.set("stride_h", stride.height);
|
||||
lp.set("dilation_w", dilation.width);
|
||||
lp.set("dilation_h", dilation.height);
|
||||
lp.set("num_output", outChannels);
|
||||
lp.set("group", group);
|
||||
lp.set("bias_term", hasBias);
|
||||
lp.type = "Convolution";
|
||||
lp.name = "testLayer";
|
||||
lp.blobs.push_back(weights);
|
||||
if (hasBias)
|
||||
{
|
||||
Mat bias(1, outChannels, CV_32F);
|
||||
randu(bias, -1.0f, 1.0f);
|
||||
lp.blobs.push_back(bias);
|
||||
}
|
||||
int inpSz[] = {1, inChannels, inSize.height, inSize.width};
|
||||
Mat input(4, &inpSz[0], CV_32F);
|
||||
test(lp, input, backendId, targetId, skipCheck);
|
||||
if (skipCheck)
|
||||
throw SkipTestException("Skip checks in unstable test");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Convolution, Combine(
|
||||
/*in channels, out channels, group*/
|
||||
Values(Vec3i(6, 4, 1), Vec3i(6, 9, 1),
|
||||
Vec3i(6, 4, 2), Vec3i(6, 9, 3)),
|
||||
/*in size*/ Values(Size(5, 6)),
|
||||
/*kernel*/ Values(Size(3, 1), Size(1, 3)),
|
||||
/*stride*/ Values(Size(1, 1), Size(2, 2)),
|
||||
/*pad*/ Values(Size(1, 0), Size(0, 1)),
|
||||
/*dilation*/ Values(Size(1, 1), Size(2, 2)),
|
||||
/*has bias*/ Bool(),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Deconvolution
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<Vec3i, Size, Size, Size, Size, Vec4i, bool, tuple<Backend, Target> > > Deconvolution;
|
||||
TEST_P(Deconvolution, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam())[0];
|
||||
int outChannels = get<0>(GetParam())[1];
|
||||
int group = get<0>(GetParam())[2];
|
||||
Size inSize = get<1>(GetParam());
|
||||
Size kernel = get<2>(GetParam());
|
||||
Size pad = get<3>(GetParam());
|
||||
Size dilation = get<4>(GetParam());
|
||||
Size stride = Size(get<5>(GetParam())[0], get<5>(GetParam())[1]);
|
||||
Size adjPad = Size(get<5>(GetParam())[2], get<5>(GetParam())[3]);
|
||||
bool hasBias = get<6>(GetParam());
|
||||
Backend backendId = get<0>(get<7>(GetParam()));
|
||||
Target targetId = get<1>(get<7>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
&& inChannels == 6 && outChannels == 4 && group == 1
|
||||
&& kernel == Size(1, 3) && pad == Size(1, 0)
|
||||
&& stride == Size(1, 1) && dilation == Size(1, 1))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
|
||||
if (targetId == DNN_TARGET_CUDA_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
|
||||
|
||||
int sz[] = {inChannels, outChannels / group, kernel.height, kernel.width};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("kernel_w", kernel.width);
|
||||
lp.set("kernel_h", kernel.height);
|
||||
lp.set("pad_w", pad.width);
|
||||
lp.set("pad_h", pad.height);
|
||||
lp.set("stride_w", stride.width);
|
||||
lp.set("stride_h", stride.height);
|
||||
lp.set("dilation_w", dilation.width);
|
||||
lp.set("dilation_h", dilation.height);
|
||||
lp.set("adj_w", adjPad.width);
|
||||
lp.set("adj_h", adjPad.height);
|
||||
lp.set("num_output", outChannels);
|
||||
lp.set("group", group);
|
||||
lp.set("bias_term", hasBias);
|
||||
lp.type = "Deconvolution";
|
||||
lp.name = "testLayer";
|
||||
lp.blobs.push_back(weights);
|
||||
if (hasBias)
|
||||
{
|
||||
Mat bias(1, outChannels, CV_32F);
|
||||
randu(bias, -1.0f, 1.0f);
|
||||
lp.blobs.push_back(bias);
|
||||
}
|
||||
int inpSz[] = {1, inChannels, inSize.height, inSize.width};
|
||||
Mat input(4, &inpSz[0], CV_32F);
|
||||
test(lp, input, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Deconvolution, Combine(
|
||||
/*in channels, out channels, group*/
|
||||
Values(Vec3i(6, 4, 1), Vec3i(6, 9, 3)),
|
||||
/*in size*/ Values(Size(5, 6)),
|
||||
/*kernel*/ Values(Size(3, 1), Size(1, 3)),
|
||||
/*pad*/ Values(Size(1, 0), Size(0, 1)),
|
||||
/*dilation*/ Values(Size(1, 1)),
|
||||
/*stride, adj. pad*/ Values(Vec4i(1,1, 0,0), Vec4i(2,2, 1,0), Vec4i(1,2, 0,1)),
|
||||
/*has bias*/ Bool(),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// LRN
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<Vec3i, int, Vec3f, bool, std::string, tuple<Backend, Target> > > LRN;
|
||||
TEST_P(LRN, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam())[0];
|
||||
Size inSize = Size(get<0>(GetParam())[1], get<0>(GetParam())[2]);
|
||||
int localSize = get<1>(GetParam());
|
||||
float alpha = get<2>(GetParam())[0];
|
||||
float beta = get<2>(GetParam())[1];
|
||||
float bias = get<2>(GetParam())[2];
|
||||
bool normBySize = get<3>(GetParam());
|
||||
std::string nrmType = get<4>(GetParam());
|
||||
Backend backendId = get<0>(get<5>(GetParam()));
|
||||
Target targetId = get<1>(get<5>(GetParam()));
|
||||
|
||||
if ((inSize.width == 5 || inSize.height == 5) && targetId == DNN_TARGET_MYRIAD &&
|
||||
nrmType == "ACROSS_CHANNELS")
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("norm_region", nrmType);
|
||||
lp.set("local_size", localSize);
|
||||
lp.set("alpha", alpha);
|
||||
lp.set("beta", beta);
|
||||
lp.set("bias", bias);
|
||||
lp.set("norm_by_size", normBySize);
|
||||
lp.type = "LRN";
|
||||
lp.name = "testLayer";
|
||||
|
||||
int sz[] = {1, inChannels, inSize.height, inSize.width};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
|
||||
double l1 = 0.0, lInf = 0.0;
|
||||
// The OpenCL kernels use the native_ math functions which have
|
||||
// implementation defined accuracy, so we use relaxed thresholds. See
|
||||
// https://github.com/opencv/opencv/issues/9821 for more details.
|
||||
if (targetId == DNN_TARGET_OPENCL)
|
||||
{
|
||||
l1 = 0.01;
|
||||
lInf = 0.01;
|
||||
}
|
||||
test(lp, input, backendId, targetId, false, l1, lInf);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, LRN, Combine(
|
||||
/*input ch,w,h*/ Values(Vec3i(6, 5, 8), Vec3i(7, 11, 6)),
|
||||
/*local size*/ Values(3, 5),
|
||||
Values(Vec3f(0.9f, 1.0f, 1.1f), Vec3f(0.9f, 1.1f, 1.0f),
|
||||
/*alpha, beta, bias*/ Vec3f(1.0f, 0.9f, 1.1f), Vec3f(1.0f, 1.1f, 0.9f),
|
||||
Vec3f(1.1f, 0.9f, 1.0f), Vec3f(1.1f, 1.0f, 0.9f)),
|
||||
/*norm_by_size*/ Bool(),
|
||||
/*norm_type*/ Values("ACROSS_CHANNELS", "WITHIN_CHANNEL"),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Average pooling
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<int, Size, Size, Size, tuple<Backend, Target> > > AvePooling;
|
||||
TEST_P(AvePooling, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam());
|
||||
Size outSize = get<1>(GetParam());; // Input size will be computed from parameters.
|
||||
Size kernel = get<2>(GetParam());
|
||||
Size stride = get<3>(GetParam());
|
||||
Backend backendId = get<0>(get<4>(GetParam()));
|
||||
Target targetId = get<1>(get<4>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
&& kernel == Size(1, 1) && (stride == Size(1, 1) || stride == Size(2, 2)))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
|
||||
const int inWidth = (outSize.width - 1) * stride.width + kernel.width;
|
||||
const int inHeight = (outSize.height - 1) * stride.height + kernel.height;
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("pool", "ave");
|
||||
lp.set("kernel_w", kernel.width);
|
||||
lp.set("kernel_h", kernel.height);
|
||||
lp.set("stride_w", stride.width);
|
||||
lp.set("stride_h", stride.height);
|
||||
lp.type = "Pooling";
|
||||
lp.name = "testLayer";
|
||||
|
||||
int sz[] = {1, inChannels, inHeight, inWidth};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(lp, input, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, AvePooling, Combine(
|
||||
/*in channels*/ Values(3, 4),
|
||||
/*out size*/ Values(Size(1, 1), Size(2, 2), Size(3, 2), Size(4, 7)),
|
||||
/*kernel*/ Values(Size(1, 1), Size(2, 2), Size(3, 3), Size(3, 2)),
|
||||
/*stride*/ Values(Size(1, 1), Size(2, 2), Size(3, 2)),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Maximum pooling
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<int, Size, Size, Size, Size, tuple<Backend, Target> > > MaxPooling;
|
||||
TEST_P(MaxPooling, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam());
|
||||
Size inSize = get<1>(GetParam());
|
||||
Size kernel = get<2>(GetParam());
|
||||
Size stride = get<3>(GetParam());
|
||||
Size pad = get<4>(GetParam());
|
||||
Backend backendId = get<0>(get<5>(GetParam()));
|
||||
Target targetId = get<1>(get<5>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD
|
||||
&& inSize == Size(7, 6) && kernel == Size(3, 2)
|
||||
&& (stride == Size(1, 1) || stride == Size(2, 2))
|
||||
&& (pad == Size(0, 1) || pad == Size(1, 1))
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD
|
||||
&& (kernel == Size(2, 2) || kernel == Size(3, 2))
|
||||
&& stride == Size(1, 1) && (pad == Size(0, 0) || pad == Size(0, 1))
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
&& (stride == Size(1, 1) || stride == Size(2, 2))
|
||||
&& (pad == Size(0, 1) || pad == Size(1, 1))
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && targetId == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("pool", "max");
|
||||
lp.set("kernel_w", kernel.width);
|
||||
lp.set("kernel_h", kernel.height);
|
||||
lp.set("stride_w", stride.width);
|
||||
lp.set("stride_h", stride.height);
|
||||
lp.set("pad_w", pad.width);
|
||||
lp.set("pad_h", pad.height);
|
||||
lp.type = "Pooling";
|
||||
lp.name = "testLayer";
|
||||
|
||||
int sz[] = {1, inChannels, inSize.height, inSize.width};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(lp, input, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, MaxPooling, Combine(
|
||||
/*in channels*/ Values(3, 4),
|
||||
/*in size*/ Values(Size(5, 5), Size(7, 6)),
|
||||
/*kernel*/ Values(Size(2, 2), Size(3, 3), Size(3, 2)),
|
||||
/*stride*/ Values(Size(1, 1), Size(2, 2), Size(3, 2)),
|
||||
/*pad*/ Values(Size(0, 0), Size(1, 1), Size(0, 1)),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Fully-connected
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<int, Size, int, bool, tuple<Backend, Target> > > FullyConnected;
|
||||
TEST_P(FullyConnected, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam());
|
||||
Size inSize = get<1>(GetParam());
|
||||
int outChannels = get<2>(GetParam());
|
||||
bool hasBias = get<3>(GetParam());
|
||||
Backend backendId = get<0>(get<4>(GetParam()));
|
||||
Target targetId = get<1>(get<4>(GetParam()));
|
||||
if ((backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && (targetId == DNN_TARGET_OPENCL_FP16 ||
|
||||
(targetId == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X))) {
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
}
|
||||
|
||||
Mat weights(outChannels, inChannels * inSize.height * inSize.width, CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
|
||||
Mat bias(1, outChannels, CV_32F);
|
||||
randu(bias, -1.0f, 1.0f);
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("num_output", outChannels);
|
||||
lp.set("bias_term", hasBias);
|
||||
lp.blobs.push_back(weights);
|
||||
lp.blobs.push_back(bias);
|
||||
lp.type = "InnerProduct";
|
||||
lp.name = "testLayer";
|
||||
|
||||
int sz[] = {1, inChannels, inSize.height, inSize.width};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
|
||||
double l1 = 0.0;
|
||||
if (targetId == DNN_TARGET_CUDA_FP16)
|
||||
l1 = 0.015;
|
||||
test(lp, input, backendId, targetId, false, true, l1);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, FullyConnected, Combine(
|
||||
/*in channels*/ Values(3, 4),
|
||||
/*in size*/ Values(Size(5, 4), Size(4, 5), Size(1, 1)),
|
||||
/*out channels*/ Values(3, 4),
|
||||
/*has bias*/ Bool(),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SoftMax
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef TestWithParam<tuple<int, tuple<Backend, Target> > > SoftMax;
|
||||
TEST_P(SoftMax, Accuracy)
|
||||
{
|
||||
int inChannels = get<0>(GetParam());
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
LayerParams lp;
|
||||
lp.type = "Softmax";
|
||||
lp.name = "testLayer";
|
||||
|
||||
int sz[] = {1, inChannels, 1, 1};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(lp, input, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, SoftMax, Combine(
|
||||
Values(3, 4, 5, 1024),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Max pooling - unpooling
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
TEST_P(Test_Halide_layers, MaxPoolUnpool)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
LayerParams pool;
|
||||
pool.set("pool", "max");
|
||||
pool.set("kernel_w", 2);
|
||||
pool.set("kernel_h", 2);
|
||||
pool.set("stride_w", 2);
|
||||
pool.set("stride_h", 2);
|
||||
pool.set("pad_w", 0);
|
||||
pool.set("pad_h", 0);
|
||||
pool.type = "Pooling";
|
||||
pool.name = "testPool";
|
||||
|
||||
LayerParams unpool;
|
||||
unpool.set("pool_k_w", 2);
|
||||
unpool.set("pool_k_h", 2);
|
||||
unpool.set("pool_stride_w", 2);
|
||||
unpool.set("pool_stride_h", 2);
|
||||
unpool.set("pool_pad_w", 0);
|
||||
unpool.set("pool_pad_h", 0);
|
||||
unpool.type = "MaxUnpool";
|
||||
unpool.name = "testUnpool";
|
||||
|
||||
Net net;
|
||||
int poolId = net.addLayer(pool.name, pool.type, pool);
|
||||
net.connect(0, 0, poolId, 0);
|
||||
|
||||
int unpoolId = net.addLayer(unpool.name, unpool.type, unpool);
|
||||
net.connect(poolId, 0, unpoolId, 0);
|
||||
net.connect(poolId, 1, unpoolId, 1);
|
||||
|
||||
int sz[] = {1, 1, 4, 4};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(input, net, backend, target);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AvePooling + in-place layers
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static const int kNumChannels = 3;
|
||||
|
||||
void testInPlaceActivation(LayerParams& lp, Backend backendId, Target targetId, double l1 = 0.0, double lInf = 0.0)
|
||||
{
|
||||
EXPECT_FALSE(lp.name.empty());
|
||||
|
||||
LayerParams pool;
|
||||
pool.set("pool", "ave");
|
||||
pool.set("kernel_w", 2);
|
||||
pool.set("kernel_h", 2);
|
||||
pool.set("stride_w", 2);
|
||||
pool.set("stride_h", 2);
|
||||
pool.type = "Pooling";
|
||||
pool.name = "ave_pool";
|
||||
|
||||
Net net;
|
||||
int poolId = net.addLayer(pool.name, pool.type, pool);
|
||||
net.connect(0, 0, poolId, 0);
|
||||
net.addLayerToPrev(lp.name, lp.type, lp);
|
||||
|
||||
int sz[] = {1, kNumChannels, 10, 10};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(input, net, backendId, targetId, false, true, l1, lInf);
|
||||
}
|
||||
|
||||
typedef TestWithParam<tuple<bool, bool, float, tuple<Backend, Target> > > BatchNorm;
|
||||
TEST_P(BatchNorm, Accuracy)
|
||||
{
|
||||
bool hasWeights = get<0>(GetParam());
|
||||
bool hasBias = get<1>(GetParam());
|
||||
float epsilon = get<2>(GetParam());
|
||||
Backend backendId = get<0>(get<3>(GetParam()));
|
||||
Target targetId = get<1>(get<3>(GetParam()));
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("has_weight", hasWeights);
|
||||
lp.set("has_bias", hasBias);
|
||||
lp.set("eps", epsilon);
|
||||
lp.type = "BatchNorm";
|
||||
lp.name = "testLayer";
|
||||
|
||||
lp.blobs.reserve(4);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
|
||||
if (hasBias || hasWeights)
|
||||
lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
|
||||
|
||||
for (int i = 0; i < lp.blobs.size(); ++i)
|
||||
randu(lp.blobs[i], 0.0f, 1.0f);
|
||||
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, BatchNorm, Combine(
|
||||
/*has weights*/ Bool(),
|
||||
/*has bias*/ Bool(),
|
||||
/*epsilon*/ Values(1e-3f, 1e-5f),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
typedef TestWithParam<tuple<float, tuple<Backend, Target> > > ReLU;
|
||||
TEST_P(ReLU, Accuracy)
|
||||
{
|
||||
float negativeSlope = get<0>(GetParam());
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019020000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD && negativeSlope < 0)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("negative_slope", negativeSlope);
|
||||
lp.type = "ReLU";
|
||||
lp.name = "testLayer";
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, ReLU, Combine(
|
||||
/*negative slope*/ Values(2.0f, 0.3f, -0.1f, 0.0f),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
typedef TestWithParam<tuple<std::string, tuple<Backend, Target> > > NoParamActivation;
|
||||
TEST_P(NoParamActivation, Accuracy)
|
||||
{
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
LayerParams lp;
|
||||
lp.type = get<0>(GetParam());
|
||||
lp.name = "testLayer";
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, NoParamActivation, Combine(
|
||||
/*type*/ Values("TanH", "Sigmoid", "AbsVal", "BNLL", "Swish", "Mish"),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
typedef TestWithParam<tuple<Vec3f, tuple<Backend, Target> > > Power;
|
||||
TEST_P(Power, Accuracy)
|
||||
{
|
||||
float power = get<0>(GetParam())[0];
|
||||
float scale = get<0>(GetParam())[1];
|
||||
float shift = get<0>(GetParam())[2];
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("power", power);
|
||||
lp.set("scale", scale);
|
||||
lp.set("shift", shift);
|
||||
lp.type = "Power";
|
||||
lp.name = "testLayer";
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Power, Combine(
|
||||
/*power, scale, shift*/ Values(Vec3f(0.9f, 1.0f, 1.1f), Vec3f(0.9f, 1.1f, 1.0f),
|
||||
Vec3f(1.0f, 0.9f, 1.1f), Vec3f(1.0f, 1.1f, 0.9f),
|
||||
Vec3f(1.1f, 0.9f, 1.0f), Vec3f(1.1f, 1.0f, 0.9f)),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
typedef TestWithParam<tuple<Vec3f, tuple<Backend, Target> > > Exp;
|
||||
TEST_P(Exp, Accuracy)
|
||||
{
|
||||
float base = get<0>(GetParam())[0];
|
||||
float scale = get<0>(GetParam())[1];
|
||||
float shift = get<0>(GetParam())[2];
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("base", base);
|
||||
lp.set("scale", scale);
|
||||
lp.set("shift", shift);
|
||||
lp.type = "Exp";
|
||||
lp.name = "testLayer";
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Exp, Combine(
|
||||
/*base, scale, shift*/ Values(Vec3f(0.9f, -1.0f, 1.1f), Vec3f(0.9f, 1.1f, -1.0f),
|
||||
Vec3f(-1.0f, 0.9f, 1.1f), Vec3f(-1.0f, 1.1f, 0.9f),
|
||||
Vec3f(1.1f, 0.9f, -1.0f), Vec3f(1.1f, -1.0f, 0.9f)),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
TEST_P(Test_Halide_layers, ChannelsPReLU)
|
||||
{
|
||||
LayerParams lp;
|
||||
lp.type = "ChannelsPReLU";
|
||||
lp.name = "testLayer";
|
||||
lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
|
||||
randu(lp.blobs[0], -1.0f, 1.0f);
|
||||
|
||||
testInPlaceActivation(lp, backend, target);
|
||||
}
|
||||
|
||||
typedef TestWithParam<tuple<bool, tuple<Backend, Target> > > Scale;
|
||||
TEST_P(Scale, Accuracy)
|
||||
{
|
||||
bool hasBias = get<0>(GetParam());
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("bias_term", hasBias);
|
||||
lp.type = "Scale";
|
||||
lp.name = "testLayer";
|
||||
lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
|
||||
randu(lp.blobs[0], -1.0f, 1.0f);
|
||||
if (hasBias)
|
||||
{
|
||||
lp.blobs.push_back(Mat(1, kNumChannels, CV_32F));
|
||||
randu(lp.blobs[1], -1.0f, 1.0f);
|
||||
}
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Scale, Combine(
|
||||
Bool(),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Concat layer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// input --- conv --- concat --- output
|
||||
// `--- conv ----^ ^ ^
|
||||
// `---- ... ------' '
|
||||
// `-----------------'
|
||||
typedef TestWithParam<tuple<Vec3i, Vec3i, tuple<Backend, Target> > > Concat;
|
||||
TEST_P(Concat, Accuracy)
|
||||
{
|
||||
Vec3i inSize = get<0>(GetParam());
|
||||
Vec3i numChannels = get<1>(GetParam());
|
||||
Backend backendId = get<0>(get<2>(GetParam()));
|
||||
Target targetId = get<1>(get<2>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD
|
||||
&& inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION); // crash
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_CPU
|
||||
&& inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION); // TODO: IE_CPU
|
||||
#endif
|
||||
|
||||
Net net;
|
||||
|
||||
std::vector<int> convLayerIds;
|
||||
convLayerIds.reserve(numChannels.channels);
|
||||
for (int i = 0, n = numChannels.channels; i < n; ++i)
|
||||
{
|
||||
if (!numChannels[i])
|
||||
break;
|
||||
|
||||
int sz[] = {numChannels[i], inSize[0], 1, 1};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
|
||||
LayerParams convParam;
|
||||
convParam.set("kernel_w", 1);
|
||||
convParam.set("kernel_h", 1);
|
||||
convParam.set("num_output", numChannels[i]);
|
||||
convParam.set("bias_term", false);
|
||||
convParam.type = "Convolution";
|
||||
std::ostringstream ss;
|
||||
ss << "convLayer" << i;
|
||||
convParam.name = ss.str();
|
||||
convParam.blobs.push_back(weights);
|
||||
|
||||
int layerId = net.addLayer(convParam.name, convParam.type, convParam);
|
||||
convLayerIds.push_back(layerId);
|
||||
net.connect(0, 0, layerId, 0);
|
||||
}
|
||||
|
||||
LayerParams concatParam;
|
||||
concatParam.type = "Concat";
|
||||
concatParam.name = "testLayer";
|
||||
int concatId = net.addLayer(concatParam.name, concatParam.type, concatParam);
|
||||
net.connect(0, 0, concatId, 0);
|
||||
for (int i = 0; i < convLayerIds.size(); ++i)
|
||||
{
|
||||
net.connect(convLayerIds[i], 0, concatId, i + 1);
|
||||
}
|
||||
|
||||
int sz[] = {1, inSize[0], inSize[1], inSize[2]};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
test(input, net, backendId, targetId);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Concat, Combine(
|
||||
/*input size*/ Values(Vec3i(1, 4, 5), Vec3i(2, 8, 6)),
|
||||
/*channels*/ Values(Vec3i(2, 0, 0), Vec3i(3, 4, 0), Vec3i(1, 6, 2)),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Element-wise layers
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// input --- conv --- eltwise --- output
|
||||
// `--- conv ----^ ^ ^
|
||||
// `---- ... ------' '
|
||||
// `-----------------'
|
||||
typedef TestWithParam<tuple<Vec3i, std::string, int, bool, tuple<Backend, Target> > > Eltwise;
|
||||
TEST_P(Eltwise, Accuracy)
|
||||
{
|
||||
Vec3i inSize = get<0>(GetParam());
|
||||
std::string op = get<1>(GetParam());
|
||||
int numConv = get<2>(GetParam());
|
||||
bool weighted = get<3>(GetParam());
|
||||
Backend backendId = get<0>(get<4>(GetParam()));
|
||||
Target targetId = get<1>(get<4>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD &&
|
||||
inSize == Vec3i(1, 4, 5))
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && numConv > 1)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_OPENCL &&
|
||||
op == "sum" && numConv == 1 && !weighted)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && numConv > 1)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
bool convInputShift = 1;
|
||||
int numEltwiseInputs = numConv;
|
||||
if (op == "div")
|
||||
{
|
||||
numConv = 1;
|
||||
convInputShift = 0; // first input is convolution
|
||||
}
|
||||
|
||||
Net net;
|
||||
|
||||
std::vector<int> convLayerIds(numConv);
|
||||
for (int i = 0; i < numConv; ++i)
|
||||
{
|
||||
int sz[] = {inSize[0], inSize[0], 1, 1};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
|
||||
LayerParams convParam;
|
||||
convParam.set("kernel_w", 1);
|
||||
convParam.set("kernel_h", 1);
|
||||
convParam.set("num_output", inSize[0]);
|
||||
convParam.set("bias_term", false);
|
||||
convParam.type = "Convolution";
|
||||
std::ostringstream ss;
|
||||
ss << "convLayer" << i;
|
||||
convParam.name = ss.str();
|
||||
convParam.blobs.push_back(weights);
|
||||
|
||||
convLayerIds[i] = net.addLayer(convParam.name, convParam.type, convParam);
|
||||
net.connect(0, 0, convLayerIds[i], 0);
|
||||
}
|
||||
|
||||
LayerParams eltwiseParam;
|
||||
eltwiseParam.set("operation", op);
|
||||
if (op == "sum" && weighted)
|
||||
{
|
||||
RNG& rng = cv::theRNG();
|
||||
std::vector<float> coeff(1 + numConv);
|
||||
for (int i = 0; i < coeff.size(); ++i)
|
||||
{
|
||||
coeff[i] = rng.uniform(-2.0f, 2.0f);
|
||||
}
|
||||
eltwiseParam.set("coeff", DictValue::arrayReal<float*>(&coeff[0], coeff.size()));
|
||||
}
|
||||
eltwiseParam.type = "Eltwise";
|
||||
eltwiseParam.name = "testLayer";
|
||||
int eltwiseId = net.addLayer(eltwiseParam.name, eltwiseParam.type, eltwiseParam);
|
||||
if (convInputShift == 1)
|
||||
net.connect(0, 0, eltwiseId, 0);
|
||||
for (int i = 0; i < numConv; ++i)
|
||||
{
|
||||
net.connect(convLayerIds[i], 0, eltwiseId, i + convInputShift);
|
||||
}
|
||||
if (convInputShift == 0)
|
||||
net.connect(0, 0, eltwiseId, numConv);
|
||||
for (int i = numConv; i < numEltwiseInputs; ++i)
|
||||
{
|
||||
net.connect(0, 0, eltwiseId, i + 1);
|
||||
}
|
||||
|
||||
int sz[] = {1, inSize[0], inSize[1], inSize[2]};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
if (op == "div")
|
||||
randu(input, 1.0f, 1.0f); // ensure no divisor value has absouluate value of less than 0.5
|
||||
test(input, net, backendId, targetId, /*skipCheck*/false, (op == "div") ? false : true);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, Eltwise, Combine(
|
||||
/*input size*/ Values(Vec3i(1, 4, 5), Vec3i(2, 8, 6)),
|
||||
/*operation*/ Values("prod", "sum", "div", "max", "min"),
|
||||
/*num convs*/ Values(1, 2, 3),
|
||||
/*weighted(for sum only)*/ Bool(),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Mixed backends
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef HAVE_HALIDE
|
||||
TEST(MixedBackends_Halide_Default_Halide, Accuracy)
|
||||
{
|
||||
// Just a layer that supports Halide backend.
|
||||
LayerParams lrn;
|
||||
lrn.type = "LRN";
|
||||
lrn.name = "testLRN";
|
||||
|
||||
// Some of layers that doesn't supports Halide backend yet.
|
||||
LayerParams mvn;
|
||||
mvn.type = "MVN";
|
||||
mvn.name = "testMVN";
|
||||
|
||||
// Halide layer again.
|
||||
LayerParams lrn2;
|
||||
lrn2.type = "LRN";
|
||||
lrn2.name = "testLRN2";
|
||||
|
||||
Net net;
|
||||
int lrnId = net.addLayer(lrn.name, lrn.type, lrn);
|
||||
net.connect(0, 0, lrnId, 0);
|
||||
net.addLayerToPrev(mvn.name, mvn.type, mvn);
|
||||
net.addLayerToPrev(lrn2.name, lrn2.type, lrn2);
|
||||
|
||||
int sz[] = {4, 3, 5, 6};
|
||||
Mat input(4, &sz[0], CV_32F);
|
||||
randu(input, -1.0f, 1.0f);
|
||||
net.setInput(input);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
Mat outputDefault = net.forward().clone();
|
||||
|
||||
net.setPreferableBackend(DNN_BACKEND_HALIDE);
|
||||
net.setInput(input);
|
||||
Mat outputHalide = net.forward().clone();
|
||||
normAssert(outputDefault, outputHalide);
|
||||
|
||||
net.setPreferableTarget(DNN_TARGET_OPENCL);
|
||||
net.setInput(input);
|
||||
outputHalide = net.forward().clone();
|
||||
normAssert(outputDefault, outputHalide);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_Halide_layers, dnnBackendsAndTargetsWithHalide());
|
||||
|
||||
}} // namespace
|
500
3rdparty/opencv-4.5.4/modules/dnn/test/test_ie_models.cpp
vendored
Normal file
500
3rdparty/opencv-4.5.4/modules/dnn/test/test_ie_models.cpp
vendored
Normal file
@ -0,0 +1,500 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
#include <opencv2/core/utils/filesystem.hpp>
|
||||
|
||||
|
||||
//
|
||||
// Synchronize headers include statements with src/op_inf_engine.hpp
|
||||
//
|
||||
//#define INFERENCE_ENGINE_DEPRECATED // turn off deprecation warnings from IE
|
||||
//there is no way to suppress warnings from IE only at this moment, so we are forced to suppress warnings globally
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4996) // was declared deprecated
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC visibility push(default)
|
||||
#endif
|
||||
|
||||
#include <inference_engine.hpp>
|
||||
#include <ie_icnn_network.hpp>
|
||||
#include <ie_extension.h>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static void initDLDTDataPath()
|
||||
{
|
||||
#ifndef WINRT
|
||||
static bool initialized = false;
|
||||
if (!initialized)
|
||||
{
|
||||
#if INF_ENGINE_RELEASE <= 2018050000
|
||||
const char* dldtTestDataPath = getenv("INTEL_CVSDK_DIR");
|
||||
if (dldtTestDataPath)
|
||||
cvtest::addDataSearchPath(dldtTestDataPath);
|
||||
#else
|
||||
const char* omzDataPath = getenv("OPENCV_OPEN_MODEL_ZOO_DATA_PATH");
|
||||
if (omzDataPath)
|
||||
cvtest::addDataSearchPath(omzDataPath);
|
||||
const char* dnnDataPath = getenv("OPENCV_DNN_TEST_DATA_PATH");
|
||||
if (dnnDataPath)
|
||||
cvtest::addDataSearchPath(std::string(dnnDataPath) + "/omz_intel_models");
|
||||
#endif
|
||||
initialized = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
using namespace InferenceEngine;
|
||||
|
||||
struct OpenVINOModelTestCaseInfo
|
||||
{
|
||||
const char* modelPathFP32;
|
||||
const char* modelPathFP16;
|
||||
};
|
||||
|
||||
static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestModels()
|
||||
{
|
||||
static std::map<std::string, OpenVINOModelTestCaseInfo> g_models {
|
||||
#if INF_ENGINE_RELEASE >= 2018050000 && \
|
||||
INF_ENGINE_RELEASE <= 2020999999 // don't use IRv5 models with 2020.1+
|
||||
// layout is defined by open_model_zoo/model_downloader
|
||||
// Downloaded using these parameters for Open Model Zoo downloader (2019R1):
|
||||
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
|
||||
// --name face-person-detection-retail-0002,face-person-detection-retail-0002-fp16,age-gender-recognition-retail-0013,age-gender-recognition-retail-0013-fp16,head-pose-estimation-adas-0001,head-pose-estimation-adas-0001-fp16,person-detection-retail-0002,person-detection-retail-0002-fp16,vehicle-detection-adas-0002,vehicle-detection-adas-0002-fp16
|
||||
{ "age-gender-recognition-retail-0013", {
|
||||
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013",
|
||||
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013-fp16"
|
||||
}},
|
||||
{ "face-person-detection-retail-0002", {
|
||||
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002",
|
||||
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002-fp16"
|
||||
}},
|
||||
{ "head-pose-estimation-adas-0001", {
|
||||
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001",
|
||||
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001-fp16"
|
||||
}},
|
||||
{ "person-detection-retail-0002", {
|
||||
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002",
|
||||
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002-fp16"
|
||||
}},
|
||||
{ "vehicle-detection-adas-0002", {
|
||||
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002",
|
||||
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002-fp16"
|
||||
}},
|
||||
#endif
|
||||
#if INF_ENGINE_RELEASE >= 2020010000
|
||||
// Downloaded using these parameters for Open Model Zoo downloader (2020.1):
|
||||
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
|
||||
// --name person-detection-retail-0013,age-gender-recognition-retail-0013
|
||||
{ "person-detection-retail-0013", { // IRv10
|
||||
"intel/person-detection-retail-0013/FP32/person-detection-retail-0013",
|
||||
"intel/person-detection-retail-0013/FP16/person-detection-retail-0013"
|
||||
}},
|
||||
{ "age-gender-recognition-retail-0013", {
|
||||
"intel/age-gender-recognition-retail-0013/FP16/age-gender-recognition-retail-0013",
|
||||
"intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013"
|
||||
}},
|
||||
#endif
|
||||
#if INF_ENGINE_RELEASE >= 2021020000
|
||||
// OMZ: 2020.2
|
||||
{ "face-detection-0105", {
|
||||
"intel/face-detection-0105/FP32/face-detection-0105",
|
||||
"intel/face-detection-0105/FP16/face-detection-0105"
|
||||
}},
|
||||
{ "face-detection-0106", {
|
||||
"intel/face-detection-0106/FP32/face-detection-0106",
|
||||
"intel/face-detection-0106/FP16/face-detection-0106"
|
||||
}},
|
||||
#endif
|
||||
#if INF_ENGINE_RELEASE >= 2021040000
|
||||
// OMZ: 2021.4
|
||||
{ "person-vehicle-bike-detection-2004", {
|
||||
"intel/person-vehicle-bike-detection-2004/FP32/person-vehicle-bike-detection-2004",
|
||||
"intel/person-vehicle-bike-detection-2004/FP16/person-vehicle-bike-detection-2004"
|
||||
//"intel/person-vehicle-bike-detection-2004/FP16-INT8/person-vehicle-bike-detection-2004"
|
||||
}},
|
||||
#endif
|
||||
};
|
||||
|
||||
return g_models;
|
||||
}
|
||||
|
||||
static const std::vector<std::string> getOpenVINOTestModelsList()
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
|
||||
for (const auto& it : models)
|
||||
result.push_back(it.first);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static std::string getOpenVINOModel(const std::string &modelName, bool isFP16)
|
||||
{
|
||||
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
|
||||
const auto it = models.find(modelName);
|
||||
if (it != models.end())
|
||||
{
|
||||
OpenVINOModelTestCaseInfo modelInfo = it->second;
|
||||
if (isFP16 && modelInfo.modelPathFP16)
|
||||
return std::string(modelInfo.modelPathFP16);
|
||||
else if (!isFP16 && modelInfo.modelPathFP32)
|
||||
return std::string(modelInfo.modelPathFP32);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static inline void genData(const InferenceEngine::TensorDesc& desc, Mat& m, Blob::Ptr& dataPtr)
|
||||
{
|
||||
const std::vector<size_t>& dims = desc.getDims();
|
||||
if (desc.getPrecision() == InferenceEngine::Precision::FP32)
|
||||
{
|
||||
m.create(std::vector<int>(dims.begin(), dims.end()), CV_32F);
|
||||
randu(m, -1, 1);
|
||||
dataPtr = make_shared_blob<float>(desc, (float*)m.data);
|
||||
}
|
||||
else if (desc.getPrecision() == InferenceEngine::Precision::I32)
|
||||
{
|
||||
m.create(std::vector<int>(dims.begin(), dims.end()), CV_32S);
|
||||
randu(m, -100, 100);
|
||||
dataPtr = make_shared_blob<int>(desc, (int*)m.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL() << "Unsupported precision: " << desc.getPrecision();
|
||||
}
|
||||
}
|
||||
|
||||
void runIE(Target target, const std::string& xmlPath, const std::string& binPath,
|
||||
std::map<std::string, cv::Mat>& inputsMap, std::map<std::string, cv::Mat>& outputsMap)
|
||||
{
|
||||
SCOPED_TRACE("runIE");
|
||||
|
||||
std::string device_name;
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000)
|
||||
Core ie;
|
||||
#else
|
||||
InferenceEnginePluginPtr enginePtr;
|
||||
InferencePlugin plugin;
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019030000)
|
||||
CNNNetwork net = ie.ReadNetwork(xmlPath, binPath);
|
||||
#else
|
||||
CNNNetReader reader;
|
||||
reader.ReadNetwork(xmlPath);
|
||||
reader.ReadWeights(binPath);
|
||||
|
||||
CNNNetwork net = reader.getNetwork();
|
||||
#endif
|
||||
|
||||
ExecutableNetwork netExec;
|
||||
InferRequest infRequest;
|
||||
|
||||
try
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case DNN_TARGET_CPU:
|
||||
device_name = "CPU";
|
||||
break;
|
||||
case DNN_TARGET_OPENCL:
|
||||
case DNN_TARGET_OPENCL_FP16:
|
||||
device_name = "GPU";
|
||||
break;
|
||||
case DNN_TARGET_MYRIAD:
|
||||
device_name = "MYRIAD";
|
||||
break;
|
||||
case DNN_TARGET_FPGA:
|
||||
device_name = "FPGA";
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "Unknown target");
|
||||
};
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000)
|
||||
auto dispatcher = InferenceEngine::PluginDispatcher({""});
|
||||
enginePtr = dispatcher.getPluginByDevice(device_name);
|
||||
#endif
|
||||
if (target == DNN_TARGET_CPU || target == DNN_TARGET_FPGA)
|
||||
{
|
||||
std::string suffixes[] = {"_avx2", "_sse4", ""};
|
||||
bool haveFeature[] = {
|
||||
checkHardwareSupport(CPU_AVX2),
|
||||
checkHardwareSupport(CPU_SSE4_2),
|
||||
true
|
||||
};
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (!haveFeature[i])
|
||||
continue;
|
||||
#ifdef _WIN32
|
||||
std::string libName = "cpu_extension" + suffixes[i] + ".dll";
|
||||
#elif defined(__APPLE__)
|
||||
std::string libName = "libcpu_extension" + suffixes[i] + ".dylib";
|
||||
#else
|
||||
std::string libName = "libcpu_extension" + suffixes[i] + ".so";
|
||||
#endif // _WIN32
|
||||
try
|
||||
{
|
||||
IExtensionPtr extension = make_so_pointer<IExtension>(libName);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000)
|
||||
ie.AddExtension(extension, device_name);
|
||||
#else
|
||||
enginePtr->AddExtension(extension, 0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
catch(...) {}
|
||||
}
|
||||
// Some of networks can work without a library of extra layers.
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GT(2019010000)
|
||||
netExec = ie.LoadNetwork(net, device_name);
|
||||
#else
|
||||
plugin = InferencePlugin(enginePtr);
|
||||
netExec = plugin.LoadNetwork(net, {});
|
||||
#endif
|
||||
infRequest = netExec.CreateInferRequest();
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
CV_Error(Error::StsAssert, format("Failed to initialize Inference Engine backend: %s", ex.what()));
|
||||
}
|
||||
|
||||
// Fill input blobs.
|
||||
inputsMap.clear();
|
||||
BlobMap inputBlobs;
|
||||
for (auto& it : net.getInputsInfo())
|
||||
{
|
||||
const InferenceEngine::TensorDesc& desc = it.second->getTensorDesc();
|
||||
genData(desc, inputsMap[it.first], inputBlobs[it.first]);
|
||||
if (cvtest::debugLevel > 0)
|
||||
{
|
||||
const std::vector<size_t>& dims = desc.getDims();
|
||||
std::cout << "Input: '" << it.first << "' precison=" << desc.getPrecision() << " dims=" << dims.size() << " [";
|
||||
for (auto d : dims)
|
||||
std::cout << " " << d;
|
||||
std::cout << "] ocv_mat=" << inputsMap[it.first].size << " of " << typeToString(inputsMap[it.first].type()) << std::endl;
|
||||
}
|
||||
}
|
||||
infRequest.SetInput(inputBlobs);
|
||||
|
||||
// Fill output blobs.
|
||||
outputsMap.clear();
|
||||
BlobMap outputBlobs;
|
||||
for (auto& it : net.getOutputsInfo())
|
||||
{
|
||||
const InferenceEngine::TensorDesc& desc = it.second->getTensorDesc();
|
||||
genData(desc, outputsMap[it.first], outputBlobs[it.first]);
|
||||
if (cvtest::debugLevel > 0)
|
||||
{
|
||||
const std::vector<size_t>& dims = desc.getDims();
|
||||
std::cout << "Output: '" << it.first << "' precison=" << desc.getPrecision() << " dims=" << dims.size() << " [";
|
||||
for (auto d : dims)
|
||||
std::cout << " " << d;
|
||||
std::cout << "] ocv_mat=" << outputsMap[it.first].size << " of " << typeToString(outputsMap[it.first].type()) << std::endl;
|
||||
}
|
||||
}
|
||||
infRequest.SetOutput(outputBlobs);
|
||||
|
||||
infRequest.Infer();
|
||||
}
|
||||
|
||||
void runCV(Backend backendId, Target targetId, const std::string& xmlPath, const std::string& binPath,
|
||||
const std::map<std::string, cv::Mat>& inputsMap,
|
||||
std::map<std::string, cv::Mat>& outputsMap)
|
||||
{
|
||||
SCOPED_TRACE("runOCV");
|
||||
|
||||
Net net = readNet(xmlPath, binPath);
|
||||
for (auto& it : inputsMap)
|
||||
net.setInput(it.second, it.first);
|
||||
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
|
||||
if (cvtest::debugLevel > 0)
|
||||
{
|
||||
std::cout << "OpenCV output names: " << outNames.size() << std::endl;
|
||||
for (auto name : outNames)
|
||||
std::cout << "- " << name << std::endl;
|
||||
}
|
||||
std::vector<Mat> outs;
|
||||
net.forward(outs, outNames);
|
||||
|
||||
outputsMap.clear();
|
||||
EXPECT_EQ(outs.size(), outNames.size());
|
||||
for (int i = 0; i < outs.size(); ++i)
|
||||
{
|
||||
EXPECT_TRUE(outputsMap.insert({outNames[i], outs[i]}).second);
|
||||
}
|
||||
}
|
||||
|
||||
typedef TestWithParam<tuple< tuple<Backend, Target>, std::string> > DNNTestOpenVINO;
|
||||
TEST_P(DNNTestOpenVINO, models)
|
||||
{
|
||||
initDLDTDataPath();
|
||||
|
||||
const Backend backendId = get<0>(get<0>(GetParam()));
|
||||
const Target targetId = get<1>(get<0>(GetParam()));
|
||||
std::string modelName = get<1>(GetParam());
|
||||
|
||||
ASSERT_FALSE(backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) <<
|
||||
"Inference Engine backend is required";
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GE(2021030000)
|
||||
if (targetId == DNN_TARGET_MYRIAD && (false
|
||||
|| modelName == "person-detection-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
|
||||
|| modelName == "age-gender-recognition-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
|
||||
|| modelName == "face-detection-0105" // get_element_type() must be called on a node with exactly one output
|
||||
|| modelName == "face-detection-0106" // get_element_type() must be called on a node with exactly one output
|
||||
|| modelName == "person-vehicle-bike-detection-2004" // 2021.4+: ncDeviceOpen:1013 Failed to find booted device after boot
|
||||
)
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (targetId == DNN_TARGET_OPENCL && (false
|
||||
|| modelName == "face-detection-0106" // Operation: 2278 of type ExperimentalDetectronPriorGridGenerator(op::v6) is not supported
|
||||
)
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (targetId == DNN_TARGET_OPENCL_FP16 && (false
|
||||
|| modelName == "face-detection-0106" // Operation: 2278 of type ExperimentalDetectronPriorGridGenerator(op::v6) is not supported
|
||||
)
|
||||
)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GE(2020020000)
|
||||
if (targetId == DNN_TARGET_MYRIAD && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (modelName == "person-detection-retail-0013") // IRv10
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2020040000)
|
||||
if (targetId == DNN_TARGET_MYRIAD && modelName == "person-detection-retail-0002") // IRv5, OpenVINO 2020.4 regression
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
bool isFP16 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD);
|
||||
|
||||
const std::string modelPath = getOpenVINOModel(modelName, isFP16);
|
||||
ASSERT_FALSE(modelPath.empty()) << modelName;
|
||||
|
||||
std::string xmlPath = findDataFile(modelPath + ".xml", false);
|
||||
std::string binPath = findDataFile(modelPath + ".bin", false);
|
||||
|
||||
std::map<std::string, cv::Mat> inputsMap;
|
||||
std::map<std::string, cv::Mat> ieOutputsMap, cvOutputsMap;
|
||||
// Single Myriad device cannot be shared across multiple processes.
|
||||
if (targetId == DNN_TARGET_MYRIAD)
|
||||
resetMyriadDevice();
|
||||
if (targetId == DNN_TARGET_HDDL)
|
||||
releaseHDDLPlugin();
|
||||
EXPECT_NO_THROW(runIE(targetId, xmlPath, binPath, inputsMap, ieOutputsMap)) << "runIE";
|
||||
if (targetId == DNN_TARGET_MYRIAD)
|
||||
resetMyriadDevice();
|
||||
EXPECT_NO_THROW(runCV(backendId, targetId, xmlPath, binPath, inputsMap, cvOutputsMap)) << "runCV";
|
||||
|
||||
double eps = 0;
|
||||
#if INF_ENGINE_VER_MAJOR_GE(2020010000)
|
||||
if (targetId == DNN_TARGET_CPU && checkHardwareSupport(CV_CPU_AVX_512F))
|
||||
eps = 1e-5;
|
||||
#endif
|
||||
#if INF_ENGINE_VER_MAJOR_GE(2021030000)
|
||||
if (targetId == DNN_TARGET_CPU && modelName == "face-detection-0105")
|
||||
eps = 2e-4;
|
||||
#endif
|
||||
#if INF_ENGINE_VER_MAJOR_GE(2021040000)
|
||||
if (targetId == DNN_TARGET_CPU && modelName == "person-vehicle-bike-detection-2004")
|
||||
eps = 1e-6;
|
||||
#endif
|
||||
|
||||
EXPECT_EQ(ieOutputsMap.size(), cvOutputsMap.size());
|
||||
for (auto& srcIt : ieOutputsMap)
|
||||
{
|
||||
auto dstIt = cvOutputsMap.find(srcIt.first);
|
||||
CV_Assert(dstIt != cvOutputsMap.end());
|
||||
double normInf = cvtest::norm(srcIt.second, dstIt->second, cv::NORM_INF);
|
||||
EXPECT_LE(normInf, eps) << "output=" << srcIt.first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/,
|
||||
DNNTestOpenVINO,
|
||||
Combine(dnnBackendsAndTargetsIE(),
|
||||
testing::ValuesIn(getOpenVINOTestModelsList())
|
||||
)
|
||||
);
|
||||
|
||||
typedef TestWithParam<Target> DNNTestHighLevelAPI;
|
||||
TEST_P(DNNTestHighLevelAPI, predict)
|
||||
{
|
||||
initDLDTDataPath();
|
||||
|
||||
Target target = (dnn::Target)(int)GetParam();
|
||||
bool isFP16 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD);
|
||||
const std::string modelName = "age-gender-recognition-retail-0013";
|
||||
const std::string modelPath = getOpenVINOModel(modelName, isFP16);
|
||||
ASSERT_FALSE(modelPath.empty()) << modelName;
|
||||
|
||||
std::string xmlPath = findDataFile(modelPath + ".xml");
|
||||
std::string binPath = findDataFile(modelPath + ".bin");
|
||||
|
||||
Model model(xmlPath, binPath);
|
||||
Mat frame = imread(findDataFile("dnn/googlenet_1.png"));
|
||||
std::vector<Mat> outs;
|
||||
model.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
model.setPreferableTarget(target);
|
||||
model.predict(frame, outs);
|
||||
|
||||
Net net = readNet(xmlPath, binPath);
|
||||
Mat input = blobFromImage(frame, 1.0, Size(62, 62));
|
||||
net.setInput(input);
|
||||
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
|
||||
std::vector<Mat> refs;
|
||||
net.forward(refs, outNames);
|
||||
|
||||
CV_Assert(refs.size() == outs.size());
|
||||
for (int i = 0; i < refs.size(); ++i)
|
||||
normAssert(outs[i], refs[i]);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/,
|
||||
DNNTestHighLevelAPI, testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE))
|
||||
);
|
||||
|
||||
}}
|
||||
#endif // HAVE_INF_ENGINE
|
1351
3rdparty/opencv-4.5.4/modules/dnn/test/test_int8_layers.cpp
vendored
Normal file
1351
3rdparty/opencv-4.5.4/modules/dnn/test/test_int8_layers.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2650
3rdparty/opencv-4.5.4/modules/dnn/test/test_layers.cpp
vendored
Normal file
2650
3rdparty/opencv-4.5.4/modules/dnn/test/test_layers.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
3rdparty/opencv-4.5.4/modules/dnn/test/test_main.cpp
vendored
Normal file
7
3rdparty/opencv-4.5.4/modules/dnn/test/test_main.cpp
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#if defined(HAVE_HPX)
|
||||
#include <hpx/hpx_main.hpp>
|
||||
#endif
|
||||
|
||||
CV_TEST_MAIN("", initDNNTests());
|
835
3rdparty/opencv-4.5.4/modules/dnn/test/test_misc.cpp
vendored
Normal file
835
3rdparty/opencv-4.5.4/modules/dnn/test/test_misc.cpp
vendored
Normal file
@ -0,0 +1,835 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/core/ocl.hpp>
|
||||
#include <opencv2/core/opencl/ocl_defs.hpp>
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(blobFromImage_4ch, Regression)
|
||||
{
|
||||
Mat ch[4];
|
||||
for(int i = 0; i < 4; i++)
|
||||
ch[i] = Mat::ones(10, 10, CV_8U)*i;
|
||||
|
||||
Mat img;
|
||||
merge(ch, 4, img);
|
||||
Mat blob = dnn::blobFromImage(img, 1., Size(), Scalar(), false, false);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
ch[i] = Mat(img.rows, img.cols, CV_32F, blob.ptr(0, i));
|
||||
ASSERT_DOUBLE_EQ(cvtest::norm(ch[i], cv::NORM_INF), i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(blobFromImage, allocated)
|
||||
{
|
||||
int size[] = {1, 3, 4, 5};
|
||||
Mat img(size[2], size[3], CV_32FC(size[1]));
|
||||
Mat blob(4, size, CV_32F);
|
||||
void* blobData = blob.data;
|
||||
dnn::blobFromImage(img, blob, 1.0 / 255, Size(), Scalar(), false, false);
|
||||
ASSERT_EQ(blobData, blob.data);
|
||||
}
|
||||
|
||||
TEST(imagesFromBlob, Regression)
|
||||
{
|
||||
int nbOfImages = 8;
|
||||
|
||||
std::vector<cv::Mat> inputImgs(nbOfImages);
|
||||
for (int i = 0; i < nbOfImages; i++)
|
||||
{
|
||||
inputImgs[i] = cv::Mat::ones(100, 100, CV_32FC3);
|
||||
cv::randu(inputImgs[i], cv::Scalar::all(0), cv::Scalar::all(1));
|
||||
}
|
||||
|
||||
cv::Mat blob = cv::dnn::blobFromImages(inputImgs, 1., cv::Size(), cv::Scalar(), false, false);
|
||||
std::vector<cv::Mat> outputImgs;
|
||||
cv::dnn::imagesFromBlob(blob, outputImgs);
|
||||
|
||||
for (int i = 0; i < nbOfImages; i++)
|
||||
{
|
||||
EXPECT_EQ(0, cvtest::norm(inputImgs[i], outputImgs[i], NORM_INF))
|
||||
<< "i=" << i
|
||||
<< " inputImgs[i]=" << inputImgs[i].size
|
||||
<< " outputImgs[i]=" << outputImgs[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(readNet, Regression)
|
||||
{
|
||||
Net net = readNet(findDataFile("dnn/squeezenet_v1.1.prototxt"),
|
||||
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
net = readNet(findDataFile("dnn/opencv_face_detector.caffemodel", false),
|
||||
findDataFile("dnn/opencv_face_detector.prototxt"));
|
||||
EXPECT_FALSE(net.empty());
|
||||
net = readNet(findDataFile("dnn/openface_nn4.small2.v1.t7", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
net = readNet(findDataFile("dnn/tiny-yolo-voc.cfg"),
|
||||
findDataFile("dnn/tiny-yolo-voc.weights", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
net = readNet(findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt"),
|
||||
findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false));
|
||||
EXPECT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
TEST(readNet, do_not_call_setInput) // https://github.com/opencv/opencv/issues/16618
|
||||
{
|
||||
// 1. load network
|
||||
const string proto = findDataFile("dnn/squeezenet_v1.1.prototxt");
|
||||
const string model = findDataFile("dnn/squeezenet_v1.1.caffemodel", false);
|
||||
Net net = readNetFromCaffe(proto, model);
|
||||
|
||||
// 2. mistake: no inputs are specified through .setInput()
|
||||
|
||||
// 3. try inference
|
||||
Mat res;
|
||||
EXPECT_THROW(
|
||||
{
|
||||
res = net.forward(); // no inputs after loading => should fail
|
||||
}, cv::Exception);
|
||||
EXPECT_TRUE(res.empty()) << res.size;
|
||||
}
|
||||
|
||||
TEST(Net, empty_forward_18392)
|
||||
{
|
||||
cv::dnn::Net net;
|
||||
Mat image(Size(512, 512), CV_8UC3, Scalar::all(0));
|
||||
Mat inputBlob = cv::dnn::blobFromImage(image, 1.0, Size(512, 512), Scalar(0,0,0), true, false);
|
||||
net.setInput(inputBlob);
|
||||
EXPECT_ANY_THROW(Mat output = net.forward());
|
||||
}
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
static
|
||||
void test_readNet_IE_do_not_call_setInput(Backend backendId)
|
||||
{
|
||||
const Target targetId = DNN_TARGET_CPU;
|
||||
|
||||
const std::string& model = findDataFile("dnn/layers/layer_convolution.bin");
|
||||
const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net net = readNet(model, proto);
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
|
||||
// 2. mistake: no inputs are specified through .setInput()
|
||||
|
||||
// 3. try inference
|
||||
Mat res;
|
||||
EXPECT_THROW(
|
||||
{
|
||||
res = net.forward(); // no inputs after loading => should fail
|
||||
}, cv::Exception);
|
||||
EXPECT_TRUE(res.empty()) << res.size;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNN_IE_NN_BUILDER_2019
|
||||
TEST(readNet, do_not_call_setInput_IE_NN_BUILDER_2019)
|
||||
{
|
||||
test_readNet_IE_do_not_call_setInput(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
TEST(readNet, do_not_call_setInput_IE_NGRAPH)
|
||||
{
|
||||
test_readNet_IE_do_not_call_setInput(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
}
|
||||
#endif
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
typedef testing::TestWithParam<tuple<Backend, Target> > dump;
|
||||
TEST_P(dump, Regression)
|
||||
{
|
||||
const int backend = get<0>(GetParam());
|
||||
const int target = get<1>(GetParam());
|
||||
Net net = readNet(findDataFile("dnn/squeezenet_v1.1.prototxt"),
|
||||
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
|
||||
|
||||
ASSERT_EQ(net.getLayerInputs(net.getLayerId("fire2/concat")).size(), 2);
|
||||
|
||||
int size[] = {1, 3, 227, 227};
|
||||
Mat input = cv::Mat::ones(4, size, CV_32F);
|
||||
net.setInput(input);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
EXPECT_FALSE(net.dump().empty());
|
||||
net.forward();
|
||||
EXPECT_FALSE(net.dump().empty());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, dump, dnnBackendsAndTargets());
|
||||
|
||||
class FirstCustomLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
FirstCustomLayer(const LayerParams ¶ms) : Layer(params) {}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new FirstCustomLayer(params));
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays) CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
|
||||
|
||||
std::vector<Mat> outputs;
|
||||
outputs_arr.getMatVector(outputs);
|
||||
outputs[0].setTo(1);
|
||||
}
|
||||
};
|
||||
|
||||
class SecondCustomLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
SecondCustomLayer(const LayerParams ¶ms) : Layer(params) {}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new SecondCustomLayer(params));
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays) CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
|
||||
|
||||
std::vector<Mat> outputs;
|
||||
outputs_arr.getMatVector(outputs);
|
||||
outputs[0].setTo(2);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(LayerFactory, custom_layers)
|
||||
{
|
||||
LayerParams lp;
|
||||
lp.name = "name";
|
||||
lp.type = "CustomType";
|
||||
|
||||
Mat inp(1, 1, CV_32FC1);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (i == 0) { CV_DNN_REGISTER_LAYER_CLASS(CustomType, FirstCustomLayer); }
|
||||
else if (i == 1) { CV_DNN_REGISTER_LAYER_CLASS(CustomType, SecondCustomLayer); }
|
||||
else if (i == 2) { LayerFactory::unregisterLayer("CustomType"); }
|
||||
|
||||
Net net;
|
||||
net.addLayerToPrev(lp.name, lp.type, lp);
|
||||
|
||||
net.setInput(inp);
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
Mat output = net.forward();
|
||||
|
||||
if (i == 0) { EXPECT_EQ(output.at<float>(0), 1); }
|
||||
else if (i == 1) { EXPECT_EQ(output.at<float>(0), 2); }
|
||||
else if (i == 2) { EXPECT_EQ(output.at<float>(0), 1); }
|
||||
}
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<tuple<float, Vec3f, int, tuple<Backend, Target> > > setInput;
|
||||
TEST_P(setInput, normalization)
|
||||
{
|
||||
const float kScale = get<0>(GetParam());
|
||||
const Scalar kMean = get<1>(GetParam());
|
||||
const int dtype = get<2>(GetParam());
|
||||
const int backend = get<0>(get<3>(GetParam()));
|
||||
const int target = get<1>(get<3>(GetParam()));
|
||||
const bool kSwapRB = true;
|
||||
|
||||
if(backend == DNN_BACKEND_CUDA)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA);
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16 && dtype != CV_32F)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
if (backend == DNN_BACKEND_VKCOM && dtype != CV_32F)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_VULKAN);
|
||||
|
||||
Mat inp(5, 5, CV_8UC3);
|
||||
randu(inp, 0, 255);
|
||||
Mat ref = blobFromImage(inp, kScale, Size(), kMean, kSwapRB, /*crop*/false);
|
||||
|
||||
LayerParams lp;
|
||||
Net net;
|
||||
net.addLayerToPrev("testLayer", "Identity", lp);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
Mat blob = blobFromImage(inp, 1.0, Size(), Scalar(), kSwapRB, /*crop*/false, dtype);
|
||||
ASSERT_EQ(blob.type(), dtype);
|
||||
net.setInput(blob, "", kScale, kMean);
|
||||
Mat out = net.forward();
|
||||
ASSERT_EQ(out.type(), CV_32F);
|
||||
normAssert(ref, out, "", 4e-4, 1e-3);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, setInput, Combine(
|
||||
Values(1.0f, 1.0 / 127.5),
|
||||
Values(Vec3f(), Vec3f(50, 50, 50), Vec3f(10, 50, 140)),
|
||||
Values(CV_32F, CV_8U),
|
||||
dnnBackendsAndTargets()
|
||||
));
|
||||
|
||||
class CustomLayerWithDeprecatedForward CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
CustomLayerWithDeprecatedForward(const LayerParams ¶ms) : Layer(params) {}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new CustomLayerWithDeprecatedForward(params));
|
||||
}
|
||||
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
|
||||
{
|
||||
CV_Assert_N(inputs[0]->depth() == CV_32F, outputs[0].depth() == CV_32F);
|
||||
cv::add(*inputs[0], 0.5f, outputs[0]);
|
||||
}
|
||||
};
|
||||
|
||||
class CustomLayerWithDeprecatedForwardAndFallback CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
CustomLayerWithDeprecatedForwardAndFallback(const LayerParams ¶ms) : Layer(params) {}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new CustomLayerWithDeprecatedForwardAndFallback(params));
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs, OutputArrayOfArrays outputs, OutputArrayOfArrays internals) CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
|
||||
|
||||
CV_OCL_RUN(preferableTarget == DNN_TARGET_OPENCL || preferableTarget == DNN_TARGET_OPENCL_FP16,
|
||||
forward_ocl(inputs, outputs, internals));
|
||||
|
||||
Layer::forward_fallback(inputs, outputs, internals);
|
||||
}
|
||||
|
||||
virtual void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
|
||||
{
|
||||
CV_Assert_N(inputs[0]->depth() == CV_32F, outputs[0].depth() == CV_32F);
|
||||
cv::add(*inputs[0], 0.5f, outputs[0]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
bool forward_ocl(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr)
|
||||
{
|
||||
if (inputs_arr.depth() != CV_32F)
|
||||
return false;
|
||||
|
||||
std::vector<UMat> inputs;
|
||||
std::vector<UMat> outputs;
|
||||
inputs_arr.getUMatVector(inputs);
|
||||
outputs_arr.getUMatVector(outputs);
|
||||
cv::add(inputs[0], 0.5f, outputs[0]);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef testing::TestWithParam<tuple<Backend, Target> > DeprecatedForward;
|
||||
TEST_P(DeprecatedForward, CustomLayer)
|
||||
{
|
||||
const int backend = get<0>(GetParam());
|
||||
const int target = get<1>(GetParam());
|
||||
|
||||
Mat inp(5, 5, CV_32FC1);
|
||||
randu(inp, -1.0f, 1.0f);
|
||||
inp = blobFromImage(inp);
|
||||
|
||||
CV_DNN_REGISTER_LAYER_CLASS(CustomType, CustomLayerWithDeprecatedForward);
|
||||
try
|
||||
{
|
||||
LayerParams lp;
|
||||
Net net;
|
||||
net.addLayerToPrev("testLayer", "CustomType", lp);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
normAssert(out, inp + 0.5f, "", 2e-4, 7e-4);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
throw;
|
||||
}
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
}
|
||||
|
||||
TEST_P(DeprecatedForward, CustomLayerWithFallback)
|
||||
{
|
||||
const int backend = get<0>(GetParam());
|
||||
const int target = get<1>(GetParam());
|
||||
|
||||
Mat inp(5, 5, CV_32FC1);
|
||||
randu(inp, -1.0f, 1.0f);
|
||||
inp = blobFromImage(inp);
|
||||
|
||||
CV_DNN_REGISTER_LAYER_CLASS(CustomType, CustomLayerWithDeprecatedForwardAndFallback);
|
||||
try
|
||||
{
|
||||
LayerParams lp;
|
||||
Net net;
|
||||
net.addLayerToPrev("testLayer", "CustomType", lp);
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
normAssert(out, inp + 0.5f, "", 2e-4, 7e-4);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
throw;
|
||||
}
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, DeprecatedForward, dnnBackendsAndTargets());
|
||||
|
||||
TEST(Net, forwardAndRetrieve)
|
||||
{
|
||||
std::string prototxt =
|
||||
"input: \"data\"\n"
|
||||
"layer {\n"
|
||||
" name: \"testLayer\"\n"
|
||||
" type: \"Slice\"\n"
|
||||
" bottom: \"data\"\n"
|
||||
" top: \"firstCopy\"\n"
|
||||
" top: \"secondCopy\"\n"
|
||||
" slice_param {\n"
|
||||
" axis: 0\n"
|
||||
" slice_point: 2\n"
|
||||
" }\n"
|
||||
"}";
|
||||
Net net = readNetFromCaffe(&prototxt[0], prototxt.size());
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
Mat inp(4, 5, CV_32F);
|
||||
randu(inp, -1, 1);
|
||||
net.setInput(inp);
|
||||
|
||||
std::vector<String> outNames;
|
||||
outNames.push_back("testLayer");
|
||||
std::vector<std::vector<Mat> > outBlobs;
|
||||
|
||||
net.forward(outBlobs, outNames);
|
||||
|
||||
EXPECT_EQ(outBlobs.size(), 1);
|
||||
EXPECT_EQ(outBlobs[0].size(), 2);
|
||||
normAssert(outBlobs[0][0], inp.rowRange(0, 2), "first part");
|
||||
normAssert(outBlobs[0][1], inp.rowRange(2, 4), "second part");
|
||||
}
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
static const std::chrono::milliseconds async_timeout(10000);
|
||||
|
||||
// This test runs network in synchronous mode for different inputs and then
|
||||
// runs the same model asynchronously for the same inputs.
|
||||
typedef testing::TestWithParam<tuple<int, tuple<Backend, Target> > > Async;
|
||||
TEST_P(Async, model_optimizer_pipeline_set_and_forward_single)
|
||||
{
|
||||
const int dtype = get<0>(GetParam());
|
||||
const Backend backendId = get<0>(get<1>(GetParam()));
|
||||
const Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
|
||||
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("No support for async forward");
|
||||
|
||||
const std::string& model = findDataFile("dnn/layers/layer_convolution.bin");
|
||||
const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net netSync = readNet(model, proto);
|
||||
netSync.setPreferableBackend(backendId);
|
||||
netSync.setPreferableTarget(targetId);
|
||||
|
||||
Net netAsync = readNet(model, proto);
|
||||
netAsync.setPreferableBackend(backendId);
|
||||
netAsync.setPreferableTarget(targetId);
|
||||
|
||||
// Generate inputs.
|
||||
const int numInputs = 10;
|
||||
std::vector<Mat> inputs(numInputs);
|
||||
int blobSize[] = {2, 6, 75, 113};
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
inputs[i].create(4, &blobSize[0], dtype);
|
||||
randu(inputs[i], 0, 255);
|
||||
}
|
||||
|
||||
// Run synchronously.
|
||||
std::vector<Mat> refs(numInputs);
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
netSync.setInput(inputs[i]);
|
||||
refs[i] = netSync.forward().clone();
|
||||
}
|
||||
|
||||
// Run asynchronously. To make test more robust, process inputs in the reversed order.
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
netAsync.setInput(inputs[i]);
|
||||
|
||||
AsyncArray out = netAsync.forwardAsync();
|
||||
ASSERT_TRUE(out.valid());
|
||||
Mat result;
|
||||
EXPECT_TRUE(out.get(result, async_timeout));
|
||||
normAssert(refs[i], result, format("Index: %d", i).c_str(), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Async, model_optimizer_pipeline_set_and_forward_all)
|
||||
{
|
||||
const int dtype = get<0>(GetParam());
|
||||
const Backend backendId = get<0>(get<1>(GetParam()));
|
||||
const Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
|
||||
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("No support for async forward");
|
||||
|
||||
const std::string& model = findDataFile("dnn/layers/layer_convolution.bin");
|
||||
const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net netSync = readNet(model, proto);
|
||||
netSync.setPreferableBackend(backendId);
|
||||
netSync.setPreferableTarget(targetId);
|
||||
|
||||
Net netAsync = readNet(model, proto);
|
||||
netAsync.setPreferableBackend(backendId);
|
||||
netAsync.setPreferableTarget(targetId);
|
||||
|
||||
// Generate inputs.
|
||||
const int numInputs = 10;
|
||||
std::vector<Mat> inputs(numInputs);
|
||||
int blobSize[] = {2, 6, 75, 113};
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
inputs[i].create(4, &blobSize[0], dtype);
|
||||
randu(inputs[i], 0, 255);
|
||||
}
|
||||
|
||||
// Run synchronously.
|
||||
std::vector<Mat> refs(numInputs);
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
netSync.setInput(inputs[i]);
|
||||
refs[i] = netSync.forward().clone();
|
||||
}
|
||||
|
||||
// Run asynchronously. To make test more robust, process inputs in the reversed order.
|
||||
std::vector<AsyncArray> outs(numInputs);
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
netAsync.setInput(inputs[i]);
|
||||
outs[i] = netAsync.forwardAsync();
|
||||
}
|
||||
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
ASSERT_TRUE(outs[i].valid());
|
||||
Mat result;
|
||||
EXPECT_TRUE(outs[i].get(result, async_timeout));
|
||||
normAssert(refs[i], result, format("Index: %d", i).c_str(), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Async, create_layer_pipeline_set_and_forward_all)
|
||||
{
|
||||
const int dtype = get<0>(GetParam());
|
||||
const Backend backendId = get<0>(get<1>(GetParam()));
|
||||
const Target targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("No support for async forward");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net netSync;
|
||||
Net netAsync;
|
||||
{
|
||||
int inChannels = 4;
|
||||
int outChannels = 12;
|
||||
int group = 3;
|
||||
Size inSize(113, 75);
|
||||
Size kernel(4, 5);
|
||||
Size stride(2, 3);
|
||||
Size pad(0, 1);
|
||||
Size dilation(1, 1);
|
||||
bool hasBias = true;
|
||||
|
||||
int sz[] = {outChannels, inChannels / group, kernel.height, kernel.width};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("kernel_w", kernel.width);
|
||||
lp.set("kernel_h", kernel.height);
|
||||
lp.set("pad_w", pad.width);
|
||||
lp.set("pad_h", pad.height);
|
||||
lp.set("stride_w", stride.width);
|
||||
lp.set("stride_h", stride.height);
|
||||
lp.set("dilation_w", dilation.width);
|
||||
lp.set("dilation_h", dilation.height);
|
||||
lp.set("num_output", outChannels);
|
||||
lp.set("group", group);
|
||||
lp.set("bias_term", hasBias);
|
||||
lp.type = "Convolution";
|
||||
lp.name = "testLayer";
|
||||
lp.blobs.push_back(weights);
|
||||
if (hasBias)
|
||||
{
|
||||
Mat bias(1, outChannels, CV_32F);
|
||||
randu(bias, -1.0f, 1.0f);
|
||||
lp.blobs.push_back(bias);
|
||||
}
|
||||
int inpSz[] = {1, inChannels, inSize.height, inSize.width};
|
||||
Mat input(4, &inpSz[0], CV_32F);
|
||||
|
||||
netSync.addLayerToPrev(lp.name, lp.type, lp);
|
||||
|
||||
netAsync.addLayerToPrev(lp.name, lp.type, lp);
|
||||
}
|
||||
|
||||
netSync.setPreferableBackend(backendId);
|
||||
netSync.setPreferableTarget(targetId);
|
||||
|
||||
netAsync.setPreferableBackend(backendId);
|
||||
netAsync.setPreferableTarget(targetId);
|
||||
|
||||
// Generate inputs.
|
||||
const int numInputs = 10;
|
||||
std::vector<Mat> inputs(numInputs);
|
||||
int blobSize[] = {1, 4, 75, 113};
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
inputs[i].create(4, &blobSize[0], dtype);
|
||||
randu(inputs[i], 0, 255);
|
||||
}
|
||||
|
||||
// Run synchronously.
|
||||
std::vector<Mat> refs(numInputs);
|
||||
for (int i = 0; i < numInputs; ++i)
|
||||
{
|
||||
netSync.setInput(inputs[i]);
|
||||
refs[i] = netSync.forward().clone();
|
||||
}
|
||||
|
||||
// Run asynchronously. To make test more robust, process inputs in the reversed order.
|
||||
std::vector<AsyncArray> outs(numInputs);
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
netAsync.setInput(inputs[i]);
|
||||
outs[i] = netAsync.forwardAsync();
|
||||
}
|
||||
|
||||
for (int i = numInputs - 1; i >= 0; --i)
|
||||
{
|
||||
ASSERT_TRUE(outs[i].valid());
|
||||
Mat result;
|
||||
EXPECT_TRUE(outs[i].get(result, async_timeout));
|
||||
normAssert(refs[i], result, format("Index: %d", i).c_str(), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Async, Combine(
|
||||
Values(CV_32F, CV_8U),
|
||||
dnnBackendsAndTargetsIE()
|
||||
));
|
||||
|
||||
typedef testing::TestWithParam<tuple<Backend, Target> > Test_Model_Optimizer;
|
||||
TEST_P(Test_Model_Optimizer, forward_two_nets)
|
||||
{
|
||||
const Backend backendId = get<0>(GetParam());
|
||||
const Target targetId = get<1>(GetParam());
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
|
||||
const std::string& model = findDataFile("dnn/layers/layer_convolution.bin");
|
||||
const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net net0 = readNet(model, proto);
|
||||
net0.setPreferableTarget(targetId);
|
||||
|
||||
Net net1 = readNet(model, proto);
|
||||
net1.setPreferableTarget(targetId);
|
||||
|
||||
// Generate inputs.
|
||||
int blobSize[] = {2, 6, 75, 113};
|
||||
Mat input(4, &blobSize[0], CV_32F);
|
||||
randu(input, 0, 255);
|
||||
|
||||
net0.setInput(input);
|
||||
Mat ref0 = net0.forward().clone();
|
||||
|
||||
net1.setInput(input);
|
||||
Mat ref1 = net1.forward();
|
||||
|
||||
net0.setInput(input);
|
||||
Mat ref2 = net0.forward();
|
||||
|
||||
normAssert(ref0, ref2, 0, 0);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model_Optimizer, readFromBuffer)
|
||||
{
|
||||
const Backend backendId = get<0>(GetParam());
|
||||
const Target targetId = get<1>(GetParam());
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
|
||||
if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("No support for async forward");
|
||||
|
||||
const std::string& weightsFile = findDataFile("dnn/layers/layer_convolution.bin");
|
||||
const std::string& modelFile = findDataFile("dnn/layers/layer_convolution.xml");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net net1 = readNetFromModelOptimizer(modelFile, weightsFile);
|
||||
net1.setPreferableBackend(backendId);
|
||||
net1.setPreferableTarget(targetId);
|
||||
|
||||
|
||||
std::vector<char> modelConfig;
|
||||
readFileContent(modelFile, modelConfig);
|
||||
std::vector<char> weights;
|
||||
readFileContent(weightsFile, weights);
|
||||
|
||||
Net net2 = readNetFromModelOptimizer(
|
||||
(const uchar*)modelConfig.data(), modelConfig.size(),
|
||||
(const uchar*)weights.data(), weights.size()
|
||||
);
|
||||
net2.setPreferableBackend(backendId);
|
||||
net2.setPreferableTarget(targetId);
|
||||
|
||||
int blobSize[] = {2, 6, 75, 113};
|
||||
Mat input(4, &blobSize[0], CV_32F);
|
||||
randu(input, 0, 255);
|
||||
|
||||
Mat ref, actual;
|
||||
{
|
||||
net1.setInput(input);
|
||||
ref = net1.forward();
|
||||
}
|
||||
{
|
||||
net2.setInput(input);
|
||||
actual = net2.forward();
|
||||
}
|
||||
|
||||
normAssert(ref, actual, "", 0, 0);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model_Optimizer, flexible_inputs)
|
||||
{
|
||||
const Backend backendId = get<0>(GetParam());
|
||||
const Target targetId = get<1>(GetParam());
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && targetId == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
|
||||
const std::string& model = findDataFile("dnn/layers/layer_convolution.bin");
|
||||
const std::string& proto = findDataFile("dnn/layers/layer_convolution.xml");
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API);
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
setInferenceEngineBackendType(CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
|
||||
else
|
||||
FAIL() << "Unknown backendId";
|
||||
|
||||
Net net0 = readNet(model, proto);
|
||||
net0.setPreferableTarget(targetId);
|
||||
|
||||
Net net1 = readNet(model, proto);
|
||||
net1.setPreferableTarget(targetId);
|
||||
|
||||
// Generate inputs.
|
||||
int blobSize0[] = {2, 6, 75, 113};
|
||||
Mat input0(4, &blobSize0[0], CV_32F);
|
||||
randu(input0, 0, 255);
|
||||
|
||||
net0.setInput(input0);
|
||||
Mat ref = net0.forward().clone();
|
||||
|
||||
int blobSize1[] = {1, 6, 10, 9};
|
||||
Mat input1(4, &blobSize1[0], CV_32F);
|
||||
randu(input1, 0, 255);
|
||||
|
||||
net1.setInput(input1);
|
||||
Mat out = net1.forward();
|
||||
EXPECT_NE(out.size, ref.size);
|
||||
|
||||
net1.setInput(input0);
|
||||
out = net1.forward();
|
||||
normAssert(ref, out, 0, 0);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Model_Optimizer,
|
||||
dnnBackendsAndTargetsIE()
|
||||
);
|
||||
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
}} // namespace
|
701
3rdparty/opencv-4.5.4/modules/dnn/test/test_model.cpp
vendored
Normal file
701
3rdparty/opencv-4.5.4/modules/dnn/test/test_model.cpp
vendored
Normal file
@ -0,0 +1,701 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include "npy_blob.hpp"
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
template<typename TString>
|
||||
static std::string _tf(TString filename, bool required = true)
|
||||
{
|
||||
String rootFolder = "dnn/";
|
||||
return findDataFile(rootFolder + filename, required);
|
||||
}
|
||||
|
||||
|
||||
class Test_Model : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
void testDetectModel(const std::string& weights, const std::string& cfg,
|
||||
const std::string& imgPath, const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refConfidences,
|
||||
const std::vector<Rect2d>& refBoxes,
|
||||
double scoreDiff, double iouDiff,
|
||||
double confThreshold = 0.24, double nmsThreshold = 0.0,
|
||||
const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false,
|
||||
bool nmsAcrossClasses = false)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat frame = imread(imgPath);
|
||||
DetectionModel model(weights, cfg);
|
||||
|
||||
model.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
model.setPreferableBackend(backend);
|
||||
model.setPreferableTarget(target);
|
||||
|
||||
model.setNmsAcrossClasses(nmsAcrossClasses);
|
||||
|
||||
std::vector<int> classIds;
|
||||
std::vector<float> confidences;
|
||||
std::vector<Rect> boxes;
|
||||
|
||||
model.detect(frame, classIds, confidences, boxes, confThreshold, nmsThreshold);
|
||||
|
||||
std::vector<Rect2d> boxesDouble(boxes.size());
|
||||
for (int i = 0; i < boxes.size(); i++) {
|
||||
boxesDouble[i] = boxes[i];
|
||||
}
|
||||
normAssertDetections(refClassIds, refConfidences, refBoxes, classIds,
|
||||
confidences, boxesDouble, "",
|
||||
confThreshold, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
void testClassifyModel(const std::string& weights, const std::string& cfg,
|
||||
const std::string& imgPath, std::pair<int, float> ref, float norm,
|
||||
const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat frame = imread(imgPath);
|
||||
ClassificationModel model(weights, cfg);
|
||||
model.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
std::pair<int, float> prediction = model.classify(frame);
|
||||
EXPECT_EQ(prediction.first, ref.first);
|
||||
ASSERT_NEAR(prediction.second, ref.second, norm);
|
||||
}
|
||||
|
||||
void testKeypointsModel(const std::string& weights, const std::string& cfg,
|
||||
const Mat& frame, const Mat& exp, float norm,
|
||||
const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
std::vector<Point2f> points;
|
||||
|
||||
KeypointsModel model(weights, cfg);
|
||||
model.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
model.setPreferableBackend(backend);
|
||||
model.setPreferableTarget(target);
|
||||
|
||||
points = model.estimate(frame, 0.5);
|
||||
|
||||
Mat out = Mat(points).reshape(1);
|
||||
normAssert(exp, out, "", norm, norm);
|
||||
}
|
||||
|
||||
void testSegmentationModel(const std::string& weights_file, const std::string& config_file,
|
||||
const std::string& inImgPath, const std::string& outImgPath,
|
||||
float norm, const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat frame = imread(inImgPath);
|
||||
Mat mask;
|
||||
Mat exp = imread(outImgPath, 0);
|
||||
|
||||
SegmentationModel model(weights_file, config_file);
|
||||
model.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
model.segment(frame, mask);
|
||||
normAssert(mask, exp, "", norm, norm);
|
||||
}
|
||||
|
||||
void testTextRecognitionModel(const std::string& weights, const std::string& cfg,
|
||||
const std::string& imgPath, const std::string& seq,
|
||||
const std::string& decodeType, const std::vector<std::string>& vocabulary,
|
||||
const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat frame = imread(imgPath, IMREAD_GRAYSCALE);
|
||||
|
||||
TextRecognitionModel model(weights, cfg);
|
||||
model.setDecodeType(decodeType)
|
||||
.setVocabulary(vocabulary)
|
||||
.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
model.setPreferableBackend(backend);
|
||||
model.setPreferableTarget(target);
|
||||
|
||||
std::string result = model.recognize(frame);
|
||||
EXPECT_EQ(result, seq) << "Full frame: " << imgPath;
|
||||
|
||||
std::vector<Rect> rois;
|
||||
rois.push_back(Rect(0, 0, frame.cols, frame.rows));
|
||||
rois.push_back(Rect(0, 0, frame.cols, frame.rows)); // twice
|
||||
std::vector<std::string> results;
|
||||
model.recognize(frame, rois, results);
|
||||
EXPECT_EQ((size_t)2u, results.size()) << "ROI: " << imgPath;
|
||||
EXPECT_EQ(results[0], seq) << "ROI[0]: " << imgPath;
|
||||
EXPECT_EQ(results[1], seq) << "ROI[1]: " << imgPath;
|
||||
}
|
||||
|
||||
void testTextDetectionModelByDB(const std::string& weights, const std::string& cfg,
|
||||
const std::string& imgPath, const std::vector<std::vector<Point>>& gt,
|
||||
float binThresh, float polyThresh,
|
||||
uint maxCandidates, double unclipRatio,
|
||||
const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat frame = imread(imgPath);
|
||||
|
||||
TextDetectionModel_DB model(weights, cfg);
|
||||
model.setBinaryThreshold(binThresh)
|
||||
.setPolygonThreshold(polyThresh)
|
||||
.setUnclipRatio(unclipRatio)
|
||||
.setMaxCandidates(maxCandidates)
|
||||
.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
model.setPreferableBackend(backend);
|
||||
model.setPreferableTarget(target);
|
||||
|
||||
// 1. Check common TextDetectionModel API through RotatedRect
|
||||
std::vector<cv::RotatedRect> results;
|
||||
model.detectTextRectangles(frame, results);
|
||||
|
||||
EXPECT_GT(results.size(), (size_t)0);
|
||||
|
||||
std::vector< std::vector<Point> > contours;
|
||||
for (size_t i = 0; i < results.size(); i++)
|
||||
{
|
||||
const RotatedRect& box = results[i];
|
||||
Mat contour;
|
||||
boxPoints(box, contour);
|
||||
std::vector<Point> contour2i(4);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
contour2i[i].x = cvRound(contour.at<float>(i, 0));
|
||||
contour2i[i].y = cvRound(contour.at<float>(i, 1));
|
||||
}
|
||||
contours.push_back(contour2i);
|
||||
}
|
||||
#if 0 // test debug
|
||||
Mat result = frame.clone();
|
||||
drawContours(result, contours, -1, Scalar(0, 0, 255), 1);
|
||||
imshow("result", result); // imwrite("result.png", result);
|
||||
waitKey(0);
|
||||
#endif
|
||||
normAssertTextDetections(gt, contours, "", 0.05f);
|
||||
|
||||
// 2. Check quadrangle-based API
|
||||
// std::vector< std::vector<Point> > contours;
|
||||
model.detect(frame, contours);
|
||||
|
||||
#if 0 // test debug
|
||||
Mat result = frame.clone();
|
||||
drawContours(result, contours, -1, Scalar(0, 0, 255), 1);
|
||||
imshow("result_contours", result); // imwrite("result_contours.png", result);
|
||||
waitKey(0);
|
||||
#endif
|
||||
normAssertTextDetections(gt, contours, "", 0.05f);
|
||||
}
|
||||
|
||||
void testTextDetectionModelByEAST(
|
||||
const std::string& weights, const std::string& cfg,
|
||||
const std::string& imgPath, const std::vector<RotatedRect>& gt,
|
||||
float confThresh, float nmsThresh,
|
||||
const Size& size = {-1, -1}, Scalar mean = Scalar(),
|
||||
double scale = 1.0, bool swapRB = false, bool crop = false,
|
||||
double eps_center = 5/*pixels*/, double eps_size = 5/*pixels*/, double eps_angle = 1
|
||||
)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat frame = imread(imgPath);
|
||||
|
||||
TextDetectionModel_EAST model(weights, cfg);
|
||||
model.setConfidenceThreshold(confThresh)
|
||||
.setNMSThreshold(nmsThresh)
|
||||
.setInputSize(size).setInputMean(mean).setInputScale(scale)
|
||||
.setInputSwapRB(swapRB).setInputCrop(crop);
|
||||
|
||||
model.setPreferableBackend(backend);
|
||||
model.setPreferableTarget(target);
|
||||
|
||||
std::vector<cv::RotatedRect> results;
|
||||
model.detectTextRectangles(frame, results);
|
||||
|
||||
EXPECT_EQ(results.size(), (size_t)1);
|
||||
for (size_t i = 0; i < results.size(); i++)
|
||||
{
|
||||
const RotatedRect& box = results[i];
|
||||
#if 0 // test debug
|
||||
Mat contour;
|
||||
boxPoints(box, contour);
|
||||
std::vector<Point> contour2i(4);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
contour2i[i].x = cvRound(contour.at<float>(i, 0));
|
||||
contour2i[i].y = cvRound(contour.at<float>(i, 1));
|
||||
}
|
||||
std::vector< std::vector<Point> > contours;
|
||||
contours.push_back(contour2i);
|
||||
|
||||
Mat result = frame.clone();
|
||||
drawContours(result, contours, -1, Scalar(0, 0, 255), 1);
|
||||
imshow("result", result); //imwrite("result.png", result);
|
||||
waitKey(0);
|
||||
#endif
|
||||
const RotatedRect& gtBox = gt[i];
|
||||
EXPECT_NEAR(box.center.x, gtBox.center.x, eps_center);
|
||||
EXPECT_NEAR(box.center.y, gtBox.center.y, eps_center);
|
||||
EXPECT_NEAR(box.size.width, gtBox.size.width, eps_size);
|
||||
EXPECT_NEAR(box.size.height, gtBox.size.height, eps_size);
|
||||
EXPECT_NEAR(box.angle, gtBox.angle, eps_angle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(Test_Model, Classify)
|
||||
{
|
||||
std::pair<int, float> ref(652, 0.641789);
|
||||
|
||||
std::string img_path = _tf("grace_hopper_227.png");
|
||||
std::string config_file = _tf("bvlc_alexnet.prototxt");
|
||||
std::string weights_file = _tf("bvlc_alexnet.caffemodel", false);
|
||||
|
||||
Size size{227, 227};
|
||||
float norm = 1e-4;
|
||||
|
||||
testClassifyModel(weights_file, config_file, img_path, ref, norm, size);
|
||||
}
|
||||
|
||||
|
||||
TEST_P(Test_Model, DetectRegion)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_1GB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
|
||||
std::vector<int> refClassIds = {6, 1, 11};
|
||||
std::vector<float> refConfidences = {0.750469f, 0.780879f, 0.901615f};
|
||||
std::vector<Rect2d> refBoxes = {Rect2d(240, 53, 135, 72),
|
||||
Rect2d(112, 109, 192, 200),
|
||||
Rect2d(58, 141, 117, 249)};
|
||||
|
||||
std::string img_path = _tf("dog416.png");
|
||||
std::string weights_file = _tf("yolo-voc.weights", false);
|
||||
std::string config_file = _tf("yolo-voc.cfg");
|
||||
|
||||
double scale = 1.0 / 255.0;
|
||||
Size size{416, 416};
|
||||
bool swapRB = true;
|
||||
|
||||
double confThreshold = 0.24;
|
||||
double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.397 : 0.4;
|
||||
double scoreDiff = 8e-5, iouDiff = 1e-5;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 1e-2;
|
||||
iouDiff = 1.6e-2;
|
||||
}
|
||||
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences,
|
||||
refBoxes, scoreDiff, iouDiff, confThreshold, nmsThreshold, size,
|
||||
Scalar(), scale, swapRB);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, DetectRegionWithNmsAcrossClasses)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_1GB);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
|
||||
#endif
|
||||
|
||||
std::vector<int> refClassIds = { 6, 11 };
|
||||
std::vector<float> refConfidences = { 0.750469f, 0.901615f };
|
||||
std::vector<Rect2d> refBoxes = { Rect2d(240, 53, 135, 72),
|
||||
Rect2d(58, 141, 117, 249) };
|
||||
|
||||
std::string img_path = _tf("dog416.png");
|
||||
std::string weights_file = _tf("yolo-voc.weights", false);
|
||||
std::string config_file = _tf("yolo-voc.cfg");
|
||||
|
||||
double scale = 1.0 / 255.0;
|
||||
Size size{ 416, 416 };
|
||||
bool swapRB = true;
|
||||
bool crop = false;
|
||||
bool nmsAcrossClasses = true;
|
||||
|
||||
double confThreshold = 0.24;
|
||||
double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.15: 0.15;
|
||||
double scoreDiff = 8e-5, iouDiff = 1e-5;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 1e-2;
|
||||
iouDiff = 1.6e-2;
|
||||
}
|
||||
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences,
|
||||
refBoxes, scoreDiff, iouDiff, confThreshold, nmsThreshold, size,
|
||||
Scalar(), scale, swapRB, crop,
|
||||
nmsAcrossClasses);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, DetectionOutput)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
|
||||
#endif
|
||||
|
||||
std::vector<int> refClassIds = {7, 12};
|
||||
std::vector<float> refConfidences = {0.991359f, 0.94786f};
|
||||
std::vector<Rect2d> refBoxes = {Rect2d(491, 81, 212, 98),
|
||||
Rect2d(132, 223, 207, 344)};
|
||||
|
||||
std::string img_path = _tf("dog416.png");
|
||||
std::string weights_file = _tf("resnet50_rfcn_final.caffemodel", false);
|
||||
std::string config_file = _tf("rfcn_pascal_voc_resnet50.prototxt");
|
||||
|
||||
Scalar mean = Scalar(102.9801, 115.9465, 122.7717);
|
||||
Size size{800, 600};
|
||||
|
||||
double scoreDiff = default_l1, iouDiff = 1e-5;
|
||||
float confThreshold = 0.8;
|
||||
double nmsThreshold = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV)
|
||||
scoreDiff = 4e-3;
|
||||
else
|
||||
scoreDiff = 2e-2;
|
||||
iouDiff = 1.8e-1;
|
||||
}
|
||||
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences, refBoxes,
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean);
|
||||
}
|
||||
|
||||
|
||||
TEST_P(Test_Model, DetectionMobilenetSSD)
|
||||
{
|
||||
Mat ref = blobFromNPY(_tf("mobilenet_ssd_caffe_out.npy"));
|
||||
ref = ref.reshape(1, ref.size[2]);
|
||||
|
||||
std::string img_path = _tf("street.png");
|
||||
Mat frame = imread(img_path);
|
||||
int frameWidth = frame.cols;
|
||||
int frameHeight = frame.rows;
|
||||
|
||||
std::vector<int> refClassIds;
|
||||
std::vector<float> refConfidences;
|
||||
std::vector<Rect2d> refBoxes;
|
||||
for (int i = 0; i < ref.rows; i++)
|
||||
{
|
||||
refClassIds.emplace_back(ref.at<float>(i, 1));
|
||||
refConfidences.emplace_back(ref.at<float>(i, 2));
|
||||
int left = ref.at<float>(i, 3) * frameWidth;
|
||||
int top = ref.at<float>(i, 4) * frameHeight;
|
||||
int right = ref.at<float>(i, 5) * frameWidth;
|
||||
int bottom = ref.at<float>(i, 6) * frameHeight;
|
||||
int width = right - left + 1;
|
||||
int height = bottom - top + 1;
|
||||
refBoxes.emplace_back(left, top, width, height);
|
||||
}
|
||||
|
||||
std::string weights_file = _tf("MobileNetSSD_deploy.caffemodel", false);
|
||||
std::string config_file = _tf("MobileNetSSD_deploy.prototxt");
|
||||
|
||||
Scalar mean = Scalar(127.5, 127.5, 127.5);
|
||||
double scale = 1.0 / 127.5;
|
||||
Size size{300, 300};
|
||||
|
||||
double scoreDiff = 1e-5, iouDiff = 1e-5;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
scoreDiff = 1.7e-2;
|
||||
iouDiff = 6.91e-2;
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
scoreDiff = 1.7e-2;
|
||||
if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
iouDiff = 6.91e-2;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 0.002;
|
||||
iouDiff = 1e-2;
|
||||
}
|
||||
float confThreshold = FLT_MIN;
|
||||
double nmsThreshold = 0.0;
|
||||
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences, refBoxes,
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean, scale);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, Keypoints_pose)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
Mat inp = imread(_tf("pose.png"));
|
||||
std::string weights = _tf("onnx/models/lightweight_pose_estimation_201912.onnx", false);
|
||||
float kpdata[] = {
|
||||
237.65625f, 78.25f, 237.65625f, 136.9375f,
|
||||
190.125f, 136.9375f, 142.59375f, 195.625f, 79.21875f, 176.0625f, 285.1875f, 117.375f,
|
||||
348.5625f, 195.625f, 396.09375f, 176.0625f, 205.96875f, 313.0f, 205.96875f, 430.375f,
|
||||
205.96875f, 528.1875f, 269.34375f, 293.4375f, 253.5f, 430.375f, 237.65625f, 528.1875f,
|
||||
221.8125f, 58.6875f, 253.5f, 58.6875f, 205.96875f, 78.25f, 253.5f, 58.6875f
|
||||
};
|
||||
Mat exp(18, 2, CV_32FC1, kpdata);
|
||||
|
||||
Size size{256, 256};
|
||||
float norm = 1e-4;
|
||||
double scale = 1.0/255;
|
||||
Scalar mean = Scalar(128, 128, 128);
|
||||
bool swapRB = false;
|
||||
|
||||
// Ref. Range: [58.6875, 508.625]
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
norm = 20; // l1 = 1.5, lInf = 20
|
||||
|
||||
testKeypointsModel(weights, "", inp, exp, norm, size, mean, scale, swapRB);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, Keypoints_face)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
Mat inp = imread(_tf("gray_face.png"), 0);
|
||||
std::string weights = _tf("onnx/models/facial_keypoints.onnx", false);
|
||||
Mat exp = blobFromNPY(_tf("facial_keypoints_exp.npy"));
|
||||
|
||||
Size size{224, 224};
|
||||
double scale = 1.0/255;
|
||||
Scalar mean = Scalar();
|
||||
bool swapRB = false;
|
||||
|
||||
// Ref. Range: [-1.1784188, 1.7758257]
|
||||
float norm = 1e-4;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
norm = 5e-3;
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
// Myriad2: l1 = 0.0004, lInf = 0.002
|
||||
// MyriadX: l1 = 0.003, lInf = 0.009
|
||||
norm = 0.009;
|
||||
}
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
norm = 0.004; // l1 = 0.0006, lInf = 0.004
|
||||
|
||||
testKeypointsModel(weights, "", inp, exp, norm, size, mean, scale, swapRB);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, Detection_normalized)
|
||||
{
|
||||
std::string img_path = _tf("grace_hopper_227.png");
|
||||
std::vector<int> refClassIds = {15};
|
||||
std::vector<float> refConfidences = {0.999222f};
|
||||
std::vector<Rect2d> refBoxes = {Rect2d(0, 4, 227, 222)};
|
||||
|
||||
std::string weights_file = _tf("MobileNetSSD_deploy.caffemodel", false);
|
||||
std::string config_file = _tf("MobileNetSSD_deploy.prototxt");
|
||||
|
||||
Scalar mean = Scalar(127.5, 127.5, 127.5);
|
||||
double scale = 1.0 / 127.5;
|
||||
Size size{300, 300};
|
||||
|
||||
double scoreDiff = 1e-5, iouDiff = 1e-5;
|
||||
float confThreshold = FLT_MIN;
|
||||
double nmsThreshold = 0.0;
|
||||
if (target == DNN_TARGET_CUDA)
|
||||
{
|
||||
scoreDiff = 3e-4;
|
||||
iouDiff = 0.018;
|
||||
}
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
scoreDiff = 5e-3;
|
||||
iouDiff = 0.09;
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
iouDiff = 0.095f;
|
||||
}
|
||||
#endif
|
||||
testDetectModel(weights_file, config_file, img_path, refClassIds, refConfidences, refBoxes,
|
||||
scoreDiff, iouDiff, confThreshold, nmsThreshold, size, mean, scale);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, Segmentation)
|
||||
{
|
||||
std::string inp = _tf("dog416.png");
|
||||
std::string weights_file = _tf("fcn8s-heavy-pascal.prototxt");
|
||||
std::string config_file = _tf("fcn8s-heavy-pascal.caffemodel", false);
|
||||
std::string exp = _tf("segmentation_exp.png");
|
||||
|
||||
Size size{128, 128};
|
||||
float norm = 0;
|
||||
double scale = 1.0;
|
||||
Scalar mean = Scalar();
|
||||
bool swapRB = false;
|
||||
|
||||
testSegmentationModel(weights_file, config_file, inp, exp, norm, size, mean, scale, swapRB);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, TextRecognition)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
|
||||
std::string imgPath = _tf("text_rec_test.png");
|
||||
std::string weightPath = _tf("onnx/models/crnn.onnx", false);
|
||||
std::string seq = "welcome";
|
||||
|
||||
Size size{100, 32};
|
||||
double scale = 1.0 / 127.5;
|
||||
Scalar mean = Scalar(127.5);
|
||||
std::string decodeType = "CTC-greedy";
|
||||
std::vector<std::string> vocabulary = {"0","1","2","3","4","5","6","7","8","9",
|
||||
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
|
||||
|
||||
testTextRecognitionModel(weightPath, "", imgPath, seq, decodeType, vocabulary, size, mean, scale);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, TextRecognitionWithCTCPrefixBeamSearch)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
|
||||
std::string imgPath = _tf("text_rec_test.png");
|
||||
std::string weightPath = _tf("onnx/models/crnn.onnx", false);
|
||||
std::string seq = "welcome";
|
||||
|
||||
Size size{100, 32};
|
||||
double scale = 1.0 / 127.5;
|
||||
Scalar mean = Scalar(127.5);
|
||||
std::string decodeType = "CTC-prefix-beam-search";
|
||||
std::vector<std::string> vocabulary = {"0","1","2","3","4","5","6","7","8","9",
|
||||
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
|
||||
|
||||
testTextRecognitionModel(weightPath, "", imgPath, seq, decodeType, vocabulary, size, mean, scale);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, TextDetectionByDB)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
|
||||
std::string imgPath = _tf("text_det_test1.png");
|
||||
std::string weightPath = _tf("onnx/models/DB_TD500_resnet50.onnx", false);
|
||||
|
||||
// GroundTruth
|
||||
std::vector<std::vector<Point>> gt = {
|
||||
{ Point(142, 193), Point(136, 164), Point(213, 150), Point(219, 178) },
|
||||
{ Point(136, 165), Point(122, 114), Point(319, 71), Point(330, 122) }
|
||||
};
|
||||
|
||||
Size size{736, 736};
|
||||
double scale = 1.0 / 255.0;
|
||||
Scalar mean = Scalar(122.67891434, 116.66876762, 104.00698793);
|
||||
|
||||
float binThresh = 0.3;
|
||||
float polyThresh = 0.5;
|
||||
uint maxCandidates = 200;
|
||||
double unclipRatio = 2.0;
|
||||
|
||||
testTextDetectionModelByDB(weightPath, "", imgPath, gt, binThresh, polyThresh, maxCandidates, unclipRatio, size, mean, scale);
|
||||
}
|
||||
|
||||
TEST_P(Test_Model, TextDetectionByEAST)
|
||||
{
|
||||
std::string imgPath = _tf("text_det_test2.jpg");
|
||||
std::string weightPath = _tf("frozen_east_text_detection.pb", false);
|
||||
|
||||
// GroundTruth
|
||||
std::vector<RotatedRect> gt = {
|
||||
RotatedRect(Point2f(657.55f, 409.5f), Size2f(316.84f, 62.45f), -4.79)
|
||||
};
|
||||
|
||||
// Model parameters
|
||||
Size size{320, 320};
|
||||
double scale = 1.0;
|
||||
Scalar mean = Scalar(123.68, 116.78, 103.94);
|
||||
bool swapRB = true;
|
||||
|
||||
// Detection algorithm parameters
|
||||
float confThresh = 0.5;
|
||||
float nmsThresh = 0.4;
|
||||
|
||||
double eps_center = 5/*pixels*/;
|
||||
double eps_size = 5/*pixels*/;
|
||||
double eps_angle = 1;
|
||||
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
eps_center = 10;
|
||||
eps_size = 25;
|
||||
eps_angle = 3;
|
||||
}
|
||||
|
||||
testTextDetectionModelByEAST(weightPath, "", imgPath, gt, confThresh, nmsThresh, size, mean, scale, swapRB, false/*crop*/,
|
||||
eps_center, eps_size, eps_angle
|
||||
);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Model, dnnBackendsAndTargets());
|
||||
|
||||
}} // namespace
|
77
3rdparty/opencv-4.5.4/modules/dnn/test/test_nms.cpp
vendored
Normal file
77
3rdparty/opencv-4.5.4/modules/dnn/test/test_nms.cpp
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(NMS, Accuracy)
|
||||
{
|
||||
//reference results obtained using tf.image.non_max_suppression with iou_threshold=0.5
|
||||
std::string dataPath = findDataFile("dnn/nms_reference.yml");
|
||||
FileStorage fs(dataPath, FileStorage::READ);
|
||||
|
||||
std::vector<Rect> bboxes;
|
||||
std::vector<float> scores;
|
||||
std::vector<int> ref_indices;
|
||||
|
||||
fs["boxes"] >> bboxes;
|
||||
fs["probs"] >> scores;
|
||||
fs["output"] >> ref_indices;
|
||||
|
||||
const float nms_thresh = .5f;
|
||||
const float score_thresh = .01f;
|
||||
std::vector<int> indices;
|
||||
cv::dnn::NMSBoxes(bboxes, scores, score_thresh, nms_thresh, indices);
|
||||
|
||||
ASSERT_EQ(ref_indices.size(), indices.size());
|
||||
|
||||
std::sort(indices.begin(), indices.end());
|
||||
std::sort(ref_indices.begin(), ref_indices.end());
|
||||
|
||||
for(size_t i = 0; i < indices.size(); i++)
|
||||
ASSERT_EQ(indices[i], ref_indices[i]);
|
||||
}
|
||||
|
||||
TEST(SoftNMS, Accuracy)
|
||||
{
|
||||
//reference results are obtained using TF v2.7 tf.image.non_max_suppression_with_scores
|
||||
std::string dataPath = findDataFile("dnn/soft_nms_reference.yml");
|
||||
FileStorage fs(dataPath, FileStorage::READ);
|
||||
|
||||
std::vector<Rect> bboxes;
|
||||
std::vector<float> scores;
|
||||
std::vector<int> ref_indices;
|
||||
std::vector<float> ref_updated_scores;
|
||||
|
||||
fs["boxes"] >> bboxes;
|
||||
fs["probs"] >> scores;
|
||||
fs["indices"] >> ref_indices;
|
||||
fs["updated_scores"] >> ref_updated_scores;
|
||||
|
||||
std::vector<float> updated_scores;
|
||||
const float score_thresh = .01f;
|
||||
const float nms_thresh = .5f;
|
||||
std::vector<int> indices;
|
||||
const size_t top_k = 0;
|
||||
const float sigma = 1.; // sigma in TF is being multiplied by 2, so 0.5 should be passed there
|
||||
cv::dnn::softNMSBoxes(bboxes, scores, updated_scores, score_thresh, nms_thresh, indices, top_k, sigma);
|
||||
|
||||
ASSERT_EQ(ref_indices.size(), indices.size());
|
||||
for(size_t i = 0; i < indices.size(); i++)
|
||||
{
|
||||
ASSERT_EQ(indices[i], ref_indices[i]);
|
||||
}
|
||||
|
||||
ASSERT_EQ(ref_updated_scores.size(), updated_scores.size());
|
||||
for(size_t i = 0; i < updated_scores.size(); i++)
|
||||
{
|
||||
EXPECT_NEAR(updated_scores[i], ref_updated_scores[i], 1e-7);
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
1512
3rdparty/opencv-4.5.4/modules/dnn/test/test_onnx_importer.cpp
vendored
Normal file
1512
3rdparty/opencv-4.5.4/modules/dnn/test/test_onnx_importer.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
3rdparty/opencv-4.5.4/modules/dnn/test/test_precomp.hpp
vendored
Normal file
52
3rdparty/opencv-4.5.4/modules/dnn/test/test_precomp.hpp
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#ifndef __OPENCV_TEST_PRECOMP_HPP__
|
||||
#define __OPENCV_TEST_PRECOMP_HPP__
|
||||
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/ts/ts_perf.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
|
||||
#include "opencv2/dnn.hpp"
|
||||
#include "test_common.hpp"
|
||||
|
||||
#endif
|
1474
3rdparty/opencv-4.5.4/modules/dnn/test/test_tf_importer.cpp
vendored
Normal file
1474
3rdparty/opencv-4.5.4/modules/dnn/test/test_tf_importer.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
641
3rdparty/opencv-4.5.4/modules/dnn/test/test_torch_importer.cpp
vendored
Normal file
641
3rdparty/opencv-4.5.4/modules/dnn/test/test_torch_importer.cpp
vendored
Normal file
@ -0,0 +1,641 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
template<typename TStr>
|
||||
static std::string _tf(TStr filename, bool inTorchDir = true, bool required = true)
|
||||
{
|
||||
String path = "dnn/";
|
||||
if (inTorchDir)
|
||||
path += "torch/";
|
||||
path += filename;
|
||||
return findDataFile(path, required);
|
||||
}
|
||||
|
||||
TEST(Torch_Importer, simple_read)
|
||||
{
|
||||
Net net;
|
||||
ASSERT_NO_THROW(net = readNetFromTorch(_tf("net_simple_net.txt"), false));
|
||||
ASSERT_FALSE(net.empty());
|
||||
}
|
||||
|
||||
class Test_Torch_layers : public DNNTestLayer
|
||||
{
|
||||
public:
|
||||
void runTorchNet(const String& prefix, String outLayerName = "",
|
||||
bool check2ndBlob = false, bool isBinary = false, bool evaluate = true,
|
||||
double l1 = 0.0, double lInf = 0.0)
|
||||
{
|
||||
String suffix = (isBinary) ? ".dat" : ".txt";
|
||||
|
||||
Mat inp, outRef;
|
||||
ASSERT_NO_THROW( inp = readTorchBlob(_tf(prefix + "_input" + suffix), isBinary) );
|
||||
ASSERT_NO_THROW( outRef = readTorchBlob(_tf(prefix + "_output" + suffix), isBinary) );
|
||||
|
||||
checkBackend(backend, target, &inp, &outRef);
|
||||
|
||||
Net net = readNetFromTorch(_tf(prefix + "_net" + suffix), isBinary, evaluate);
|
||||
ASSERT_FALSE(net.empty());
|
||||
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
if (outLayerName.empty())
|
||||
outLayerName = net.getLayerNames().back();
|
||||
|
||||
net.setInput(inp);
|
||||
std::vector<Mat> outBlobs;
|
||||
net.forward(outBlobs, outLayerName);
|
||||
l1 = l1 ? l1 : default_l1;
|
||||
lInf = lInf ? lInf : default_lInf;
|
||||
normAssert(outRef, outBlobs[0], "", l1, lInf);
|
||||
|
||||
if (check2ndBlob && backend == DNN_BACKEND_OPENCV)
|
||||
{
|
||||
Mat out2 = outBlobs[1];
|
||||
Mat ref2 = readTorchBlob(_tf(prefix + "_output_2" + suffix), isBinary);
|
||||
normAssert(out2, ref2, "", l1, lInf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(Test_Torch_layers, run_convolution)
|
||||
{
|
||||
// Output reference values are in range [23.4018, 72.0181]
|
||||
double l1 = default_l1, lInf = default_lInf;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.08;
|
||||
lInf = 0.43;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.08;
|
||||
lInf = 0.5;
|
||||
}
|
||||
runTorchNet("net_conv", "", false, true, true, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_pool_max)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
if (target == DNN_TARGET_CUDA_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
|
||||
double l1 = 0.0, lInf = 0.0;
|
||||
runTorchNet("net_pool_max", "", true, false, true, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_pool_ave)
|
||||
{
|
||||
runTorchNet("net_pool_ave");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_reshape_change_batch_size)
|
||||
{
|
||||
runTorchNet("net_reshape");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_reshape)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
runTorchNet("net_reshape_batch");
|
||||
runTorchNet("net_reshape_channels", "", false, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_reshape_single_sample)
|
||||
{
|
||||
// Reference output values in range [14.4586, 18.4492].
|
||||
double l1 = default_l1, lInf = default_lInf;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.033;
|
||||
lInf = 0.05;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.02;
|
||||
lInf = 0.04;
|
||||
}
|
||||
runTorchNet("net_reshape_single_sample", "", false, false, true, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_linear)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
runTorchNet("net_linear_2d");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_concat)
|
||||
{
|
||||
runTorchNet("net_concat", "l5_torchMerge");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_depth_concat)
|
||||
{
|
||||
double lInf = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
lInf = 0.032;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
lInf = 0.03;
|
||||
}
|
||||
runTorchNet("net_depth_concat", "", false, true, true, 0.0, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_deconv)
|
||||
{
|
||||
runTorchNet("net_deconv");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_batch_norm)
|
||||
{
|
||||
runTorchNet("net_batch_norm", "", false, true);
|
||||
runTorchNet("net_batch_norm_train", "", false, true, false);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_prelu)
|
||||
{
|
||||
runTorchNet("net_prelu");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_cadd_table)
|
||||
{
|
||||
runTorchNet("net_cadd_table");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_softmax)
|
||||
{
|
||||
runTorchNet("net_softmax");
|
||||
runTorchNet("net_softmax_spatial");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_logsoftmax)
|
||||
{
|
||||
runTorchNet("net_logsoftmax");
|
||||
runTorchNet("net_logsoftmax_spatial");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_lp_pooling_square)
|
||||
{
|
||||
runTorchNet("net_lp_pooling_square", "", false, true);
|
||||
}
|
||||
TEST_P(Test_Torch_layers, net_lp_pooling_power)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
runTorchNet("net_lp_pooling_power", "", false, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_conv_gemm_lrn)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
double l1 = 0.0, lInf = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
l1 = 0.046;
|
||||
lInf = 0.023;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.0042;
|
||||
lInf = 0.021;
|
||||
}
|
||||
// The OpenCL kernels use the native_ math functions which have
|
||||
// implementation defined accuracy, so we use relaxed thresholds. See
|
||||
// https://github.com/opencv/opencv/issues/9821 for more details.
|
||||
else if (target == DNN_TARGET_OPENCL)
|
||||
{
|
||||
l1 = 0.02;
|
||||
lInf = 0.02;
|
||||
}
|
||||
runTorchNet("net_conv_gemm_lrn", "", false, true, true, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_inception_block)
|
||||
{
|
||||
runTorchNet("net_inception_block", "", false, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_normalize)
|
||||
{
|
||||
if(backend == DNN_BACKEND_CUDA)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); /* only L1 and L2 norms are supported */
|
||||
runTorchNet("net_normalize", "", false, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_padding)
|
||||
{
|
||||
runTorchNet("net_padding", "", false, true);
|
||||
runTorchNet("net_spatial_zero_padding", "", false, true);
|
||||
runTorchNet("net_spatial_reflection_padding", "", false, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_non_spatial)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && ( \
|
||||
INF_ENGINE_VER_MAJOR_EQ(2021030000) || \
|
||||
INF_ENGINE_VER_MAJOR_EQ(2021040000) \
|
||||
)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
// 2021.3: crash
|
||||
// 2021.4: [ GENERAL_ERROR ] AssertionFailed: !out.networkInputs.empty()
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
|
||||
#endif
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 &&
|
||||
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
runTorchNet("net_non_spatial", "", false, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_paralel)
|
||||
{
|
||||
if (backend != DNN_BACKEND_OPENCV || target != DNN_TARGET_CPU)
|
||||
throw SkipTestException(""); // TODO: Check this
|
||||
runTorchNet("net_parallel", "l5_torchMerge");
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, net_residual)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_OPENCL ||
|
||||
target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
runTorchNet("net_residual", "", false, true);
|
||||
}
|
||||
|
||||
class Test_Torch_nets : public DNNTestLayer {};
|
||||
|
||||
TEST_P(Test_Torch_nets, OpenFace_accuracy)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
#endif
|
||||
checkBackend();
|
||||
|
||||
const string model = findDataFile("dnn/openface_nn4.small2.v1.t7", false);
|
||||
Net net = readNetFromTorch(model);
|
||||
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
Mat sample = imread(findDataFile("cv/shared/lena.png"));
|
||||
Mat sampleF32(sample.size(), CV_32FC3);
|
||||
sample.convertTo(sampleF32, sampleF32.type());
|
||||
sampleF32 /= 255;
|
||||
resize(sampleF32, sampleF32, Size(96, 96), 0, 0, INTER_NEAREST);
|
||||
|
||||
Mat inputBlob = blobFromImage(sampleF32, 1.0, Size(), Scalar(), /*swapRB*/true);
|
||||
|
||||
net.setInput(inputBlob);
|
||||
Mat out = net.forward();
|
||||
|
||||
// Reference output values are in range [-0.17212, 0.263492]
|
||||
// on Myriad problem layer: l4_Pooling - does not use pads_begin
|
||||
float l1 = 1e-5, lInf = 1e-3;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 2e-3;
|
||||
lInf = 5e-3;
|
||||
}
|
||||
else if (target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
l1 = 0.0004;
|
||||
lInf = 0.0012;
|
||||
}
|
||||
Mat outRef = readTorchBlob(_tf("net_openface_output.dat"), true);
|
||||
normAssert(out, outRef, "", l1, lInf);
|
||||
}
|
||||
|
||||
static Mat getSegmMask(const Mat& scores)
|
||||
{
|
||||
const int rows = scores.size[2];
|
||||
const int cols = scores.size[3];
|
||||
const int numClasses = scores.size[1];
|
||||
|
||||
Mat maxCl = Mat::zeros(rows, cols, CV_8UC1);
|
||||
Mat maxVal(rows, cols, CV_32FC1, Scalar(0));
|
||||
for (int ch = 0; ch < numClasses; ch++)
|
||||
{
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
const float *ptrScore = scores.ptr<float>(0, ch, row);
|
||||
uint8_t *ptrMaxCl = maxCl.ptr<uint8_t>(row);
|
||||
float *ptrMaxVal = maxVal.ptr<float>(row);
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
if (ptrScore[col] > ptrMaxVal[col])
|
||||
{
|
||||
ptrMaxVal[col] = ptrScore[col];
|
||||
ptrMaxCl[col] = (uchar)ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxCl;
|
||||
}
|
||||
|
||||
// Computer per-class intersection over union metric.
|
||||
static void normAssertSegmentation(const Mat& ref, const Mat& test)
|
||||
{
|
||||
CV_Assert_N(ref.dims == 4, test.dims == 4);
|
||||
const int numClasses = ref.size[1];
|
||||
CV_Assert(numClasses == test.size[1]);
|
||||
|
||||
Mat refMask = getSegmMask(ref);
|
||||
Mat testMask = getSegmMask(test);
|
||||
EXPECT_EQ(countNonZero(refMask != testMask), 0);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_nets, ENet_accuracy)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
checkBackend();
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("");
|
||||
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#else
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
throw SkipTestException("");
|
||||
}
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2021010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
throw SkipTestException("");
|
||||
}
|
||||
|
||||
Net net;
|
||||
{
|
||||
const string model = findDataFile("dnn/Enet-model-best.net", false);
|
||||
net = readNetFromTorch(model, true);
|
||||
ASSERT_TRUE(!net.empty());
|
||||
}
|
||||
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
Mat sample = imread(_tf("street.png", false));
|
||||
Mat inputBlob = blobFromImage(sample, 1./255, Size(), Scalar(), /*swapRB*/true);
|
||||
|
||||
net.setInput(inputBlob, "");
|
||||
Mat out = net.forward();
|
||||
Mat ref = blobFromNPY(_tf("torch_enet_prob.npy", false));
|
||||
// Due to numerical instability in Pooling-Unpooling layers (indexes jittering)
|
||||
// thresholds for ENet must be changed. Accuracy of results was checked on
|
||||
// Cityscapes dataset and difference in mIOU with Torch is 10E-4%
|
||||
normAssert(ref, out, "", 0.00044, /*target == DNN_TARGET_CPU ? 0.453 : */0.552);
|
||||
normAssertSegmentation(ref, out);
|
||||
|
||||
const int N = 3;
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
net.setInput(inputBlob, "");
|
||||
Mat out = net.forward();
|
||||
normAssert(ref, out, "", 0.00044, /*target == DNN_TARGET_CPU ? 0.453 : */0.552);
|
||||
normAssertSegmentation(ref, out);
|
||||
}
|
||||
}
|
||||
|
||||
// Check accuracy of style transfer models from https://github.com/jcjohnson/fast-neural-style
|
||||
// th fast_neural_style.lua \
|
||||
// -input_image ~/opencv_extra/testdata/dnn/googlenet_1.png \
|
||||
// -output_image lena.png \
|
||||
// -median_filter 0 \
|
||||
// -image_size 0 \
|
||||
// -model models/eccv16/starry_night.t7
|
||||
// th fast_neural_style.lua \
|
||||
// -input_image ~/opencv_extra/testdata/dnn/googlenet_1.png \
|
||||
// -output_image lena.png \
|
||||
// -median_filter 0 \
|
||||
// -image_size 0 \
|
||||
// -model models/instance_norm/feathers.t7
|
||||
TEST_P(Test_Torch_nets, FastNeuralStyle_accuracy)
|
||||
{
|
||||
#if defined INF_ENGINE_RELEASE
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
#if INF_ENGINE_RELEASE <= 2018050000
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
std::string models[] = {"dnn/fast_neural_style_eccv16_starry_night.t7",
|
||||
"dnn/fast_neural_style_instance_norm_feathers.t7"};
|
||||
std::string targets[] = {"dnn/lena_starry_night.png", "dnn/lena_feathers.png"};
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
const string model = findDataFile(models[i], false);
|
||||
Net net = readNetFromTorch(model);
|
||||
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
Mat img = imread(findDataFile("dnn/googlenet_1.png"));
|
||||
Mat inputBlob = blobFromImage(img, 1.0, Size(), Scalar(103.939, 116.779, 123.68), false);
|
||||
|
||||
net.setInput(inputBlob);
|
||||
Mat out = net.forward();
|
||||
|
||||
// Deprocessing.
|
||||
getPlane(out, 0, 0) += 103.939;
|
||||
getPlane(out, 0, 1) += 116.779;
|
||||
getPlane(out, 0, 2) += 123.68;
|
||||
out = cv::min(cv::max(0, out), 255);
|
||||
|
||||
Mat ref = imread(findDataFile(targets[i]));
|
||||
Mat refBlob = blobFromImage(ref, 1.0, Size(), Scalar(), false);
|
||||
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
double normL1 = cvtest::norm(refBlob, out, cv::NORM_L1) / refBlob.total();
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
EXPECT_LE(normL1, 4.0f);
|
||||
else
|
||||
EXPECT_LE(normL1, 0.6f);
|
||||
}
|
||||
else if(target == DNN_TARGET_CUDA_FP16)
|
||||
{
|
||||
normAssert(out, refBlob, "", 0.6, 25);
|
||||
}
|
||||
else
|
||||
normAssert(out, refBlob, "", 0.5, 1.1);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Torch_nets, dnnBackendsAndTargets());
|
||||
|
||||
// Test a custom layer
|
||||
// https://github.com/torch/nn/blob/master/doc/convolution.md#nn.SpatialUpSamplingNearest
|
||||
class SpatialUpSamplingNearestLayer CV_FINAL : public Layer
|
||||
{
|
||||
public:
|
||||
SpatialUpSamplingNearestLayer(const LayerParams ¶ms) : Layer(params)
|
||||
{
|
||||
scale = params.get<int>("scale_factor");
|
||||
}
|
||||
|
||||
static Ptr<Layer> create(LayerParams& params)
|
||||
{
|
||||
return Ptr<Layer>(new SpatialUpSamplingNearestLayer(params));
|
||||
}
|
||||
|
||||
virtual bool getMemoryShapes(const std::vector<std::vector<int> > &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<std::vector<int> > &outputs,
|
||||
std::vector<std::vector<int> > &internals) const CV_OVERRIDE
|
||||
{
|
||||
std::vector<int> outShape(4);
|
||||
outShape[0] = inputs[0][0]; // batch size
|
||||
outShape[1] = inputs[0][1]; // number of channels
|
||||
outShape[2] = scale * inputs[0][2];
|
||||
outShape[3] = scale * inputs[0][3];
|
||||
outputs.assign(1, outShape);
|
||||
return false;
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays) CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
|
||||
|
||||
std::vector<Mat> inputs, outputs;
|
||||
inputs_arr.getMatVector(inputs);
|
||||
outputs_arr.getMatVector(outputs);
|
||||
|
||||
Mat& inp = inputs[0];
|
||||
Mat& out = outputs[0];
|
||||
const int outHeight = out.size[2];
|
||||
const int outWidth = out.size[3];
|
||||
for (size_t n = 0; n < inp.size[0]; ++n)
|
||||
{
|
||||
for (size_t ch = 0; ch < inp.size[1]; ++ch)
|
||||
{
|
||||
resize(getPlane(inp, n, ch), getPlane(out, n, ch),
|
||||
Size(outWidth, outHeight), 0, 0, INTER_NEAREST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int scale;
|
||||
};
|
||||
|
||||
TEST_P(Test_Torch_layers, upsampling_nearest)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // TODO
|
||||
#endif
|
||||
|
||||
// Test a custom layer.
|
||||
CV_DNN_REGISTER_LAYER_CLASS(SpatialUpSamplingNearest, SpatialUpSamplingNearestLayer);
|
||||
try
|
||||
{
|
||||
runTorchNet("net_spatial_upsampling_nearest", "", false, true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LayerFactory::unregisterLayer("SpatialUpSamplingNearest");
|
||||
throw;
|
||||
}
|
||||
LayerFactory::unregisterLayer("SpatialUpSamplingNearest");
|
||||
|
||||
// Test an implemented layer.
|
||||
runTorchNet("net_spatial_upsampling_nearest", "", false, true);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_Torch_layers, dnnBackendsAndTargets());
|
||||
|
||||
}
|
Reference in New Issue
Block a user