mirror of https://github.com/opencv/opencv.git
commit
e6171d17f8
40 changed files with 705 additions and 404 deletions
@ -1,199 +0,0 @@ |
|||||||
# ----- Find Matlab/Octave ----- |
|
||||||
# |
|
||||||
# OpenCVFindMatlab.cmake attempts to locate the install path of Matlab in order |
|
||||||
# to extract the mex headers, libraries and shell scripts. If found |
|
||||||
# successfully, the following variables will be defined |
|
||||||
# |
|
||||||
# MATLAB_FOUND: true/false |
|
||||||
# MATLAB_ROOT_DIR: Root of Matlab installation |
|
||||||
# MATLAB_BIN: The main Matlab "executable" (shell script) |
|
||||||
# MATLAB_MEX_SCRIPT: The mex script used to compile mex files |
|
||||||
# MATLAB_INCLUDE_DIRS:Path to "mex.h" |
|
||||||
# MATLAB_LIBRARY_DIRS:Path to mex and matrix libraries |
|
||||||
# MATLAB_LIBRARIES: The Matlab libs, usually mx, mex, mat |
|
||||||
# MATLAB_MEXEXT: The mex library extension. It will be one of: |
|
||||||
# mexwin32, mexwin64, mexglx, mexa64, mexmac, |
|
||||||
# mexmaci, mexmaci64, mexsol, mexs64 |
|
||||||
# MATLAB_ARCH: The installation architecture. It is **usually** |
|
||||||
# the MEXEXT with the preceding "mex" removed, |
|
||||||
# though it's different for linux distros. |
|
||||||
# |
|
||||||
# There doesn't appear to be an elegant way to detect all versions of Matlab |
|
||||||
# across different platforms. If you know the matlab path and want to avoid |
|
||||||
# the search, you can define the path to the Matlab root when invoking cmake: |
|
||||||
# |
|
||||||
# cmake -DMATLAB_ROOT_DIR='/PATH/TO/ROOT_DIR' .. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ----- set_library_presuffix ----- |
|
||||||
# |
|
||||||
# Matlab tends to use some non-standard prefixes and suffixes on its libraries. |
|
||||||
# For example, libmx.dll on Windows (Windows does not add prefixes) and |
|
||||||
# mkl.dylib on OS X (OS X uses "lib" prefixes). |
|
||||||
# On some versions of Windows the .dll suffix also appears to not be checked. |
|
||||||
# |
|
||||||
# This function modifies the library prefixes and suffixes used by |
|
||||||
# find_library when finding Matlab libraries. It does not affect scopes |
|
||||||
# outside of this file. |
|
||||||
function(set_libarch_prefix_suffix) |
|
||||||
if (UNIX AND NOT APPLE) |
|
||||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE) |
|
||||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a" PARENT_SCOPE) |
|
||||||
elseif (APPLE) |
|
||||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE) |
|
||||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".a" PARENT_SCOPE) |
|
||||||
elseif (WIN32) |
|
||||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE) |
|
||||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll" PARENT_SCOPE) |
|
||||||
endif() |
|
||||||
endfunction() |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ----- locate_matlab_root ----- |
|
||||||
# |
|
||||||
# Attempt to find the path to the Matlab installation. If successful, sets |
|
||||||
# the absolute path in the variable MATLAB_ROOT_DIR |
|
||||||
function(locate_matlab_root) |
|
||||||
|
|
||||||
# --- UNIX/APPLE --- |
|
||||||
if (UNIX) |
|
||||||
# possible root locations, in order of likelihood |
|
||||||
set(SEARCH_DIRS_ /Applications /usr/local /opt/local /usr /opt) |
|
||||||
foreach (DIR_ ${SEARCH_DIRS_}) |
|
||||||
file(GLOB MATLAB_ROOT_DIR_ ${DIR_}/MATLAB/R* ${DIR_}/MATLAB_R*) |
|
||||||
if (MATLAB_ROOT_DIR_) |
|
||||||
# sort in order from highest to lowest |
|
||||||
# normally it's in the format MATLAB_R[20XX][A/B] |
|
||||||
# TODO: numerical rather than lexicographic sort. However, |
|
||||||
# CMake does not support floating-point MATH(EXPR ...) at this time. |
|
||||||
list(SORT MATLAB_ROOT_DIR_) |
|
||||||
list(REVERSE MATLAB_ROOT_DIR_) |
|
||||||
list(GET MATLAB_ROOT_DIR_ 0 MATLAB_ROOT_DIR_) |
|
||||||
set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE) |
|
||||||
return() |
|
||||||
endif() |
|
||||||
endforeach() |
|
||||||
|
|
||||||
# --- WINDOWS --- |
|
||||||
elseif (WIN32) |
|
||||||
# 1. search the path environment variable |
|
||||||
find_program(MATLAB_ROOT_DIR_ matlab PATHS ENV PATH) |
|
||||||
if (MATLAB_ROOT_DIR_) |
|
||||||
# get the root directory from the full path |
|
||||||
# /path/to/matlab/rootdir/bin/matlab.exe |
|
||||||
get_filename_component(MATLAB_ROOT_DIR_ ${MATLAB_ROOT_DIR_} PATH) |
|
||||||
get_filename_component(MATLAB_ROOT_DIR_ ${MATLAB_ROOT_DIR_} PATH) |
|
||||||
set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE) |
|
||||||
return() |
|
||||||
endif() |
|
||||||
|
|
||||||
# 2. search the registry |
|
||||||
# determine the available Matlab versions |
|
||||||
set(REG_EXTENSION_ "SOFTWARE\\Mathworks\\MATLAB") |
|
||||||
set(REG_ROOTS_ "HKEY_LOCAL_MACHINE" "HKEY_CURRENT_USER") |
|
||||||
foreach(REG_ROOT_ ${REG_ROOTS_}) |
|
||||||
execute_process(COMMAND reg query "${REG_ROOT_}\\${REG_EXTENSION_}" OUTPUT_VARIABLE QUERY_RESPONSE_ ERROR_VARIABLE UNUSED_) |
|
||||||
if (QUERY_RESPONSE_) |
|
||||||
string(REGEX MATCHALL "[0-9]\\.[0-9]" VERSION_STRINGS_ ${QUERY_RESPONSE_}) |
|
||||||
list(APPEND VERSIONS_ ${VERSION_STRINGS_}) |
|
||||||
endif() |
|
||||||
endforeach() |
|
||||||
|
|
||||||
# select the highest version |
|
||||||
list(APPEND VERSIONS_ "0.0") |
|
||||||
list(SORT VERSIONS_) |
|
||||||
list(REVERSE VERSIONS_) |
|
||||||
list(GET VERSIONS_ 0 VERSION_) |
|
||||||
|
|
||||||
# request the MATLABROOT from the registry |
|
||||||
foreach(REG_ROOT_ ${REG_ROOTS_}) |
|
||||||
get_filename_component(QUERY_RESPONSE_ [${REG_ROOT_}\\${REG_EXTENSION_}\\${VERSION_};MATLABROOT] ABSOLUTE) |
|
||||||
if (NOT ${QUERY_RESPONSE_} MATCHES "registry$") |
|
||||||
set(MATLAB_ROOT_DIR ${QUERY_RESPONSE_} PARENT_SCOPE) |
|
||||||
return() |
|
||||||
endif() |
|
||||||
endforeach() |
|
||||||
endif() |
|
||||||
endfunction() |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ----- locate_matlab_components ----- |
|
||||||
# |
|
||||||
# Given a directory MATLAB_ROOT_DIR, attempt to find the Matlab components |
|
||||||
# (include directory and libraries) under the root. If everything is found, |
|
||||||
# sets the variable MATLAB_FOUND to TRUE |
|
||||||
function(locate_matlab_components MATLAB_ROOT_DIR) |
|
||||||
# get the mex extension |
|
||||||
find_file(MATLAB_MEXEXT_SCRIPT_ NAMES mexext mexext.bat PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH) |
|
||||||
execute_process(COMMAND ${MATLAB_MEXEXT_SCRIPT_} |
|
||||||
OUTPUT_VARIABLE MATLAB_MEXEXT_ |
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE) |
|
||||||
if (NOT MATLAB_MEXEXT_) |
|
||||||
return() |
|
||||||
endif() |
|
||||||
|
|
||||||
# map the mexext to an architecture extension |
|
||||||
set(ARCHITECTURES_ "maci64" "maci" "glnxa64" "glnx64" "sol64" "sola64" "win32" "win64" ) |
|
||||||
foreach(ARCHITECTURE_ ${ARCHITECTURES_}) |
|
||||||
if(EXISTS ${MATLAB_ROOT_DIR}/bin/${ARCHITECTURE_}) |
|
||||||
set(MATLAB_ARCH_ ${ARCHITECTURE_}) |
|
||||||
break() |
|
||||||
endif() |
|
||||||
endforeach() |
|
||||||
|
|
||||||
# get the path to the libraries |
|
||||||
set(MATLAB_LIBRARY_DIRS_ ${MATLAB_ROOT_DIR}/bin/${MATLAB_ARCH_}) |
|
||||||
|
|
||||||
# get the libraries |
|
||||||
set_libarch_prefix_suffix() |
|
||||||
find_library(MATLAB_LIB_MX_ mx PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH) |
|
||||||
find_library(MATLAB_LIB_MEX_ mex PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH) |
|
||||||
find_library(MATLAB_LIB_MAT_ mat PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH) |
|
||||||
set(MATLAB_LIBRARIES_ ${MATLAB_LIB_MX_} ${MATLAB_LIB_MEX_} ${MATLAB_LIB_MAT_}) |
|
||||||
|
|
||||||
# get the include path |
|
||||||
find_path(MATLAB_INCLUDE_DIRS_ mex.h ${MATLAB_ROOT_DIR}/extern/include) |
|
||||||
|
|
||||||
# get the mex shell script |
|
||||||
find_program(MATLAB_MEX_SCRIPT_ NAMES mex mex.bat PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH) |
|
||||||
|
|
||||||
# get the Matlab executable |
|
||||||
find_program(MATLAB_BIN_ NAMES matlab PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH) |
|
||||||
|
|
||||||
# export into parent scope |
|
||||||
if (MATLAB_MEX_SCRIPT_ AND MATLAB_LIBRARIES_ AND MATLAB_INCLUDE_DIRS_) |
|
||||||
set(MATLAB_BIN ${MATLAB_BIN_} PARENT_SCOPE) |
|
||||||
set(MATLAB_MEX_SCRIPT ${MATLAB_MEX_SCRIPT_} PARENT_SCOPE) |
|
||||||
set(MATLAB_INCLUDE_DIRS ${MATLAB_INCLUDE_DIRS_} PARENT_SCOPE) |
|
||||||
set(MATLAB_LIBRARIES ${MATLAB_LIBRARIES_} PARENT_SCOPE) |
|
||||||
set(MATLAB_LIBRARY_DIRS ${MATLAB_LIBRARY_DIRS_} PARENT_SCOPE) |
|
||||||
set(MATLAB_MEXEXT ${MATLAB_MEXEXT_} PARENT_SCOPE) |
|
||||||
set(MATLAB_ARCH ${MATLAB_ARCH_} PARENT_SCOPE) |
|
||||||
endif() |
|
||||||
endfunction() |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------- |
|
||||||
# FIND MATLAB COMPONENTS |
|
||||||
# ---------------------------------------------------------------------------- |
|
||||||
if (NOT MATLAB_FOUND) |
|
||||||
|
|
||||||
# attempt to find the Matlab root folder |
|
||||||
if (NOT MATLAB_ROOT_DIR) |
|
||||||
locate_matlab_root() |
|
||||||
endif() |
|
||||||
|
|
||||||
# given the matlab root folder, find the library locations |
|
||||||
if (MATLAB_ROOT_DIR) |
|
||||||
locate_matlab_components(${MATLAB_ROOT_DIR}) |
|
||||||
endif() |
|
||||||
find_package_handle_standard_args(Matlab DEFAULT_MSG |
|
||||||
MATLAB_MEX_SCRIPT MATLAB_INCLUDE_DIRS |
|
||||||
MATLAB_ROOT_DIR MATLAB_LIBRARIES |
|
||||||
MATLAB_LIBRARY_DIRS MATLAB_MEXEXT |
|
||||||
MATLAB_ARCH MATLAB_BIN) |
|
||||||
endif() |
|
@ -0,0 +1,91 @@ |
|||||||
|
Anisotropic image segmentation by a gradient structure tensor {#tutorial_anisotropic_image_segmentation_by_a_gst} |
||||||
|
========================== |
||||||
|
|
||||||
|
Goal |
||||||
|
---- |
||||||
|
|
||||||
|
In this tutorial you will learn: |
||||||
|
|
||||||
|
- what the gradient structure tensor is |
||||||
|
- how to estimate orientation and coherency of an anisotropic image by a gradient structure tensor |
||||||
|
- how to segment an anisotropic image with a single local orientation by a gradient structure tensor |
||||||
|
|
||||||
|
Theory |
||||||
|
------ |
||||||
|
|
||||||
|
@note The explanation is based on the books @cite jahne2000computer, @cite bigun2006vision and @cite van1995estimators. Good physical explanation of a gradient structure tensor is given in @cite yang1996structure. Also, you can refer to a wikipedia page [Structure tensor]. |
||||||
|
@note A anisotropic image on this page is a real world image. |
||||||
|
|
||||||
|
### What is the gradient structure tensor? |
||||||
|
|
||||||
|
In mathematics, the gradient structure tensor (also referred to as the second-moment matrix, the second order moment tensor, the inertia tensor, etc.) is a matrix derived from the gradient of a function. It summarizes the predominant directions of the gradient in a specified neighborhood of a point, and the degree to which those directions are coherent (coherency). The gradient structure tensor is widely used in image processing and computer vision for 2D/3D image segmentation, motion detection, adaptive filtration, local image features detection, etc. |
||||||
|
|
||||||
|
Important features of anisotropic images include orientation and coherency of a local anisotropy. In this paper we will show how to estimate orientation and coherency, and how to segment an anisotropic image with a single local orientation by a gradient structure tensor. |
||||||
|
|
||||||
|
The gradient structure tensor of an image is a 2x2 symmetric matrix. Eigenvectors of the gradient structure tensor indicate local orientation, whereas eigenvalues give coherency (a measure of anisotropism). |
||||||
|
|
||||||
|
The gradient structure tensor \f$J\f$ of an image \f$Z\f$ can be written as: |
||||||
|
|
||||||
|
\f[J = \begin{bmatrix} |
||||||
|
J_{11} & J_{12} \\ |
||||||
|
J_{12} & J_{22} |
||||||
|
\end{bmatrix}\f] |
||||||
|
|
||||||
|
where \f$J_{11} = M[Z_{x}^{2}]\f$, \f$J_{22} = M[Z_{y}^{2}]\f$, \f$J_{12} = M[Z_{x}Z_{y}]\f$ - components of the tensor, \f$M[]\f$ is a symbol of mathematical expectation (we can consider this operation as averaging in a window w), \f$Z_{x}\f$ and \f$Z_{y}\f$ are partial derivatives of an image \f$Z\f$ with respect to \f$x\f$ and \f$y\f$. |
||||||
|
|
||||||
|
The eigenvalues of the tensor can be found in the below formula: |
||||||
|
\f[\lambda_{1,2} = J_{11} + J_{22} \pm \sqrt{(J_{11} - J_{22})^{2} + 4J_{12}^{2}}\f] |
||||||
|
where \f$\lambda_1\f$ - largest eigenvalue, \f$\lambda_2\f$ - smallest eigenvalue. |
||||||
|
|
||||||
|
### How to estimate orientation and coherency of an anisotropic image by gradient structure tensor? |
||||||
|
|
||||||
|
The orientation of an anisotropic image: |
||||||
|
\f[\alpha = 0.5arctg\frac{2J_{12}}{J_{22} - J_{11}}\f] |
||||||
|
|
||||||
|
Coherency: |
||||||
|
\f[C = \frac{\lambda_1 - \lambda_2}{\lambda_1 + \lambda_2}\f] |
||||||
|
|
||||||
|
The coherency ranges from 0 to 1. For ideal local orientation (\f$\lambda_2\f$ = 0, \f$\lambda_1\f$ > 0) it is one, for an isotropic gray value structure (\f$\lambda_1\f$ = \f$\lambda_2\f$ > 0) it is zero. |
||||||
|
|
||||||
|
Source code |
||||||
|
----------- |
||||||
|
|
||||||
|
You can find source code in the `samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp` of the OpenCV source code library. |
||||||
|
|
||||||
|
@include cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp |
||||||
|
|
||||||
|
Explanation |
||||||
|
----------- |
||||||
|
An anisotropic image segmentation algorithm consists of a gradient structure tensor calculation, an orientation calculation, a coherency calculation and an orientation and coherency thresholding: |
||||||
|
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp main |
||||||
|
|
||||||
|
A function calcGST() calculates orientation and coherency by using a gradient structure tensor. An input parameter w defines a window size: |
||||||
|
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp calcGST |
||||||
|
|
||||||
|
The below code applies a thresholds LowThr and HighThr to image orientation and a threshold C_Thr to image coherency calculated by the previous function. LowThr and HighThr define orientation range: |
||||||
|
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp thresholding |
||||||
|
|
||||||
|
And finally we combine thresholding results: |
||||||
|
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp combining |
||||||
|
|
||||||
|
Result |
||||||
|
------ |
||||||
|
|
||||||
|
Below you can see the real anisotropic image with single direction: |
||||||
|
![Anisotropic image with the single direction](images/gst_input.jpg) |
||||||
|
|
||||||
|
Below you can see the orientation and coherency of the anisotropic image: |
||||||
|
![Orientation](images/gst_orientation.jpg) |
||||||
|
![Coherency](images/gst_coherency.jpg) |
||||||
|
|
||||||
|
Below you can see the segmentation result: |
||||||
|
![Segmentation result](images/gst_result.jpg) |
||||||
|
|
||||||
|
The result has been computed with w = 52, C_Thr = 0.43, LowThr = 35, HighThr = 57. We can see that the algorithm selected only the areas with one single direction. |
||||||
|
|
||||||
|
References |
||||||
|
------ |
||||||
|
- [Structure tensor] - structure tensor description on the wikipedia |
||||||
|
|
||||||
|
<!-- invisible references list --> |
||||||
|
[Structure tensor]: https://en.wikipedia.org/wiki/Structure_tensor |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,182 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
import os |
||||||
|
import cv2 as cv |
||||||
|
import numpy as np |
||||||
|
|
||||||
|
from tests_common import NewOpenCVTests, unittest |
||||||
|
|
||||||
|
def normAssert(test, a, b, lInf=1e-5): |
||||||
|
test.assertLess(np.max(np.abs(a - b)), lInf) |
||||||
|
|
||||||
|
def inter_area(box1, box2): |
||||||
|
x_min, x_max = max(box1[0], box2[0]), min(box1[2], box2[2]) |
||||||
|
y_min, y_max = max(box1[1], box2[1]), min(box1[3], box2[3]) |
||||||
|
return (x_max - x_min) * (y_max - y_min) |
||||||
|
|
||||||
|
def area(box): |
||||||
|
return (box[2] - box[0]) * (box[3] - box[1]) |
||||||
|
|
||||||
|
def box2str(box): |
||||||
|
left, top = box[0], box[1] |
||||||
|
width, height = box[2] - left, box[3] - top |
||||||
|
return '[%f x %f from (%f, %f)]' % (width, height, left, top) |
||||||
|
|
||||||
|
def normAssertDetections(test, ref, out, confThreshold=0.0, scores_diff=1e-5, boxes_iou_diff=1e-4): |
||||||
|
ref = np.array(ref, np.float32) |
||||||
|
refClassIds, testClassIds = ref[:, 1], out[:, 1] |
||||||
|
refScores, testScores = ref[:, 2], out[:, 2] |
||||||
|
refBoxes, testBoxes = ref[:, 3:], out[:, 3:] |
||||||
|
|
||||||
|
matchedRefBoxes = [False] * len(refBoxes) |
||||||
|
errMsg = '' |
||||||
|
for i in range(len(refBoxes)): |
||||||
|
testScore = testScores[i] |
||||||
|
if testScore < confThreshold: |
||||||
|
continue |
||||||
|
|
||||||
|
testClassId, testBox = testClassIds[i], testBoxes[i] |
||||||
|
matched = False |
||||||
|
for j in range(len(refBoxes)): |
||||||
|
if (not matchedRefBoxes[j]) and testClassId == refClassIds[j] and \ |
||||||
|
abs(testScore - refScores[j]) < scores_diff: |
||||||
|
interArea = inter_area(testBox, refBoxes[j]) |
||||||
|
iou = interArea / (area(testBox) + area(refBoxes[j]) - interArea) |
||||||
|
if abs(iou - 1.0) < boxes_iou_diff: |
||||||
|
matched = True |
||||||
|
matchedRefBoxes[j] = True |
||||||
|
if not matched: |
||||||
|
errMsg += '\nUnmatched prediction: class %d score %f box %s' % (testClassId, testScore, box2str(testBox)) |
||||||
|
|
||||||
|
for i in range(len(refBoxes)): |
||||||
|
if (not matchedRefBoxes[i]) and refScores[i] > confThreshold: |
||||||
|
errMsg += '\nUnmatched reference: class %d score %f box %s' % (refClassIds[i], refScores[i], box2str(refBoxes[i])) |
||||||
|
if errMsg: |
||||||
|
test.fail(errMsg) |
||||||
|
|
||||||
|
|
||||||
|
# Returns a simple one-layer network created from Caffe's format |
||||||
|
def getSimpleNet(): |
||||||
|
prototxt = """ |
||||||
|
name: "simpleNet" |
||||||
|
input: "data" |
||||||
|
layer { |
||||||
|
type: "Identity" |
||||||
|
name: "testLayer" |
||||||
|
top: "testLayer" |
||||||
|
bottom: "data" |
||||||
|
} |
||||||
|
""" |
||||||
|
return cv.dnn.readNetFromCaffe(bytearray(prototxt, 'utf8')) |
||||||
|
|
||||||
|
|
||||||
|
def testBackendAndTarget(backend, target): |
||||||
|
net = getSimpleNet() |
||||||
|
net.setPreferableBackend(backend) |
||||||
|
net.setPreferableTarget(target) |
||||||
|
inp = np.random.standard_normal([1, 2, 3, 4]).astype(np.float32) |
||||||
|
try: |
||||||
|
net.setInput(inp) |
||||||
|
net.forward() |
||||||
|
except BaseException as e: |
||||||
|
return False |
||||||
|
return True |
||||||
|
|
||||||
|
|
||||||
|
haveInfEngine = testBackendAndTarget(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_CPU) |
||||||
|
dnnBackendsAndTargets = [ |
||||||
|
[cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_CPU], |
||||||
|
] |
||||||
|
|
||||||
|
if haveInfEngine: |
||||||
|
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_CPU]) |
||||||
|
if testBackendAndTarget(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_MYRIAD): |
||||||
|
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_MYRIAD]) |
||||||
|
|
||||||
|
if cv.ocl.haveOpenCL() and cv.ocl.useOpenCL(): |
||||||
|
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_OPENCL]) |
||||||
|
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_OPENCL_FP16]) |
||||||
|
if haveInfEngine: # FIXIT Check Intel iGPU only |
||||||
|
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_OPENCL]) |
||||||
|
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_OPENCL_FP16]) |
||||||
|
|
||||||
|
|
||||||
|
def printParams(backend, target): |
||||||
|
backendNames = { |
||||||
|
cv.dnn.DNN_BACKEND_OPENCV: 'OCV', |
||||||
|
cv.dnn.DNN_BACKEND_INFERENCE_ENGINE: 'DLIE' |
||||||
|
} |
||||||
|
targetNames = { |
||||||
|
cv.dnn.DNN_TARGET_CPU: 'CPU', |
||||||
|
cv.dnn.DNN_TARGET_OPENCL: 'OCL', |
||||||
|
cv.dnn.DNN_TARGET_OPENCL_FP16: 'OCL_FP16', |
||||||
|
cv.dnn.DNN_TARGET_MYRIAD: 'MYRIAD' |
||||||
|
} |
||||||
|
print('%s/%s' % (backendNames[backend], targetNames[target])) |
||||||
|
|
||||||
|
|
||||||
|
class dnn_test(NewOpenCVTests): |
||||||
|
|
||||||
|
def find_dnn_file(self, filename, required=True): |
||||||
|
return self.find_file(filename, [os.environ.get('OPENCV_DNN_TEST_DATA_PATH', os.getcwd())], required=required) |
||||||
|
|
||||||
|
def test_blobFromImage(self): |
||||||
|
np.random.seed(324) |
||||||
|
|
||||||
|
width = 6 |
||||||
|
height = 7 |
||||||
|
scale = 1.0/127.5 |
||||||
|
mean = (10, 20, 30) |
||||||
|
|
||||||
|
# Test arguments names. |
||||||
|
img = np.random.randint(0, 255, [4, 5, 3]).astype(np.uint8) |
||||||
|
blob = cv.dnn.blobFromImage(img, scale, (width, height), mean, True, False) |
||||||
|
blob_args = cv.dnn.blobFromImage(img, scalefactor=scale, size=(width, height), |
||||||
|
mean=mean, swapRB=True, crop=False) |
||||||
|
normAssert(self, blob, blob_args) |
||||||
|
|
||||||
|
# Test values. |
||||||
|
target = cv.resize(img, (width, height), interpolation=cv.INTER_LINEAR) |
||||||
|
target = target.astype(np.float32) |
||||||
|
target = target[:,:,[2, 1, 0]] # BGR2RGB |
||||||
|
target[:,:,0] -= mean[0] |
||||||
|
target[:,:,1] -= mean[1] |
||||||
|
target[:,:,2] -= mean[2] |
||||||
|
target *= scale |
||||||
|
target = target.transpose(2, 0, 1).reshape(1, 3, height, width) # to NCHW |
||||||
|
normAssert(self, blob, target) |
||||||
|
|
||||||
|
|
||||||
|
def test_face_detection(self): |
||||||
|
testdata_required = bool(os.environ.get('OPENCV_DNN_TEST_REQUIRE_TESTDATA', False)) |
||||||
|
proto = self.find_dnn_file('dnn/opencv_face_detector.prototxt2', required=testdata_required) |
||||||
|
model = self.find_dnn_file('dnn/opencv_face_detector.caffemodel', required=testdata_required) |
||||||
|
if proto is None or model is None: |
||||||
|
raise unittest.SkipTest("Missing DNN test files (dnn/opencv_face_detector.{prototxt/caffemodel}). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.") |
||||||
|
|
||||||
|
img = self.get_sample('gpu/lbpcascade/er.png') |
||||||
|
blob = cv.dnn.blobFromImage(img, mean=(104, 177, 123), swapRB=False, crop=False) |
||||||
|
|
||||||
|
ref = [[0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631], |
||||||
|
[0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168], |
||||||
|
[0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290], |
||||||
|
[0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477], |
||||||
|
[0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494], |
||||||
|
[0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801]] |
||||||
|
|
||||||
|
print('\n') |
||||||
|
for backend, target in dnnBackendsAndTargets: |
||||||
|
printParams(backend, target) |
||||||
|
|
||||||
|
net = cv.dnn.readNet(proto, model) |
||||||
|
net.setPreferableBackend(backend) |
||||||
|
net.setPreferableTarget(target) |
||||||
|
net.setInput(blob) |
||||||
|
out = net.forward().reshape(-1, 7) |
||||||
|
|
||||||
|
scoresDiff = 4e-3 if target in [cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD] else 1e-5 |
||||||
|
iouDiff = 2e-2 if target in [cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD] else 1e-4 |
||||||
|
|
||||||
|
normAssertDetections(self, ref, out, 0.5, scoresDiff, iouDiff) |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
NewOpenCVTests.bootstrap() |
Loading…
Reference in new issue