chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
# Plaidml is an optional backend
|
||||
pkgs = [
|
||||
('ocl' , cv.gapi.core.ocl.kernels()),
|
||||
('cpu' , cv.gapi.core.cpu.kernels()),
|
||||
('fluid' , cv.gapi.core.fluid.kernels())
|
||||
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
||||
]
|
||||
|
||||
|
||||
class gapi_core_test(NewOpenCVTests):
|
||||
|
||||
def test_add(self):
|
||||
# TODO: Extend to use any type and size here
|
||||
sz = (720, 1280)
|
||||
in1 = np.full(sz, 100)
|
||||
in2 = np.full(sz, 50)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.add(in1, in2)
|
||||
|
||||
# G-API
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
g_out = cv.gapi.add(g_in1, g_in2)
|
||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in1, in2), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_add_uint8(self):
|
||||
sz = (720, 1280)
|
||||
in1 = np.full(sz, 100, dtype=np.uint8)
|
||||
in2 = np.full(sz, 50 , dtype=np.uint8)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.add(in1, in2)
|
||||
|
||||
# G-API
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
g_out = cv.gapi.add(g_in1, g_in2)
|
||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in1, in2), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_mean(self):
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in_mat = cv.imread(img_path)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.mean(in_mat)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.mean(g_in)
|
||||
comp = cv.GComputation(g_in, g_out)
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_split3(self):
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in_mat = cv.imread(img_path)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.split(in_mat)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
b, g, r = cv.gapi.split3(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
for e, a in zip(expected, actual):
|
||||
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
self.assertEqual(e.dtype, a.dtype, 'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_threshold(self):
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
||||
maxv = (30, 30)
|
||||
|
||||
# OpenCV
|
||||
expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_sc = cv.GScalar()
|
||||
mat, threshold = cv.gapi.threshold(g_in, g_sc, cv.THRESH_TRIANGLE)
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(mat, threshold))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected_mat, actual_mat, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
self.assertEqual(expected_mat.dtype, actual_mat.dtype,
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
self.assertEqual(expected_thresh, actual_thresh[0],
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_kmeans(self):
|
||||
# K-means params
|
||||
count = 100
|
||||
sz = (count, 2)
|
||||
in_mat = np.random.random(sz).astype(np.float32)
|
||||
K = 5
|
||||
flags = cv.KMEANS_RANDOM_CENTERS
|
||||
attempts = 1
|
||||
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
compactness, out_labels, centers = cv.gapi.kmeans(g_in, K, criteria, attempts, flags)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(compactness, out_labels, centers))
|
||||
|
||||
compact, labels, centers = comp.apply(cv.gin(in_mat))
|
||||
|
||||
# Assert
|
||||
self.assertTrue(compact >= 0)
|
||||
self.assertEqual(sz[0], labels.shape[0])
|
||||
self.assertEqual(1, labels.shape[1])
|
||||
self.assertTrue(labels.size != 0)
|
||||
self.assertEqual(centers.shape[1], sz[1])
|
||||
self.assertEqual(centers.shape[0], K)
|
||||
self.assertTrue(centers.size != 0)
|
||||
|
||||
|
||||
def generate_random_points(self, sz):
|
||||
arr = np.random.random(sz).astype(np.float32).T
|
||||
return list(zip(*[arr[i] for i in range(sz[1])]))
|
||||
|
||||
|
||||
def test_kmeans_2d(self):
|
||||
# K-means 2D params
|
||||
count = 100
|
||||
sz = (count, 2)
|
||||
amount = sz[0]
|
||||
K = 5
|
||||
flags = cv.KMEANS_RANDOM_CENTERS
|
||||
attempts = 1
|
||||
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0)
|
||||
in_vector = self.generate_random_points(sz)
|
||||
in_labels = []
|
||||
|
||||
# G-API
|
||||
data = cv.GArrayT(cv.gapi.CV_POINT2F)
|
||||
best_labels = cv.GArrayT(cv.gapi.CV_INT)
|
||||
|
||||
compactness, out_labels, centers = cv.gapi.kmeans(data, K, best_labels, criteria, attempts, flags)
|
||||
comp = cv.GComputation(cv.GIn(data, best_labels), cv.GOut(compactness, out_labels, centers))
|
||||
|
||||
compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels))
|
||||
|
||||
# Assert
|
||||
self.assertTrue(compact >= 0)
|
||||
self.assertEqual(amount, len(labels))
|
||||
self.assertEqual(K, len(centers))
|
||||
|
||||
|
||||
def test_kmeans_3d(self):
|
||||
# K-means 3D params
|
||||
count = 100
|
||||
sz = (count, 3)
|
||||
amount = sz[0]
|
||||
K = 5
|
||||
flags = cv.KMEANS_RANDOM_CENTERS
|
||||
attempts = 1
|
||||
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0)
|
||||
in_vector = self.generate_random_points(sz)
|
||||
in_labels = []
|
||||
|
||||
# G-API
|
||||
data = cv.GArrayT(cv.gapi.CV_POINT3F)
|
||||
best_labels = cv.GArrayT(cv.gapi.CV_INT)
|
||||
|
||||
compactness, out_labels, centers = cv.gapi.kmeans(data, K, best_labels, criteria, attempts, flags)
|
||||
comp = cv.GComputation(cv.GIn(data, best_labels), cv.GOut(compactness, out_labels, centers))
|
||||
|
||||
compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels))
|
||||
|
||||
# Assert
|
||||
self.assertTrue(compact >= 0)
|
||||
self.assertEqual(amount, len(labels))
|
||||
self.assertEqual(K, len(centers))
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
# Plaidml is an optional backend
|
||||
pkgs = [
|
||||
('ocl' , cv.gapi.core.ocl.kernels()),
|
||||
('cpu' , cv.gapi.core.cpu.kernels()),
|
||||
('fluid' , cv.gapi.core.fluid.kernels())
|
||||
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
||||
]
|
||||
|
||||
|
||||
class gapi_imgproc_test(NewOpenCVTests):
|
||||
|
||||
def test_good_features_to_track(self):
|
||||
# TODO: Extend to use any type and size here
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
||||
|
||||
# NB: goodFeaturesToTrack configuration
|
||||
max_corners = 50
|
||||
quality_lvl = 0.01
|
||||
min_distance = 10
|
||||
block_sz = 3
|
||||
use_harris_detector = True
|
||||
k = 0.04
|
||||
mask = None
|
||||
|
||||
# OpenCV
|
||||
expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl,
|
||||
min_distance, mask=mask,
|
||||
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl,
|
||||
min_distance, mask, block_sz, use_harris_detector, k)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg))
|
||||
# NB: OpenCV & G-API have different output shapes:
|
||||
# OpenCV - (num_points, 1, 2)
|
||||
# G-API - (num_points, 2)
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected.flatten(),
|
||||
np.array(actual, dtype=np.float32).flatten(),
|
||||
cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_rgb2gray(self):
|
||||
# TODO: Extend to use any type and size here
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in1 = cv.imread(img_path)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.RGB2Gray(g_in)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
def test_bounding_rect(self):
|
||||
sz = 1280
|
||||
fscale = 256
|
||||
|
||||
def sample_value(fscale):
|
||||
return np.random.uniform(0, 255 * fscale) / fscale
|
||||
|
||||
points = np.array([(sample_value(fscale), sample_value(fscale)) for _ in range(1280)], np.float32)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.boundingRect(points)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.boundingRect(g_in)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
for pkg_name, pkg in pkgs:
|
||||
actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg))
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||
'Failed on ' + pkg_name + ' backend')
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,341 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
|
||||
class test_gapi_infer(NewOpenCVTests):
|
||||
|
||||
def infer_reference_network(self, model_path, weights_path, img):
|
||||
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
||||
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
||||
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
||||
|
||||
blob = cv.dnn.blobFromImage(img)
|
||||
|
||||
net.setInput(blob)
|
||||
return net.forward(net.getUnconnectedOutLayersNames())
|
||||
|
||||
|
||||
def make_roi(self, img, roi):
|
||||
return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...]
|
||||
|
||||
|
||||
def test_age_gender_infer(self):
|
||||
# NB: Check IE
|
||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||
return
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.resize(cv.imread(img_path), (62,62))
|
||||
|
||||
# OpenCV DNN
|
||||
dnn_age, dnn_gender = self.infer_reference_network(model_path, weights_path, img)
|
||||
|
||||
# OpenCV G-API
|
||||
g_in = cv.GMat()
|
||||
inputs = cv.GInferInputs()
|
||||
inputs.setInput('data', g_in)
|
||||
|
||||
outputs = cv.gapi.infer("net", inputs)
|
||||
age_g = outputs.at("age_conv3")
|
||||
gender_g = outputs.at("prob")
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(age_g, gender_g))
|
||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||
|
||||
gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||
|
||||
# Check
|
||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_age_gender_infer_roi(self):
|
||||
# NB: Check IE
|
||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||
return
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
roi = (10, 10, 62, 62)
|
||||
|
||||
# OpenCV DNN
|
||||
dnn_age, dnn_gender = self.infer_reference_network(model_path,
|
||||
weights_path,
|
||||
self.make_roi(img, roi))
|
||||
|
||||
# OpenCV G-API
|
||||
g_in = cv.GMat()
|
||||
g_roi = cv.GOpaqueT(cv.gapi.CV_RECT)
|
||||
inputs = cv.GInferInputs()
|
||||
inputs.setInput('data', g_in)
|
||||
|
||||
outputs = cv.gapi.infer("net", g_roi, inputs)
|
||||
age_g = outputs.at("age_conv3")
|
||||
gender_g = outputs.at("prob")
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_roi), cv.GOut(age_g, gender_g))
|
||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||
|
||||
gapi_age, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||
|
||||
# Check
|
||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_age_gender_infer_roi_list(self):
|
||||
# NB: Check IE
|
||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||
return
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)]
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
|
||||
# OpenCV DNN
|
||||
dnn_age_list = []
|
||||
dnn_gender_list = []
|
||||
for roi in rois:
|
||||
age, gender = self.infer_reference_network(model_path,
|
||||
weights_path,
|
||||
self.make_roi(img, roi))
|
||||
dnn_age_list.append(age)
|
||||
dnn_gender_list.append(gender)
|
||||
|
||||
# OpenCV G-API
|
||||
g_in = cv.GMat()
|
||||
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
|
||||
inputs = cv.GInferInputs()
|
||||
inputs.setInput('data', g_in)
|
||||
|
||||
outputs = cv.gapi.infer("net", g_rois, inputs)
|
||||
age_g = outputs.at("age_conv3")
|
||||
gender_g = outputs.at("prob")
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g))
|
||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||
|
||||
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
|
||||
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||
|
||||
# Check
|
||||
for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list,
|
||||
gapi_gender_list,
|
||||
dnn_age_list,
|
||||
dnn_gender_list):
|
||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_age_gender_infer2_roi(self):
|
||||
# NB: Check IE
|
||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||
return
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)]
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
|
||||
# OpenCV DNN
|
||||
dnn_age_list = []
|
||||
dnn_gender_list = []
|
||||
for roi in rois:
|
||||
age, gender = self.infer_reference_network(model_path,
|
||||
weights_path,
|
||||
self.make_roi(img, roi))
|
||||
dnn_age_list.append(age)
|
||||
dnn_gender_list.append(gender)
|
||||
|
||||
# OpenCV G-API
|
||||
g_in = cv.GMat()
|
||||
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
|
||||
inputs = cv.GInferListInputs()
|
||||
inputs.setInput('data', g_rois)
|
||||
|
||||
outputs = cv.gapi.infer2("net", g_in, inputs)
|
||||
age_g = outputs.at("age_conv3")
|
||||
gender_g = outputs.at("prob")
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g))
|
||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||
|
||||
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
|
||||
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||
|
||||
# Check
|
||||
for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list,
|
||||
gapi_gender_list,
|
||||
dnn_age_list,
|
||||
dnn_gender_list):
|
||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
|
||||
def test_person_detection_retail_0013(self):
|
||||
# NB: Check IE
|
||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||
return
|
||||
|
||||
root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
device_id = 'CPU'
|
||||
img = cv.resize(cv.imread(img_path), (544, 320))
|
||||
|
||||
# OpenCV DNN
|
||||
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
||||
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
||||
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
||||
|
||||
blob = cv.dnn.blobFromImage(img)
|
||||
|
||||
def parseSSD(detections, size):
|
||||
h, w = size
|
||||
bboxes = []
|
||||
detections = detections.reshape(-1, 7)
|
||||
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
|
||||
if confidence >= 0.5:
|
||||
x = int(xmin * w)
|
||||
y = int(ymin * h)
|
||||
width = int(xmax * w - x)
|
||||
height = int(ymax * h - y)
|
||||
bboxes.append((x, y, width, height))
|
||||
|
||||
return bboxes
|
||||
|
||||
net.setInput(blob)
|
||||
dnn_detections = net.forward()
|
||||
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
|
||||
|
||||
# OpenCV G-API
|
||||
g_in = cv.GMat()
|
||||
inputs = cv.GInferInputs()
|
||||
inputs.setInput('data', g_in)
|
||||
|
||||
g_sz = cv.gapi.streaming.size(g_in)
|
||||
outputs = cv.gapi.infer("net", inputs)
|
||||
detections = outputs.at("detection_out")
|
||||
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
|
||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||
|
||||
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
|
||||
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
|
||||
np.array(gapi_boxes).flatten(),
|
||||
cv.NORM_INF))
|
||||
|
||||
|
||||
def test_person_detection_retail_0013(self):
|
||||
# NB: Check IE
|
||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||
return
|
||||
|
||||
root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
device_id = 'CPU'
|
||||
img = cv.resize(cv.imread(img_path), (544, 320))
|
||||
|
||||
# OpenCV DNN
|
||||
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
||||
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
||||
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
||||
|
||||
blob = cv.dnn.blobFromImage(img)
|
||||
|
||||
def parseSSD(detections, size):
|
||||
h, w = size
|
||||
bboxes = []
|
||||
detections = detections.reshape(-1, 7)
|
||||
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
|
||||
if confidence >= 0.5:
|
||||
x = int(xmin * w)
|
||||
y = int(ymin * h)
|
||||
width = int(xmax * w - x)
|
||||
height = int(ymax * h - y)
|
||||
bboxes.append((x, y, width, height))
|
||||
|
||||
return bboxes
|
||||
|
||||
net.setInput(blob)
|
||||
dnn_detections = net.forward()
|
||||
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
|
||||
|
||||
# OpenCV G-API
|
||||
g_in = cv.GMat()
|
||||
inputs = cv.GInferInputs()
|
||||
inputs.setInput('data', g_in)
|
||||
|
||||
g_sz = cv.gapi.streaming.size(g_in)
|
||||
outputs = cv.gapi.infer("net", inputs)
|
||||
detections = outputs.at("detection_out")
|
||||
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
|
||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||
|
||||
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
|
||||
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
|
||||
np.array(gapi_boxes).flatten(),
|
||||
cv.NORM_INF))
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
CLASSIFICATION_MODEL_PATH = "vision/classification/squeezenet/model/squeezenet1.0-9.onnx"
|
||||
|
||||
class test_gapi_infer(NewOpenCVTests):
|
||||
def find_dnn_file(self, filename):
|
||||
return self.find_file(filename, [os.environ.get('OPENCV_GAPI_ONNX_MODEL_PATH')], False)
|
||||
|
||||
def test_onnx_classification(self):
|
||||
model_path = self.find_dnn_file(CLASSIFICATION_MODEL_PATH)
|
||||
if model_path is None:
|
||||
raise unittest.SkipTest("Missing DNN test file")
|
||||
|
||||
in_mat = cv.imread(
|
||||
self.find_file("cv/dpm/cat.png",
|
||||
[os.environ.get('OPENCV_TEST_DATA_PATH')]))
|
||||
|
||||
g_in = cv.GMat()
|
||||
g_infer_inputs = cv.GInferInputs()
|
||||
g_infer_inputs.setInput("data_0", g_in)
|
||||
g_infer_out = cv.gapi.infer("squeeze-net", g_infer_inputs)
|
||||
g_out = g_infer_out.at("softmaxout_1")
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
net = cv.gapi.onnx.params("squeeze-net", model_path)
|
||||
net.cfgNormalize("data_0", False)
|
||||
try:
|
||||
out_gapi = comp.apply(cv.gin(in_mat), cv.gapi.compile_args(cv.gapi.networks(net)))
|
||||
except cv.error as err:
|
||||
if err.args[0] == "G-API has been compiled without ONNX support":
|
||||
raise unittest.SkipTest("G-API has been compiled without ONNX support")
|
||||
else:
|
||||
raise
|
||||
|
||||
self.assertEqual((1, 1000, 1, 1), out_gapi.shape)
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,238 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
|
||||
openvino_is_available = True
|
||||
try:
|
||||
from openvino.runtime import Core, Type, Layout, PartialShape
|
||||
from openvino.preprocess import ResizeAlgorithm, PrePostProcessor
|
||||
except ImportError:
|
||||
openvino_is_available = False
|
||||
|
||||
|
||||
def skip_if_openvino_not_available():
|
||||
if not openvino_is_available:
|
||||
raise unittest.SkipTest("OpenVINO isn't available from python.")
|
||||
|
||||
|
||||
class AgeGenderOV:
|
||||
def __init__(self, model_path, bin_path, device):
|
||||
self.device = device
|
||||
self.core = Core()
|
||||
self.model = self.core.read_model(model_path, bin_path)
|
||||
|
||||
|
||||
def reshape(self, new_shape):
|
||||
self.model.reshape(new_shape)
|
||||
|
||||
|
||||
def cfgPrePostProcessing(self, pp_callback):
|
||||
ppp = PrePostProcessor(self.model)
|
||||
pp_callback(ppp)
|
||||
self.model = ppp.build()
|
||||
|
||||
|
||||
def apply(self, in_data):
|
||||
compiled_model = self.core.compile_model(self.model, self.device)
|
||||
infer_request = compiled_model.create_infer_request()
|
||||
results = infer_request.infer(in_data)
|
||||
ov_age = results['age_conv3'].squeeze()
|
||||
ov_gender = results['prob'].squeeze()
|
||||
return ov_age, ov_gender
|
||||
|
||||
|
||||
class AgeGenderGAPI:
|
||||
tag = 'age-gender-net'
|
||||
|
||||
def __init__(self, model_path, bin_path, device):
|
||||
g_in = cv.GMat()
|
||||
inputs = cv.GInferInputs()
|
||||
inputs.setInput('data', g_in)
|
||||
# TODO: It'd be nice to pass dict instead.
|
||||
# E.g cv.gapi.infer("net", {'data': g_in})
|
||||
outputs = cv.gapi.infer(AgeGenderGAPI.tag, inputs)
|
||||
age_g = outputs.at("age_conv3")
|
||||
gender_g = outputs.at("prob")
|
||||
|
||||
self.comp = cv.GComputation(cv.GIn(g_in), cv.GOut(age_g, gender_g))
|
||||
self.pp = cv.gapi.ov.params(AgeGenderGAPI.tag, \
|
||||
model_path, bin_path, device)
|
||||
|
||||
|
||||
def apply(self, in_data):
|
||||
compile_args = cv.gapi.compile_args(cv.gapi.networks(self.pp))
|
||||
gapi_age, gapi_gender = self.comp.apply(cv.gin(in_data), compile_args)
|
||||
gapi_gender = gapi_gender.squeeze()
|
||||
gapi_age = gapi_age.squeeze()
|
||||
return gapi_age, gapi_gender
|
||||
|
||||
|
||||
class test_gapi_infer_ov(NewOpenCVTests):
|
||||
|
||||
def test_age_gender_infer_image(self):
|
||||
skip_if_openvino_not_available()
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
bin_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
|
||||
# OpenVINO
|
||||
def preproc(ppp):
|
||||
ppp.input().model().set_layout(Layout("NCHW"))
|
||||
ppp.input().tensor().set_element_type(Type.u8) \
|
||||
.set_spatial_static_shape(img.shape[0], img.shape[1]) \
|
||||
.set_layout(Layout("NHWC"))
|
||||
ppp.input().preprocess().resize(ResizeAlgorithm.RESIZE_LINEAR)
|
||||
|
||||
|
||||
ref = AgeGenderOV(model_path, bin_path, device_id)
|
||||
ref.cfgPrePostProcessing(preproc)
|
||||
ov_age, ov_gender = ref.apply(np.expand_dims(img, 0))
|
||||
|
||||
# OpenCV G-API (No preproc required)
|
||||
comp = AgeGenderGAPI(model_path, bin_path, device_id)
|
||||
gapi_age, gapi_gender = comp.apply(img)
|
||||
|
||||
# Check
|
||||
self.assertEqual(0.0, cv.norm(ov_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(ov_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_age_gender_infer_tensor(self):
|
||||
skip_if_openvino_not_available()
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
bin_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
|
||||
# Prepare data manually
|
||||
tensor = cv.resize(img, (62, 62)).astype(np.float32)
|
||||
tensor = np.transpose(tensor, (2, 0, 1))
|
||||
tensor = np.expand_dims(tensor, 0)
|
||||
|
||||
# OpenVINO (No preproce required)
|
||||
ref = AgeGenderOV(model_path, bin_path, device_id)
|
||||
ov_age, ov_gender = ref.apply(tensor)
|
||||
|
||||
# OpenCV G-API (No preproc required)
|
||||
comp = AgeGenderGAPI(model_path, bin_path, device_id)
|
||||
gapi_age, gapi_gender = comp.apply(tensor)
|
||||
|
||||
# Check
|
||||
self.assertEqual(0.0, cv.norm(ov_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(ov_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_age_gender_infer_batch(self):
|
||||
skip_if_openvino_not_available()
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
bin_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
img_path1 = self.find_file('cv/face/david1.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img_path2 = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img1 = cv.imread(img_path1)
|
||||
img2 = cv.imread(img_path2)
|
||||
# img1 and img2 have the same size
|
||||
batch_img = np.array([img1, img2])
|
||||
|
||||
# OpenVINO
|
||||
def preproc(ppp):
|
||||
ppp.input().model().set_layout(Layout("NCHW"))
|
||||
ppp.input().tensor().set_element_type(Type.u8) \
|
||||
.set_spatial_static_shape(img1.shape[0], img2.shape[1]) \
|
||||
.set_layout(Layout("NHWC"))
|
||||
ppp.input().preprocess().resize(ResizeAlgorithm.RESIZE_LINEAR)
|
||||
|
||||
|
||||
ref = AgeGenderOV(model_path, bin_path, device_id)
|
||||
ref.reshape(PartialShape([2, 3, 62, 62]))
|
||||
ref.cfgPrePostProcessing(preproc)
|
||||
ov_age, ov_gender = ref.apply(batch_img)
|
||||
|
||||
# OpenCV G-API
|
||||
comp = AgeGenderGAPI(model_path, bin_path, device_id)
|
||||
comp.pp.cfgReshape([2, 3, 62, 62]) \
|
||||
.cfgInputModelLayout("NCHW") \
|
||||
.cfgInputTensorLayout("NHWC") \
|
||||
.cfgResize(cv.INTER_LINEAR)
|
||||
gapi_age, gapi_gender = comp.apply(batch_img)
|
||||
|
||||
# Check
|
||||
self.assertEqual(0.0, cv.norm(ov_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(ov_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_age_gender_infer_planar(self):
|
||||
skip_if_openvino_not_available()
|
||||
|
||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
bin_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')], required=False)
|
||||
device_id = 'CPU'
|
||||
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
planar_img = np.transpose(img, (2, 0, 1))
|
||||
planar_img = np.expand_dims(planar_img, 0)
|
||||
|
||||
# OpenVINO
|
||||
def preproc(ppp):
|
||||
ppp.input().tensor().set_element_type(Type.u8) \
|
||||
.set_spatial_static_shape(img.shape[0], img.shape[1])
|
||||
ppp.input().preprocess().resize(ResizeAlgorithm.RESIZE_LINEAR)
|
||||
|
||||
|
||||
ref = AgeGenderOV(model_path, bin_path, device_id)
|
||||
ref.cfgPrePostProcessing(preproc)
|
||||
ov_age, ov_gender = ref.apply(planar_img)
|
||||
|
||||
# OpenCV G-API
|
||||
comp = AgeGenderGAPI(model_path, bin_path, device_id)
|
||||
comp.pp.cfgResize(cv.INTER_LINEAR)
|
||||
gapi_age, gapi_gender = comp.apply(planar_img)
|
||||
|
||||
# Check
|
||||
self.assertEqual(0.0, cv.norm(ov_gender, gapi_gender, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(ov_age, gapi_age, cv.NORM_INF))
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
class gapi_kernels_test(NewOpenCVTests):
|
||||
|
||||
def test_fluid_core_package(self):
|
||||
fluid_core = cv.gapi.core.fluid.kernels()
|
||||
self.assertLess(0, fluid_core.size())
|
||||
|
||||
def test_fluid_imgproc_package(self):
|
||||
fluid_imgproc = cv.gapi.imgproc.fluid.kernels()
|
||||
self.assertLess(0, fluid_imgproc.size())
|
||||
|
||||
def test_combine(self):
|
||||
fluid_core = cv.gapi.core.fluid.kernels()
|
||||
fluid_imgproc = cv.gapi.imgproc.fluid.kernels()
|
||||
fluid = cv.gapi.combine(fluid_core, fluid_imgproc)
|
||||
self.assertEqual(fluid_core.size() + fluid_imgproc.size(), fluid.size())
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
class gapi_ot_test(NewOpenCVTests):
|
||||
|
||||
def test_ot_smoke(self):
|
||||
# Input
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in_image = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2BGR)
|
||||
in_rects = [ (138, 89, 71, 64) ]
|
||||
in_rects_cls = [ 0 ]
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_in_rects = cv.GArray.Rect()
|
||||
g_in_rects_cls = cv.GArray.Int()
|
||||
delta = 0.5
|
||||
|
||||
g_out_rects, g_out_rects_cls, g_track_ids, g_track_sts = \
|
||||
cv.gapi.ot.track(g_in, g_in_rects, g_in_rects_cls, delta)
|
||||
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_in_rects, g_in_rects_cls),
|
||||
cv.GOut(g_out_rects, g_out_rects_cls,
|
||||
g_track_ids, g_track_sts))
|
||||
|
||||
__, __, __, sts = comp.apply(cv.gin(in_image, in_rects, in_rects_cls),
|
||||
args=cv.gapi.compile_args(cv.gapi.ot.cpu.kernels()))
|
||||
|
||||
self.assertEqual(cv.gapi.ot.NEW, sts[0])
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,227 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
# FIXME: FText isn't supported yet.
|
||||
class gapi_render_test(NewOpenCVTests):
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
|
||||
self.size = (300, 300, 3)
|
||||
|
||||
# Rect
|
||||
self.rect = (30, 30, 50, 50)
|
||||
self.rcolor = (0, 255, 0)
|
||||
self.rlt = cv.LINE_4
|
||||
self.rthick = 2
|
||||
self.rshift = 3
|
||||
|
||||
# Text
|
||||
self.text = 'Hello, world!'
|
||||
self.org = (100, 100)
|
||||
self.ff = cv.FONT_HERSHEY_SIMPLEX
|
||||
self.fs = 1.0
|
||||
self.tthick = 2
|
||||
self.tlt = cv.LINE_8
|
||||
self.tcolor = (255, 255, 255)
|
||||
self.blo = False
|
||||
|
||||
# Circle
|
||||
self.center = (200, 200)
|
||||
self.radius = 200
|
||||
self.ccolor = (255, 255, 0)
|
||||
self.cthick = 2
|
||||
self.clt = cv.LINE_4
|
||||
self.cshift = 1
|
||||
|
||||
# Line
|
||||
self.pt1 = (50, 50)
|
||||
self.pt2 = (200, 200)
|
||||
self.lcolor = (0, 255, 128)
|
||||
self.lthick = 5
|
||||
self.llt = cv.LINE_8
|
||||
self.lshift = 2
|
||||
|
||||
# Poly
|
||||
self.pts = [(50, 100), (100, 200), (25, 250)]
|
||||
self.pcolor = (0, 0, 255)
|
||||
self.pthick = 3
|
||||
self.plt = cv.LINE_4
|
||||
self.pshift = 1
|
||||
|
||||
# Image
|
||||
self.iorg = (150, 150)
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
self.img = cv.resize(cv.imread(img_path), (50, 50))
|
||||
self.alpha = np.full(self.img.shape[:2], 0.8, dtype=np.float32)
|
||||
|
||||
# Mosaic
|
||||
self.mos = (100, 100, 100, 100)
|
||||
self.cell_sz = 25
|
||||
self.decim = 0
|
||||
|
||||
# Render primitives
|
||||
self.prims = [cv.gapi.wip.draw.Rect(self.rect, self.rcolor, self.rthick, self.rlt, self.rshift),
|
||||
cv.gapi.wip.draw.Text(self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo),
|
||||
cv.gapi.wip.draw.Circle(self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift),
|
||||
cv.gapi.wip.draw.Line(self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift),
|
||||
cv.gapi.wip.draw.Mosaic(self.mos, self.cell_sz, self.decim),
|
||||
cv.gapi.wip.draw.Image(self.iorg, self.img, self.alpha),
|
||||
cv.gapi.wip.draw.Poly(self.pts, self.pcolor, self.pthick, self.plt, self.pshift)]
|
||||
|
||||
def cvt_nv12_to_yuv(self, y, uv):
|
||||
h,w,_ = uv.shape
|
||||
upsample_uv = cv.resize(uv, (h * 2, w * 2))
|
||||
return cv.merge([y, upsample_uv])
|
||||
|
||||
def cvt_yuv_to_nv12(self, yuv, y_out, uv_out):
|
||||
chs = cv.split(yuv, [y_out, None, None])
|
||||
uv = cv.merge([chs[1], chs[2]])
|
||||
uv_out = cv.resize(uv, (uv.shape[0] // 2, uv.shape[1] // 2), dst=uv_out)
|
||||
return y_out, uv_out
|
||||
|
||||
def cvt_bgr_to_yuv_color(self, bgr):
|
||||
y = bgr[2] * 0.299000 + bgr[1] * 0.587000 + bgr[0] * 0.114000;
|
||||
u = bgr[2] * -0.168736 + bgr[1] * -0.331264 + bgr[0] * 0.500000 + 128;
|
||||
v = bgr[2] * 0.500000 + bgr[1] * -0.418688 + bgr[0] * -0.081312 + 128;
|
||||
return (y, u, v)
|
||||
|
||||
def blend_img(self, background, org, img, alpha):
|
||||
x, y = org
|
||||
h, w, _ = img.shape
|
||||
roi_img = background[x:x+w, y:y+h, :]
|
||||
img32f_w = cv.merge([alpha] * 3).astype(np.float32)
|
||||
roi32f_w = np.full(roi_img.shape, 1.0, dtype=np.float32)
|
||||
roi32f_w -= img32f_w
|
||||
img32f = (img / 255).astype(np.float32)
|
||||
roi32f = (roi_img / 255).astype(np.float32)
|
||||
cv.multiply(img32f, img32f_w, dst=img32f)
|
||||
cv.multiply(roi32f, roi32f_w, dst=roi32f)
|
||||
roi32f += img32f
|
||||
roi_img[...] = np.round(roi32f * 255)
|
||||
|
||||
# This is quite naive implementations used as a simple reference
|
||||
# doesn't consider corner cases.
|
||||
def draw_mosaic(self, img, mos, cell_sz, decim):
|
||||
x,y,w,h = mos
|
||||
mosaic_area = img[x:x+w, y:y+h, :]
|
||||
for i in range(0, mosaic_area.shape[0], cell_sz):
|
||||
for j in range(0, mosaic_area.shape[1], cell_sz):
|
||||
cell_roi = mosaic_area[j:j+cell_sz, i:i+cell_sz, :]
|
||||
s0, s1, s2 = cv.mean(cell_roi)[:3]
|
||||
mosaic_area[j:j+cell_sz, i:i+cell_sz] = (round(s0), round(s1), round(s2))
|
||||
|
||||
def render_primitives_bgr_ref(self, img):
|
||||
cv.rectangle(img, self.rect, self.rcolor, self.rthick, self.rlt, self.rshift)
|
||||
cv.putText(img, self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo)
|
||||
cv.circle(img, self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift)
|
||||
cv.line(img, self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift)
|
||||
cv.fillPoly(img, np.expand_dims(np.array([self.pts]), axis=0), self.pcolor, self.plt, self.pshift)
|
||||
self.draw_mosaic(img, self.mos, self.cell_sz, self.decim)
|
||||
self.blend_img(img, self.iorg, self.img, self.alpha)
|
||||
|
||||
def render_primitives_nv12_ref(self, y_plane, uv_plane):
|
||||
yuv = self.cvt_nv12_to_yuv(y_plane, uv_plane)
|
||||
cv.rectangle(yuv, self.rect, self.cvt_bgr_to_yuv_color(self.rcolor), self.rthick, self.rlt, self.rshift)
|
||||
cv.putText(yuv, self.text, self.org, self.ff, self.fs, self.cvt_bgr_to_yuv_color(self.tcolor), self.tthick, self.tlt, self.blo)
|
||||
cv.circle(yuv, self.center, self.radius, self.cvt_bgr_to_yuv_color(self.ccolor), self.cthick, self.clt, self.cshift)
|
||||
cv.line(yuv, self.pt1, self.pt2, self.cvt_bgr_to_yuv_color(self.lcolor), self.lthick, self.llt, self.lshift)
|
||||
cv.fillPoly(yuv, np.expand_dims(np.array([self.pts]), axis=0), self.cvt_bgr_to_yuv_color(self.pcolor), self.plt, self.pshift)
|
||||
self.draw_mosaic(yuv, self.mos, self.cell_sz, self.decim)
|
||||
self.blend_img(yuv, self.iorg, cv.cvtColor(self.img, cv.COLOR_BGR2YUV), self.alpha)
|
||||
self.cvt_yuv_to_nv12(yuv, y_plane, uv_plane)
|
||||
|
||||
def test_render_primitives_on_bgr_graph(self):
|
||||
expected = np.zeros(self.size, dtype=np.uint8)
|
||||
actual = np.array(expected, copy=True)
|
||||
|
||||
# OpenCV
|
||||
self.render_primitives_bgr_ref(expected)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_prims = cv.GArray.Prim()
|
||||
g_out = cv.gapi.wip.draw.render3ch(g_in, g_prims)
|
||||
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_prims), cv.GOut(g_out))
|
||||
actual = comp.apply(cv.gin(actual, self.prims))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
def test_render_primitives_on_bgr_function(self):
|
||||
expected = np.zeros(self.size, dtype=np.uint8)
|
||||
actual = np.array(expected, copy=True)
|
||||
|
||||
# OpenCV
|
||||
self.render_primitives_bgr_ref(expected)
|
||||
|
||||
# G-API
|
||||
cv.gapi.wip.draw.render(actual, self.prims)
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
def test_render_primitives_on_nv12_graph(self):
|
||||
y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8)
|
||||
uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8)
|
||||
|
||||
y_actual = np.array(y_expected, copy=True)
|
||||
uv_actual = np.array(uv_expected, copy=True)
|
||||
|
||||
# OpenCV
|
||||
self.render_primitives_nv12_ref(y_expected, uv_expected)
|
||||
|
||||
# G-API
|
||||
g_y = cv.GMat()
|
||||
g_uv = cv.GMat()
|
||||
g_prims = cv.GArray.Prim()
|
||||
g_out_y, g_out_uv = cv.gapi.wip.draw.renderNV12(g_y, g_uv, g_prims)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_y, g_uv, g_prims), cv.GOut(g_out_y, g_out_uv))
|
||||
y_actual, uv_actual = comp.apply(cv.gin(y_actual, uv_actual, self.prims))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF))
|
||||
|
||||
def test_render_primitives_on_nv12_function(self):
|
||||
y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8)
|
||||
uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8)
|
||||
|
||||
y_actual = np.array(y_expected, copy=True)
|
||||
uv_actual = np.array(uv_expected, copy=True)
|
||||
|
||||
# OpenCV
|
||||
self.render_primitives_nv12_ref(y_expected, uv_expected)
|
||||
|
||||
# G-API
|
||||
cv.gapi.wip.draw.render(y_actual, uv_actual, self.prims)
|
||||
|
||||
self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF))
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,722 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
# Plaidml is an optional backend
|
||||
pkgs = [
|
||||
('ocl' , cv.gapi.core.ocl.kernels()),
|
||||
('cpu' , cv.gapi.core.cpu.kernels()),
|
||||
('fluid' , cv.gapi.core.fluid.kernels())
|
||||
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
||||
]
|
||||
|
||||
|
||||
@cv.gapi.op('custom.add', in_types=[cv.GMat, cv.GMat, int], out_types=[cv.GMat])
|
||||
class GAdd:
|
||||
"""Calculates sum of two matrices."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc1, desc2, depth):
|
||||
return desc1
|
||||
|
||||
|
||||
@cv.gapi.kernel(GAdd)
|
||||
class GAddImpl:
|
||||
"""Implementation for GAdd operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img1, img2, dtype):
|
||||
return cv.add(img1, img2)
|
||||
|
||||
|
||||
@cv.gapi.op('custom.split3', in_types=[cv.GMat], out_types=[cv.GMat, cv.GMat, cv.GMat])
|
||||
class GSplit3:
|
||||
"""Divides a 3-channel matrix into 3 single-channel matrices."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
out_desc = desc.withType(desc.depth, 1)
|
||||
return out_desc, out_desc, out_desc
|
||||
|
||||
|
||||
@cv.gapi.kernel(GSplit3)
|
||||
class GSplit3Impl:
|
||||
"""Implementation for GSplit3 operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img):
|
||||
# NB: cv.split return list but g-api requires tuple in multiple output case
|
||||
return tuple(cv.split(img))
|
||||
|
||||
|
||||
@cv.gapi.op('custom.mean', in_types=[cv.GMat], out_types=[cv.GScalar])
|
||||
class GMean:
|
||||
"""Calculates the mean value M of matrix elements."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
return cv.empty_scalar_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GMean)
|
||||
class GMeanImpl:
|
||||
"""Implementation for GMean operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img):
|
||||
# NB: cv.split return list but g-api requires tuple in multiple output case
|
||||
return cv.mean(img)
|
||||
|
||||
|
||||
@cv.gapi.op('custom.addC', in_types=[cv.GMat, cv.GScalar, int], out_types=[cv.GMat])
|
||||
class GAddC:
|
||||
"""Adds a given scalar value to each element of given matrix."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(mat_desc, scalar_desc, dtype):
|
||||
return mat_desc
|
||||
|
||||
|
||||
@cv.gapi.kernel(GAddC)
|
||||
class GAddCImpl:
|
||||
"""Implementation for GAddC operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img, sc, dtype):
|
||||
# NB: dtype is just ignored in this implementation.
|
||||
# Moreover from G-API kernel got scalar as tuples with 4 elements
|
||||
# where the last element is equal to zero, just cut him for broadcasting.
|
||||
return img + np.array(sc, dtype=np.uint8)[:-1]
|
||||
|
||||
|
||||
@cv.gapi.op('custom.size', in_types=[cv.GMat], out_types=[cv.GOpaque.Size])
|
||||
class GSize:
|
||||
"""Gets dimensions from input matrix."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(mat_desc):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GSize)
|
||||
class GSizeImpl:
|
||||
"""Implementation for GSize operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img):
|
||||
# NB: Take only H, W, because the operation should return cv::Size which is 2D.
|
||||
return img.shape[:2]
|
||||
|
||||
|
||||
@cv.gapi.op('custom.sizeR', in_types=[cv.GOpaque.Rect], out_types=[cv.GOpaque.Size])
|
||||
class GSizeR:
|
||||
"""Gets dimensions from rectangle."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(opaq_desc):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GSizeR)
|
||||
class GSizeRImpl:
|
||||
"""Implementation for GSizeR operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(rect):
|
||||
# NB: rect - is tuple (x, y, h, w)
|
||||
return (rect[2], rect[3])
|
||||
|
||||
|
||||
@cv.gapi.op('custom.boundingRect', in_types=[cv.GArray.Point], out_types=[cv.GOpaque.Rect])
|
||||
class GBoundingRect:
|
||||
"""Calculates minimal up-right bounding rectangle for the specified
|
||||
9 point set or non-zero pixels of gray-scale image."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(arr_desc):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GBoundingRect)
|
||||
class GBoundingRectImpl:
|
||||
"""Implementation for GBoundingRect operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(array):
|
||||
# NB: OpenCV - numpy array (n_points x 2).
|
||||
# G-API - array of tuples (n_points).
|
||||
return cv.boundingRect(np.array(array))
|
||||
|
||||
|
||||
@cv.gapi.op('custom.goodFeaturesToTrack',
|
||||
in_types=[cv.GMat, int, float, float, int, bool, float],
|
||||
out_types=[cv.GArray.Point2f])
|
||||
class GGoodFeatures:
|
||||
"""Finds the most prominent corners in the image
|
||||
or in the specified image region."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc, max_corners, quality_lvl,
|
||||
min_distance, block_sz,
|
||||
use_harris_detector, k):
|
||||
return cv.empty_array_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GGoodFeatures)
|
||||
class GGoodFeaturesImpl:
|
||||
"""Implementation for GGoodFeatures operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img, max_corners, quality_lvl,
|
||||
min_distance, block_sz,
|
||||
use_harris_detector, k):
|
||||
features = cv.goodFeaturesToTrack(img, max_corners, quality_lvl,
|
||||
min_distance, mask=None,
|
||||
blockSize=block_sz,
|
||||
useHarrisDetector=use_harris_detector, k=k)
|
||||
# NB: The operation output is cv::GArray<cv::Pointf>, so it should be mapped
|
||||
# to python parameters like this: [(1.2, 3.4), (5.2, 3.2)], because the cv::Point2f
|
||||
# according to opencv rules mapped to the tuple and cv::GArray<> mapped to the list.
|
||||
# OpenCV returns np.array with shape (n_features, 1, 2), so let's to convert it to list
|
||||
# tuples with size == n_features.
|
||||
features = list(map(tuple, features.reshape(features.shape[0], -1)))
|
||||
return features
|
||||
|
||||
|
||||
# To validate invalid cases
|
||||
def create_op(in_types, out_types):
|
||||
@cv.gapi.op('custom.op', in_types=in_types, out_types=out_types)
|
||||
class Op:
|
||||
"""Custom operation for testing."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
raise NotImplementedError("outMeta isn't implemented")
|
||||
return Op
|
||||
|
||||
|
||||
# NB: Just mock operation to test different kinds for output G-types.
|
||||
@cv.gapi.op('custom.square_mean', in_types=[cv.GArray.Int], out_types=[cv.GOpaque.Float, cv.GArray.Int])
|
||||
class GSquareMean:
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
return cv.empty_gopaque_desc(), cv.empty_array_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GSquareMean)
|
||||
class GSquareMeanImpl:
|
||||
@staticmethod
|
||||
def run(arr):
|
||||
squares = [val**2 for val in arr]
|
||||
return sum(arr) / len(arr), squares
|
||||
|
||||
@cv.gapi.op('custom.squares', in_types=[cv.GArray.Int], out_types=[cv.GArray.Int])
|
||||
class GSquare:
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
return cv.empty_array_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GSquare)
|
||||
class GSquareImpl:
|
||||
@staticmethod
|
||||
def run(arr):
|
||||
squares = [val**2 for val in arr]
|
||||
return squares
|
||||
|
||||
|
||||
class gapi_sample_pipelines(NewOpenCVTests):
|
||||
def test_different_output_opaque_kinds(self):
|
||||
g_in = cv.GArray.Int()
|
||||
g_mean, g_squares = GSquareMean.on(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_mean, g_squares))
|
||||
|
||||
pkg = cv.gapi.kernels(GSquareMeanImpl)
|
||||
mean, squares = comp.apply(cv.gin([1,2,3]), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
self.assertEqual([1,4,9], list(squares))
|
||||
self.assertEqual(2.0, mean)
|
||||
|
||||
|
||||
def test_custom_op_add(self):
|
||||
sz = (3, 3)
|
||||
in_mat1 = np.full(sz, 45, dtype=np.uint8)
|
||||
in_mat2 = np.full(sz, 50, dtype=np.uint8)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.add(in_mat1, in_mat2)
|
||||
|
||||
# G-API
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
g_out = GAdd.on(g_in1, g_in2, cv.CV_8UC1)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
|
||||
pkg = cv.gapi.kernels(GAddImpl)
|
||||
actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_custom_op_split3(self):
|
||||
sz = (4, 4)
|
||||
in_ch1 = np.full(sz, 1, dtype=np.uint8)
|
||||
in_ch2 = np.full(sz, 2, dtype=np.uint8)
|
||||
in_ch3 = np.full(sz, 3, dtype=np.uint8)
|
||||
# H x W x C
|
||||
in_mat = np.stack((in_ch1, in_ch2, in_ch3), axis=2)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_ch1, g_ch2, g_ch3 = GSplit3.on(g_in)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ch1, g_ch2, g_ch3))
|
||||
|
||||
pkg = cv.gapi.kernels(GSplit3Impl)
|
||||
ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(in_ch1, ch1, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(in_ch2, ch2, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(in_ch3, ch3, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_custom_op_mean(self):
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in_mat = cv.imread(img_path)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.mean(in_mat)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = GMean.on(g_in)
|
||||
|
||||
comp = cv.GComputation(g_in, g_out)
|
||||
|
||||
pkg = cv.gapi.kernels(GMeanImpl)
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
# Comparison
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
def test_custom_op_addC(self):
|
||||
sz = (3, 3, 3)
|
||||
in_mat = np.full(sz, 45, dtype=np.uint8)
|
||||
sc = (50, 10, 20)
|
||||
|
||||
# Numpy reference, make array from sc to keep uint8 dtype.
|
||||
expected = in_mat + np.array(sc, dtype=np.uint8)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_sc = cv.GScalar()
|
||||
g_out = GAddC.on(g_in, g_sc, cv.CV_8UC1)
|
||||
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(g_out))
|
||||
|
||||
pkg = cv.gapi.kernels(GAddCImpl)
|
||||
actual = comp.apply(cv.gin(in_mat, sc), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_custom_op_size(self):
|
||||
sz = (100, 150, 3)
|
||||
in_mat = np.full(sz, 45, dtype=np.uint8)
|
||||
|
||||
# Open_cV
|
||||
expected = (100, 150)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_sz = GSize.on(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_sz))
|
||||
|
||||
pkg = cv.gapi.kernels(GSizeImpl)
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_custom_op_sizeR(self):
|
||||
# x, y, h, w
|
||||
roi = (10, 15, 100, 150)
|
||||
|
||||
expected = (100, 150)
|
||||
|
||||
# G-API
|
||||
g_r = cv.GOpaque.Rect()
|
||||
g_sz = GSizeR.on(g_r)
|
||||
comp = cv.GComputation(cv.GIn(g_r), cv.GOut(g_sz))
|
||||
|
||||
pkg = cv.gapi.kernels(GSizeRImpl)
|
||||
actual = comp.apply(cv.gin(roi), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
# cv.norm works with tuples ?
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_custom_op_boundingRect(self):
|
||||
points = [(0,0), (0,1), (1,0), (1,1)]
|
||||
|
||||
# OpenCV
|
||||
expected = cv.boundingRect(np.array(points))
|
||||
|
||||
# G-API
|
||||
g_pts = cv.GArray.Point()
|
||||
g_br = GBoundingRect.on(g_pts)
|
||||
comp = cv.GComputation(cv.GIn(g_pts), cv.GOut(g_br))
|
||||
|
||||
pkg = cv.gapi.kernels(GBoundingRectImpl)
|
||||
actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
# cv.norm works with tuples ?
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_custom_op_goodFeaturesToTrack(self):
|
||||
# G-API
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
||||
|
||||
# NB: goodFeaturesToTrack configuration
|
||||
max_corners = 50
|
||||
quality_lvl = 0.01
|
||||
min_distance = 10.0
|
||||
block_sz = 3
|
||||
use_harris_detector = True
|
||||
k = 0.04
|
||||
|
||||
# OpenCV
|
||||
expected = cv.goodFeaturesToTrack(in_mat, max_corners, quality_lvl,
|
||||
min_distance, mask=None,
|
||||
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = GGoodFeatures.on(g_in, max_corners, quality_lvl,
|
||||
min_distance, block_sz, use_harris_detector, k)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
pkg = cv.gapi.kernels(GGoodFeaturesImpl)
|
||||
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
# NB: OpenCV & G-API have different output types.
|
||||
# OpenCV - numpy array with shape (num_points, 1, 2)
|
||||
# G-API - list of tuples with size - num_points
|
||||
# Comparison
|
||||
self.assertEqual(0.0, cv.norm(expected.flatten(),
|
||||
np.array(actual, dtype=np.float32).flatten(), cv.NORM_INF))
|
||||
|
||||
|
||||
def test_invalid_op(self):
|
||||
# NB: Empty input types list
|
||||
with self.assertRaises(Exception): create_op(in_types=[], out_types=[cv.GMat])
|
||||
# NB: Empty output types list
|
||||
with self.assertRaises(Exception): create_op(in_types=[cv.GMat], out_types=[])
|
||||
|
||||
# Invalid output types
|
||||
with self.assertRaises(Exception): create_op(in_types=[cv.GMat], out_types=[int])
|
||||
with self.assertRaises(Exception): create_op(in_types=[cv.GMat], out_types=[cv.GMat, int])
|
||||
with self.assertRaises(Exception): create_op(in_types=[cv.GMat], out_types=[str, cv.GScalar])
|
||||
|
||||
|
||||
def test_invalid_op_input(self):
|
||||
# NB: Check GMat/GScalar
|
||||
with self.assertRaises(Exception): create_op([cv.GMat] , [cv.GScalar]).on(cv.GScalar())
|
||||
with self.assertRaises(Exception): create_op([cv.GScalar], [cv.GScalar]).on(cv.GMat())
|
||||
|
||||
# NB: Check GOpaque
|
||||
op = create_op([cv.GOpaque.Rect], [cv.GMat])
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Bool())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Int())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Double())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Float())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.String())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Point())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Point2f())
|
||||
with self.assertRaises(Exception): op.on(cv.GOpaque.Size())
|
||||
|
||||
# NB: Check GArray
|
||||
op = create_op([cv.GArray.Rect], [cv.GMat])
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Bool())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Int())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Double())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Float())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.String())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Point())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Point2f())
|
||||
with self.assertRaises(Exception): op.on(cv.GArray.Size())
|
||||
|
||||
# Check other possible invalid options
|
||||
with self.assertRaises(Exception): op.on(cv.GMat())
|
||||
with self.assertRaises(Exception): op.on(cv.GScalar())
|
||||
|
||||
with self.assertRaises(Exception): op.on(1)
|
||||
with self.assertRaises(Exception): op.on('foo')
|
||||
with self.assertRaises(Exception): op.on(False)
|
||||
|
||||
with self.assertRaises(Exception): create_op([cv.GMat, int], [cv.GMat]).on(cv.GMat(), 'foo')
|
||||
with self.assertRaises(Exception): create_op([cv.GMat, int], [cv.GMat]).on(cv.GMat())
|
||||
|
||||
|
||||
def test_state_in_class(self):
|
||||
@cv.gapi.op('custom.sum', in_types=[cv.GArray.Int], out_types=[cv.GOpaque.Int])
|
||||
class GSum:
|
||||
@staticmethod
|
||||
def outMeta(arr_desc):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GSum)
|
||||
class GSumImpl:
|
||||
last_result = 0
|
||||
|
||||
@staticmethod
|
||||
def run(arr):
|
||||
GSumImpl.last_result = sum(arr)
|
||||
return GSumImpl.last_result
|
||||
|
||||
|
||||
g_in = cv.GArray.Int()
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(GSum.on(g_in)))
|
||||
|
||||
s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl)))
|
||||
self.assertEqual(10, s)
|
||||
|
||||
s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl)))
|
||||
self.assertEqual(18, s)
|
||||
|
||||
self.assertEqual(18, GSumImpl.last_result)
|
||||
|
||||
|
||||
def test_opaq_with_custom_type(self):
|
||||
@cv.gapi.op('custom.op', in_types=[cv.GOpaque.Any, cv.GOpaque.String], out_types=[cv.GOpaque.Any])
|
||||
class GLookUp:
|
||||
@staticmethod
|
||||
def outMeta(opaq_desc0, opaq_desc1):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
@cv.gapi.kernel(GLookUp)
|
||||
class GLookUpImpl:
|
||||
@staticmethod
|
||||
def run(table, key):
|
||||
return table[key]
|
||||
|
||||
|
||||
g_table = cv.GOpaque.Any()
|
||||
g_key = cv.GOpaque.String()
|
||||
g_out = GLookUp.on(g_table, g_key)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_table, g_key), cv.GOut(g_out))
|
||||
|
||||
table = {
|
||||
'int': 42,
|
||||
'str': 'hello, world!',
|
||||
'tuple': (42, 42)
|
||||
}
|
||||
|
||||
out = comp.apply(cv.gin(table, 'int'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
||||
self.assertEqual(42, out)
|
||||
|
||||
out = comp.apply(cv.gin(table, 'str'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
||||
self.assertEqual('hello, world!', out)
|
||||
|
||||
out = comp.apply(cv.gin(table, 'tuple'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
||||
self.assertEqual((42, 42), out)
|
||||
|
||||
|
||||
def test_array_with_custom_type(self):
|
||||
@cv.gapi.op('custom.op', in_types=[cv.GArray.Any, cv.GArray.Any], out_types=[cv.GArray.Any])
|
||||
class GConcat:
|
||||
@staticmethod
|
||||
def outMeta(arr_desc0, arr_desc1):
|
||||
return cv.empty_array_desc()
|
||||
|
||||
@cv.gapi.kernel(GConcat)
|
||||
class GConcatImpl:
|
||||
@staticmethod
|
||||
def run(arr0, arr1):
|
||||
return arr0 + arr1
|
||||
|
||||
g_arr0 = cv.GArray.Any()
|
||||
g_arr1 = cv.GArray.Any()
|
||||
g_out = GConcat.on(g_arr0, g_arr1)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_arr0, g_arr1), cv.GOut(g_out))
|
||||
|
||||
arr0 = ((2, 2), 2.0)
|
||||
arr1 = (3, 'str')
|
||||
|
||||
out = comp.apply(cv.gin(arr0, arr1),
|
||||
args=cv.gapi.compile_args(cv.gapi.kernels(GConcatImpl)))
|
||||
|
||||
self.assertEqual(arr0 + arr1, out)
|
||||
|
||||
|
||||
def test_raise_in_kernel(self):
|
||||
@cv.gapi.op('custom.op', in_types=[cv.GMat, cv.GMat], out_types=[cv.GMat])
|
||||
class GAdd:
|
||||
@staticmethod
|
||||
def outMeta(desc0, desc1):
|
||||
return desc0
|
||||
|
||||
@cv.gapi.kernel(GAdd)
|
||||
class GAddImpl:
|
||||
@staticmethod
|
||||
def run(img0, img1):
|
||||
raise Exception('Error')
|
||||
return img0 + img1
|
||||
|
||||
g_in0 = cv.GMat()
|
||||
g_in1 = cv.GMat()
|
||||
g_out = GAdd.on(g_in0, g_in1)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in0, g_in1), cv.GOut(g_out))
|
||||
|
||||
img0 = np.array([1, 2, 3])
|
||||
img1 = np.array([1, 2, 3])
|
||||
|
||||
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
||||
args=cv.gapi.compile_args(
|
||||
cv.gapi.kernels(GAddImpl)))
|
||||
|
||||
|
||||
def test_raise_in_outMeta(self):
|
||||
@cv.gapi.op('custom.op', in_types=[cv.GMat, cv.GMat], out_types=[cv.GMat])
|
||||
class GAdd:
|
||||
@staticmethod
|
||||
def outMeta(desc0, desc1):
|
||||
raise NotImplementedError("outMeta isn't implemented")
|
||||
|
||||
@cv.gapi.kernel(GAdd)
|
||||
class GAddImpl:
|
||||
@staticmethod
|
||||
def run(img0, img1):
|
||||
return img0 + img1
|
||||
|
||||
g_in0 = cv.GMat()
|
||||
g_in1 = cv.GMat()
|
||||
g_out = GAdd.on(g_in0, g_in1)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in0, g_in1), cv.GOut(g_out))
|
||||
|
||||
img0 = np.array([1, 2, 3])
|
||||
img1 = np.array([1, 2, 3])
|
||||
|
||||
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
||||
args=cv.gapi.compile_args(
|
||||
cv.gapi.kernels(GAddImpl)))
|
||||
|
||||
|
||||
def test_invalid_outMeta(self):
|
||||
@cv.gapi.op('custom.op', in_types=[cv.GMat, cv.GMat], out_types=[cv.GMat])
|
||||
class GAdd:
|
||||
@staticmethod
|
||||
def outMeta(desc0, desc1):
|
||||
# Invalid outMeta
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
@cv.gapi.kernel(GAdd)
|
||||
class GAddImpl:
|
||||
@staticmethod
|
||||
def run(img0, img1):
|
||||
return img0 + img1
|
||||
|
||||
g_in0 = cv.GMat()
|
||||
g_in1 = cv.GMat()
|
||||
g_out = GAdd.on(g_in0, g_in1)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_in0, g_in1), cv.GOut(g_out))
|
||||
|
||||
img0 = np.array([1, 2, 3])
|
||||
img1 = np.array([1, 2, 3])
|
||||
|
||||
# FIXME: Cause Bad variant access.
|
||||
# Need to provide more descriptive error message.
|
||||
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
||||
args=cv.gapi.compile_args(
|
||||
cv.gapi.kernels(GAddImpl)))
|
||||
|
||||
def test_pipeline_with_custom_kernels(self):
|
||||
@cv.gapi.op('custom.resize', in_types=[cv.GMat, tuple], out_types=[cv.GMat])
|
||||
class GResize:
|
||||
@staticmethod
|
||||
def outMeta(desc, size):
|
||||
return desc.withSize(size)
|
||||
|
||||
@cv.gapi.kernel(GResize)
|
||||
class GResizeImpl:
|
||||
@staticmethod
|
||||
def run(img, size):
|
||||
return cv.resize(img, size)
|
||||
|
||||
@cv.gapi.op('custom.transpose', in_types=[cv.GMat, tuple], out_types=[cv.GMat])
|
||||
class GTranspose:
|
||||
@staticmethod
|
||||
def outMeta(desc, order):
|
||||
return desc
|
||||
|
||||
@cv.gapi.kernel(GTranspose)
|
||||
class GTransposeImpl:
|
||||
@staticmethod
|
||||
def run(img, order):
|
||||
return np.transpose(img, order)
|
||||
|
||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||
img = cv.imread(img_path)
|
||||
size = (32, 32)
|
||||
order = (1, 0, 2)
|
||||
|
||||
# Dummy pipeline just to validate this case:
|
||||
# gapi -> custom -> custom -> gapi
|
||||
|
||||
# OpenCV
|
||||
expected = cv.cvtColor(img, cv.COLOR_BGR2RGB)
|
||||
expected = cv.resize(expected, size)
|
||||
expected = np.transpose(expected, order)
|
||||
expected = cv.mean(expected)
|
||||
|
||||
# G-API
|
||||
g_bgr = cv.GMat()
|
||||
g_rgb = cv.gapi.BGR2RGB(g_bgr)
|
||||
g_resized = GResize.on(g_rgb, size)
|
||||
g_transposed = GTranspose.on(g_resized, order)
|
||||
g_mean = cv.gapi.mean(g_transposed)
|
||||
|
||||
comp = cv.GComputation(cv.GIn(g_bgr), cv.GOut(g_mean))
|
||||
actual = comp.apply(cv.gin(img), args=cv.gapi.compile_args(
|
||||
cv.gapi.kernels(GResizeImpl, GTransposeImpl)))
|
||||
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
|
||||
class CounterState:
|
||||
def __init__(self):
|
||||
self.counter = 0
|
||||
|
||||
|
||||
@cv.gapi.op('stateful_counter',
|
||||
in_types=[cv.GOpaque.Int],
|
||||
out_types=[cv.GOpaque.Int])
|
||||
class GStatefulCounter:
|
||||
"""Accumulates state counter on every call"""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
|
||||
@cv.gapi.kernel(GStatefulCounter)
|
||||
class GStatefulCounterImpl:
|
||||
"""Implementation for GStatefulCounter operation."""
|
||||
|
||||
@staticmethod
|
||||
def setup(desc):
|
||||
return CounterState()
|
||||
|
||||
@staticmethod
|
||||
def run(value, state):
|
||||
state.counter += value
|
||||
return state.counter
|
||||
|
||||
|
||||
class SumState:
|
||||
def __init__(self):
|
||||
self.sum = 0
|
||||
|
||||
|
||||
@cv.gapi.op('stateful_sum',
|
||||
in_types=[cv.GOpaque.Int, cv.GOpaque.Int],
|
||||
out_types=[cv.GOpaque.Int])
|
||||
class GStatefulSum:
|
||||
"""Accumulates sum on every call"""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(lhs_desc, rhs_desc):
|
||||
return cv.empty_gopaque_desc()
|
||||
|
||||
|
||||
class gapi_sample_pipelines(NewOpenCVTests):
|
||||
def test_stateful_kernel_single_instance(self):
|
||||
g_in = cv.GOpaque.Int()
|
||||
g_out = GStatefulCounter.on(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
pkg = cv.gapi.kernels(GStatefulCounterImpl)
|
||||
|
||||
nums = [i for i in range(10)]
|
||||
acc = 0
|
||||
for v in nums:
|
||||
acc = comp.apply(cv.gin(v), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
self.assertEqual(sum(nums), acc)
|
||||
|
||||
|
||||
def test_stateful_kernel_multiple_instances(self):
|
||||
# NB: Every counter has his own independent state.
|
||||
g_in = cv.GOpaque.Int()
|
||||
g_out0 = GStatefulCounter.on(g_in)
|
||||
g_out1 = GStatefulCounter.on(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out0, g_out1))
|
||||
pkg = cv.gapi.kernels(GStatefulCounterImpl)
|
||||
|
||||
nums = [i for i in range(10)]
|
||||
acc0 = acc1 = 0
|
||||
for v in nums:
|
||||
acc0, acc1 = comp.apply(cv.gin(v), args=cv.gapi.compile_args(pkg))
|
||||
|
||||
ref = sum(nums)
|
||||
self.assertEqual(ref, acc0)
|
||||
self.assertEqual(ref, acc1)
|
||||
|
||||
|
||||
def test_stateful_throw_setup(self):
|
||||
@cv.gapi.kernel(GStatefulCounter)
|
||||
class GThrowStatefulCounterImpl:
|
||||
"""Implementation for GStatefulCounter operation
|
||||
that throw exception in setup method"""
|
||||
|
||||
@staticmethod
|
||||
def setup(desc):
|
||||
raise Exception('Throw from setup method')
|
||||
|
||||
@staticmethod
|
||||
def run(value, state):
|
||||
raise Exception('Unreachable')
|
||||
|
||||
g_in = cv.GOpaque.Int()
|
||||
g_out = GStatefulCounter.on(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
pkg = cv.gapi.kernels(GThrowStatefulCounterImpl)
|
||||
|
||||
with self.assertRaises(Exception): comp.apply(cv.gin(42),
|
||||
args=cv.gapi.compile_args(pkg))
|
||||
|
||||
|
||||
def test_stateful_reset(self):
|
||||
g_in = cv.GOpaque.Int()
|
||||
g_out = GStatefulCounter.on(g_in)
|
||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
pkg = cv.gapi.kernels(GStatefulCounterImpl)
|
||||
|
||||
cc = comp.compileStreaming(args=cv.gapi.compile_args(pkg))
|
||||
|
||||
cc.setSource(cv.gin(1))
|
||||
cc.start()
|
||||
for i in range(1, 10):
|
||||
_, actual = cc.pull()
|
||||
self.assertEqual(i, actual)
|
||||
cc.stop()
|
||||
|
||||
cc.setSource(cv.gin(2))
|
||||
cc.start()
|
||||
for i in range(2, 10, 2):
|
||||
_, actual = cc.pull()
|
||||
self.assertEqual(i, actual)
|
||||
cc.stop()
|
||||
|
||||
|
||||
def test_stateful_multiple_inputs(self):
|
||||
@cv.gapi.kernel(GStatefulSum)
|
||||
class GStatefulSumImpl:
|
||||
"""Implementation for GStatefulCounter operation."""
|
||||
|
||||
@staticmethod
|
||||
def setup(lhs_desc, rhs_desc):
|
||||
return SumState()
|
||||
|
||||
@staticmethod
|
||||
def run(lhs, rhs, state):
|
||||
state.sum+= lhs + rhs
|
||||
return state.sum
|
||||
|
||||
|
||||
g_in1 = cv.GOpaque.Int()
|
||||
g_in2 = cv.GOpaque.Int()
|
||||
g_out = GStatefulSum.on(g_in1, g_in2)
|
||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
pkg = cv.gapi.kernels(GStatefulSumImpl)
|
||||
|
||||
lhs_list = [1, 10, 15]
|
||||
rhs_list = [2, 14, 32]
|
||||
|
||||
ref_out = 0
|
||||
for lhs, rhs in zip(lhs_list, rhs_list):
|
||||
ref_out += lhs + rhs
|
||||
gapi_out = comp.apply(cv.gin(lhs, rhs), cv.gapi.compile_args(pkg))
|
||||
self.assertEqual(ref_out, gapi_out)
|
||||
|
||||
|
||||
def test_stateful_multiple_inputs_throw(self):
|
||||
@cv.gapi.kernel(GStatefulSum)
|
||||
class GStatefulSumImplIncorrect:
|
||||
"""Incorrect implementation for GStatefulCounter operation."""
|
||||
|
||||
# NB: setup methods is intentionally
|
||||
# incorrect - accepts one meta arg instead of two
|
||||
@staticmethod
|
||||
def setup(desc):
|
||||
return SumState()
|
||||
|
||||
@staticmethod
|
||||
def run(lhs, rhs, state):
|
||||
state.sum+= lhs + rhs
|
||||
return state.sum
|
||||
|
||||
|
||||
g_in1 = cv.GOpaque.Int()
|
||||
g_in2 = cv.GOpaque.Int()
|
||||
g_out = GStatefulSum.on(g_in1, g_in2)
|
||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
pkg = cv.gapi.kernels(GStatefulSumImplIncorrect)
|
||||
|
||||
with self.assertRaises(Exception): comp.apply(cv.gin(42, 42),
|
||||
args=cv.gapi.compile_args(pkg))
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,590 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import time
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
|
||||
@cv.gapi.op('custom.delay', in_types=[cv.GMat], out_types=[cv.GMat])
|
||||
class GDelay:
|
||||
"""Delay for 50 ms."""
|
||||
|
||||
@staticmethod
|
||||
def outMeta(desc):
|
||||
return desc
|
||||
|
||||
|
||||
@cv.gapi.kernel(GDelay)
|
||||
class GDelayImpl:
|
||||
"""Implementation for GDelay operation."""
|
||||
|
||||
@staticmethod
|
||||
def run(img):
|
||||
time.sleep(0.05)
|
||||
return img
|
||||
|
||||
|
||||
def convertNV12p2BGR(in_nv12):
|
||||
shape = in_nv12.shape
|
||||
y_height = shape[0] // 3 * 2
|
||||
uv_shape = (shape[0] // 3, shape[1])
|
||||
new_uv_shape = (uv_shape[0], uv_shape[1] // 2, 2)
|
||||
return cv.cvtColorTwoPlane(in_nv12[:y_height, :],
|
||||
in_nv12[ y_height:, :].reshape(new_uv_shape),
|
||||
cv.COLOR_YUV2BGR_NV12)
|
||||
|
||||
|
||||
class test_gapi_streaming(NewOpenCVTests):
|
||||
|
||||
def test_image_input(self):
|
||||
sz = (1280, 720)
|
||||
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||
|
||||
# OpenCV
|
||||
expected = cv.medianBlur(in_mat, 3)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.medianBlur(g_in, 3)
|
||||
c = cv.GComputation(g_in, g_out)
|
||||
ccomp = c.compileStreaming(cv.gapi.descr_of(in_mat))
|
||||
ccomp.setSource(cv.gin(in_mat))
|
||||
ccomp.start()
|
||||
|
||||
_, actual = ccomp.pull()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def test_video_input(self):
|
||||
ksize = 3
|
||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
|
||||
# OpenCV
|
||||
cap = cv.VideoCapture(path)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.medianBlur(g_in, ksize)
|
||||
c = cv.GComputation(g_in, g_out)
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
source = cv.gapi.wip.make_capture_src(path)
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
proc_num_frames = 0
|
||||
while cap.isOpened():
|
||||
has_expected, expected = cap.read()
|
||||
has_actual, actual = ccomp.pull()
|
||||
|
||||
self.assertEqual(has_expected, has_actual)
|
||||
|
||||
if not has_actual:
|
||||
break
|
||||
|
||||
self.assertEqual(0.0, cv.norm(cv.medianBlur(expected, ksize), actual, cv.NORM_INF))
|
||||
|
||||
proc_num_frames += 1
|
||||
if proc_num_frames == max_num_frames:
|
||||
break
|
||||
|
||||
|
||||
def test_video_split3(self):
|
||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
|
||||
# OpenCV
|
||||
cap = cv.VideoCapture(path)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
b, g, r = cv.gapi.split3(g_in)
|
||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
source = cv.gapi.wip.make_capture_src(path)
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
proc_num_frames = 0
|
||||
while cap.isOpened():
|
||||
has_expected, frame = cap.read()
|
||||
has_actual, actual = ccomp.pull()
|
||||
|
||||
self.assertEqual(has_expected, has_actual)
|
||||
|
||||
if not has_actual:
|
||||
break
|
||||
|
||||
expected = cv.split(frame)
|
||||
for e, a in zip(expected, actual):
|
||||
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF))
|
||||
|
||||
proc_num_frames += 1
|
||||
if proc_num_frames == max_num_frames:
|
||||
break
|
||||
|
||||
|
||||
def test_video_add(self):
|
||||
sz = (576, 768, 3)
|
||||
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||
|
||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
|
||||
# OpenCV
|
||||
cap = cv.VideoCapture(path)
|
||||
|
||||
# G-API
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
out = cv.gapi.add(g_in1, g_in2)
|
||||
c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(out))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
source = cv.gapi.wip.make_capture_src(path)
|
||||
ccomp.setSource(cv.gin(source, in_mat))
|
||||
ccomp.start()
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
proc_num_frames = 0
|
||||
while cap.isOpened():
|
||||
has_expected, frame = cap.read()
|
||||
has_actual, actual = ccomp.pull()
|
||||
|
||||
self.assertEqual(has_expected, has_actual)
|
||||
|
||||
if not has_actual:
|
||||
break
|
||||
|
||||
expected = cv.add(frame, in_mat)
|
||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||
|
||||
proc_num_frames += 1
|
||||
if proc_num_frames == max_num_frames:
|
||||
break
|
||||
|
||||
|
||||
def test_video_good_features_to_track(self):
|
||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
|
||||
# NB: goodFeaturesToTrack configuration
|
||||
max_corners = 50
|
||||
quality_lvl = 0.01
|
||||
min_distance = 10
|
||||
block_sz = 3
|
||||
use_harris_detector = True
|
||||
k = 0.04
|
||||
mask = None
|
||||
|
||||
# OpenCV
|
||||
cap = cv.VideoCapture(path)
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_gray = cv.gapi.RGB2Gray(g_in)
|
||||
g_out = cv.gapi.goodFeaturesToTrack(g_gray, max_corners, quality_lvl,
|
||||
min_distance, mask, block_sz, use_harris_detector, k)
|
||||
|
||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
source = cv.gapi.wip.make_capture_src(path)
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
proc_num_frames = 0
|
||||
while cap.isOpened():
|
||||
has_expected, frame = cap.read()
|
||||
has_actual, actual = ccomp.pull()
|
||||
|
||||
self.assertEqual(has_expected, has_actual)
|
||||
|
||||
if not has_actual:
|
||||
break
|
||||
|
||||
# OpenCV
|
||||
frame = cv.cvtColor(frame, cv.COLOR_RGB2GRAY)
|
||||
expected = cv.goodFeaturesToTrack(frame, max_corners, quality_lvl,
|
||||
min_distance, mask=mask,
|
||||
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
||||
for e, a in zip(expected, actual):
|
||||
# NB: OpenCV & G-API have different output shapes:
|
||||
# OpenCV - (num_points, 1, 2)
|
||||
# G-API - (num_points, 2)
|
||||
self.assertEqual(0.0, cv.norm(e.flatten(),
|
||||
np.array(a, np.float32).flatten(),
|
||||
cv.NORM_INF))
|
||||
|
||||
proc_num_frames += 1
|
||||
if proc_num_frames == max_num_frames:
|
||||
break
|
||||
|
||||
|
||||
def test_gapi_streaming_meta(self):
|
||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_ts = cv.gapi.streaming.timestamp(g_in)
|
||||
g_seqno = cv.gapi.streaming.seqNo(g_in)
|
||||
g_seqid = cv.gapi.streaming.seq_id(g_in)
|
||||
|
||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ts, g_seqno, g_seqid))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
source = cv.gapi.wip.make_capture_src(path)
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
curr_frame_number = 0
|
||||
while True:
|
||||
has_frame, (ts, seqno, seqid) = ccomp.pull()
|
||||
|
||||
if not has_frame:
|
||||
break
|
||||
|
||||
self.assertEqual(curr_frame_number, seqno)
|
||||
self.assertEqual(curr_frame_number, seqid)
|
||||
|
||||
curr_frame_number += 1
|
||||
if curr_frame_number == max_num_frames:
|
||||
break
|
||||
|
||||
|
||||
def test_desync(self):
|
||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
|
||||
# G-API
|
||||
g_in = cv.GMat()
|
||||
g_out1 = cv.gapi.copy(g_in)
|
||||
des = cv.gapi.streaming.desync(g_in)
|
||||
g_out2 = GDelay.on(des)
|
||||
|
||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out1, g_out2))
|
||||
|
||||
kernels = cv.gapi.kernels(GDelayImpl)
|
||||
ccomp = c.compileStreaming(args=cv.gapi.compile_args(kernels))
|
||||
source = cv.gapi.wip.make_capture_src(path)
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
# Assert
|
||||
max_num_frames = 50
|
||||
|
||||
out_counter = 0
|
||||
desync_out_counter = 0
|
||||
none_counter = 0
|
||||
while True:
|
||||
has_frame, (out1, out2) = ccomp.pull()
|
||||
if not has_frame:
|
||||
break
|
||||
|
||||
if not out1 is None:
|
||||
out_counter += 1
|
||||
if not out2 is None:
|
||||
desync_out_counter += 1
|
||||
else:
|
||||
none_counter += 1
|
||||
|
||||
if out_counter == max_num_frames:
|
||||
ccomp.stop()
|
||||
break
|
||||
|
||||
self.assertLess(0, out_counter)
|
||||
self.assertLess(desync_out_counter, out_counter)
|
||||
self.assertLess(0, none_counter)
|
||||
|
||||
|
||||
def test_compile_streaming_empty(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
comp.compileStreaming()
|
||||
|
||||
|
||||
def test_compile_streaming_args(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
comp.compileStreaming(cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||
|
||||
|
||||
def test_compile_streaming_descr_of(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming(cv.gapi.descr_of(img))
|
||||
|
||||
|
||||
def test_compile_streaming_descr_of_and_args(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming(cv.gapi.descr_of(img),
|
||||
cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||
|
||||
|
||||
def test_compile_streaming_meta(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming([cv.GMatDesc(cv.CV_8U, 3, (300, 300))])
|
||||
|
||||
|
||||
def test_compile_streaming_meta_and_args(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming([cv.GMatDesc(cv.CV_8U, 3, (300, 300))],
|
||||
cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||
|
||||
|
||||
def get_gst_source(self, gstpipeline):
|
||||
# NB: Skip test in case gstreamer isn't available.
|
||||
try:
|
||||
return cv.gapi.wip.make_gst_src(gstpipeline)
|
||||
except cv.error as e:
|
||||
if str(e).find('Built without GStreamer support!') == -1:
|
||||
raise e
|
||||
else:
|
||||
raise unittest.SkipTest(str(e))
|
||||
|
||||
|
||||
def test_gst_source(self):
|
||||
if not cv.videoio_registry.hasBackend(cv.CAP_GSTREAMER):
|
||||
raise unittest.SkipTest("Backend is not available/disabled: GSTREAMER")
|
||||
|
||||
gstpipeline = """videotestsrc is-live=true pattern=colors num-buffers=10 !
|
||||
videorate ! videoscale ! video/x-raw,width=1920,height=1080,
|
||||
framerate=30/1 ! appsink"""
|
||||
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.copy(g_in)
|
||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
|
||||
source = self.get_gst_source(gstpipeline)
|
||||
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
has_frame, output = ccomp.pull()
|
||||
while has_frame:
|
||||
self.assertTrue(output.size != 0)
|
||||
has_frame, output = ccomp.pull()
|
||||
|
||||
|
||||
def open_VideoCapture_gstreamer(self, gstpipeline):
|
||||
try:
|
||||
cap = cv.VideoCapture(gstpipeline, cv.CAP_GSTREAMER)
|
||||
except Exception as e:
|
||||
raise unittest.SkipTest("Backend GSTREAMER can't open the video; " +
|
||||
"cause: " + str(e))
|
||||
if not cap.isOpened():
|
||||
raise unittest.SkipTest("Backend GSTREAMER can't open the video")
|
||||
return cap
|
||||
|
||||
|
||||
def test_gst_source_accuracy(self):
|
||||
if not cv.videoio_registry.hasBackend(cv.CAP_GSTREAMER):
|
||||
raise unittest.SkipTest("Backend is not available/disabled: GSTREAMER")
|
||||
|
||||
path = self.find_file('highgui/video/big_buck_bunny.avi',
|
||||
[os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
gstpipeline = """filesrc location=""" + path + """ ! decodebin ! videoconvert !
|
||||
videoscale ! video/x-raw,format=NV12 ! appsink"""
|
||||
|
||||
# G-API pipeline
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.copy(g_in)
|
||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
|
||||
# G-API Gst-source
|
||||
source = self.get_gst_source(gstpipeline)
|
||||
ccomp.setSource(cv.gin(source))
|
||||
ccomp.start()
|
||||
|
||||
# OpenCV Gst-source
|
||||
cap = self.open_VideoCapture_gstreamer(gstpipeline)
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
for _ in range(max_num_frames):
|
||||
has_expected, expected = cap.read()
|
||||
has_actual, actual = ccomp.pull()
|
||||
|
||||
self.assertEqual(has_expected, has_actual)
|
||||
|
||||
if not has_expected:
|
||||
break
|
||||
|
||||
self.assertEqual(0.0, cv.norm(convertNV12p2BGR(expected), actual, cv.NORM_INF))
|
||||
|
||||
|
||||
def get_gst_pipeline(self, gstpipeline):
|
||||
# NB: Skip test in case gstreamer isn't available.
|
||||
try:
|
||||
return cv.gapi.wip.GStreamerPipeline(gstpipeline)
|
||||
except cv.error as e:
|
||||
if str(e).find('Built without GStreamer support!') == -1:
|
||||
raise e
|
||||
else:
|
||||
raise unittest.SkipTest(str(e))
|
||||
except SystemError as e:
|
||||
raise unittest.SkipTest(str(e) + ", caused by " + str(e.__cause__))
|
||||
|
||||
|
||||
def test_gst_multiple_sources(self):
|
||||
if not cv.videoio_registry.hasBackend(cv.CAP_GSTREAMER):
|
||||
raise unittest.SkipTest("Backend is not available/disabled: GSTREAMER")
|
||||
|
||||
gstpipeline = """videotestsrc is-live=true pattern=colors num-buffers=10 !
|
||||
videorate ! videoscale !
|
||||
video/x-raw,width=1920,height=1080,framerate=30/1 !
|
||||
appsink name=sink1
|
||||
videotestsrc is-live=true pattern=colors num-buffers=10 !
|
||||
videorate ! videoscale !
|
||||
video/x-raw,width=1920,height=1080,framerate=30/1 !
|
||||
appsink name=sink2"""
|
||||
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
g_out = cv.gapi.add(g_in1, g_in2)
|
||||
c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
|
||||
pp = self.get_gst_pipeline(gstpipeline)
|
||||
src1 = cv.gapi.wip.get_streaming_source(pp, "sink1")
|
||||
src2 = cv.gapi.wip.get_streaming_source(pp, "sink2")
|
||||
|
||||
ccomp.setSource(cv.gin(src1, src2))
|
||||
ccomp.start()
|
||||
|
||||
has_frame, out = ccomp.pull()
|
||||
while has_frame:
|
||||
self.assertTrue(out.size != 0)
|
||||
has_frame, out = ccomp.pull()
|
||||
|
||||
|
||||
def test_gst_multiple_sources_accuracy(self):
|
||||
if not cv.videoio_registry.hasBackend(cv.CAP_GSTREAMER):
|
||||
raise unittest.SkipTest("Backend is not available/disabled: GSTREAMER")
|
||||
|
||||
path = self.find_file('highgui/video/big_buck_bunny.avi',
|
||||
[os.environ['OPENCV_TEST_DATA_PATH']])
|
||||
gstpipeline1 = """filesrc location=""" + path + """ ! decodebin ! videoconvert !
|
||||
videoscale ! video/x-raw,format=NV12 ! appsink"""
|
||||
gstpipeline2 = """filesrc location=""" + path + """ ! decodebin !
|
||||
videoflip method=clockwise ! videoconvert ! videoscale !
|
||||
video/x-raw,format=NV12 ! appsink"""
|
||||
gstpipeline_gapi = gstpipeline1 + ' name=sink1 ' + gstpipeline2 + ' name=sink2'
|
||||
|
||||
# G-API pipeline
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
g_out1 = cv.gapi.copy(g_in1)
|
||||
g_out2 = cv.gapi.copy(g_in2)
|
||||
c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out1, g_out2))
|
||||
|
||||
ccomp = c.compileStreaming()
|
||||
|
||||
# G-API Gst-source
|
||||
pp = self.get_gst_pipeline(gstpipeline_gapi)
|
||||
|
||||
src1 = cv.gapi.wip.get_streaming_source(pp, "sink1")
|
||||
src2 = cv.gapi.wip.get_streaming_source(pp, "sink2")
|
||||
ccomp.setSource(cv.gin(src1, src2))
|
||||
ccomp.start()
|
||||
|
||||
# OpenCV Gst-source
|
||||
cap1 = self.open_VideoCapture_gstreamer(gstpipeline1)
|
||||
cap2 = self.open_VideoCapture_gstreamer(gstpipeline2)
|
||||
|
||||
# Assert
|
||||
max_num_frames = 10
|
||||
for _ in range(max_num_frames):
|
||||
has_expected1, expected1 = cap1.read()
|
||||
has_expected2, expected2 = cap2.read()
|
||||
has_actual, (actual1, actual2) = ccomp.pull()
|
||||
|
||||
self.assertEqual(has_expected1, has_expected2)
|
||||
has_expected = has_expected1 and has_expected2
|
||||
self.assertEqual(has_expected, has_actual)
|
||||
|
||||
if not has_expected:
|
||||
break
|
||||
|
||||
self.assertEqual(0.0, cv.norm(convertNV12p2BGR(expected1), actual1, cv.NORM_INF))
|
||||
self.assertEqual(0.0, cv.norm(convertNV12p2BGR(expected2), actual2, cv.NORM_INF))
|
||||
|
||||
def test_python_custom_stream_source(self):
|
||||
class MySource:
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
|
||||
def pull(self):
|
||||
if self.count >= 3:
|
||||
return None
|
||||
self.count += 1
|
||||
return np.ones((10, 10, 3), np.uint8) * self.count
|
||||
|
||||
def descr_of(self):
|
||||
return np.zeros((10, 10, 3), np.uint8)
|
||||
|
||||
g_in = cv.GMat()
|
||||
g_out = cv.gapi.copy(g_in)
|
||||
c = cv.GComputation(g_in, g_out)
|
||||
|
||||
comp = c.compileStreaming()
|
||||
|
||||
src = cv.gapi.wip.make_py_src(MySource())
|
||||
comp.setSource([src])
|
||||
comp.start()
|
||||
|
||||
frames = []
|
||||
while True:
|
||||
has_frame, frame = comp.pull()
|
||||
if not has_frame:
|
||||
break
|
||||
frames.append(frame)
|
||||
|
||||
self.assertEqual(len(frames), 3)
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from tests_common import NewOpenCVTests
|
||||
|
||||
|
||||
try:
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
raise unittest.SkipTest('Python 2.x is not supported')
|
||||
|
||||
class gapi_types_test(NewOpenCVTests):
|
||||
|
||||
def test_garray_type(self):
|
||||
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_INT64 , cv.gapi.CV_UINT64,
|
||||
cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT , cv.gapi.CV_STRING, cv.gapi.CV_POINT ,
|
||||
cv.gapi.CV_POINT2F, cv.gapi.CV_POINT3F, cv.gapi.CV_SIZE , cv.gapi.CV_RECT ,
|
||||
cv.gapi.CV_SCALAR , cv.gapi.CV_MAT , cv.gapi.CV_GMAT]
|
||||
|
||||
for t in types:
|
||||
g_array = cv.GArrayT(t)
|
||||
self.assertEqual(t, g_array.type())
|
||||
|
||||
|
||||
def test_gopaque_type(self):
|
||||
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_INT64 , cv.gapi.CV_UINT64,
|
||||
cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT , cv.gapi.CV_STRING, cv.gapi.CV_POINT ,
|
||||
cv.gapi.CV_POINT2F, cv.gapi.CV_POINT3F, cv.gapi.CV_SIZE , cv.gapi.CV_RECT]
|
||||
|
||||
for t in types:
|
||||
g_opaque = cv.GOpaqueT(t)
|
||||
self.assertEqual(t, g_opaque.type())
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
class TestSkip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('Skip tests: ' + message)
|
||||
|
||||
def test_skip():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
Reference in New Issue
Block a user