Commit 166ecaed authored by Alexander Alekhin's avatar Alexander Alekhin

Merge remote-tracking branch 'upstream/3.4' into merge-3.4

parents 2080e06f 1810702b
......@@ -252,8 +252,8 @@ OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BL
OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" WITH_CUDA
VISIBLE_IF WITH_CUDA
VERIFY HAVE_NVCUVID)
OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" (NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF NOT WINRT AND NOT CMAKE_CROSSCOMPILING
OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" (NOT CV_DISABLE_OPTIMIZATION AND NOT CMAKE_CROSSCOMPILING)
VISIBLE_IF NOT WINRT
VERIFY HAVE_EIGEN)
OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" (NOT ANDROID)
VISIBLE_IF NOT IOS AND NOT WINRT
......
......@@ -153,14 +153,14 @@ void CvHaarEvaluator::generateFeatures()
{
features.push_back( Feature( offset, false,
x, y, dx*3, dy, -1,
x+dx, y, dx , dy, +3 ) );
x+dx, y, dx , dy, +2 ) );
}
// haar_y3
if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
{
features.push_back( Feature( offset, false,
x, y, dx, dy*3, -1,
x, y+dy, dx, dy, +3 ) );
x, y+dy, dx, dy, +2 ) );
}
if( mode != CvHaarFeatureParams::BASIC )
{
......
......@@ -31,27 +31,33 @@ macro(ocv_lapack_check)
else()
# adding proxy opencv_lapack.h header
set(CBLAS_H_PROXY_PATH ${CMAKE_BINARY_DIR}/opencv_lapack.h)
if((APPLE OR OPENCV_SKIP_LAPACK_EXTERN_C) AND NOT OPENCV_FORCE_LAPACK_EXTERN_C)
set(_lapack_include_str_extern_C "")
set(_lapack_include_str_extern_C_end "")
else()
set(_lapack_include_str_extern_C "extern \"C\" {\n")
set(_lapack_include_str_extern_C_end "}\n")
endif()
set(_lapack_include_str "${_lapack_include_str_extern_C}\#include \"${OPENCV_CBLAS_H_PATH_${_lapack_impl}}\"")
set(_lapack_add_extern_c NOT (APPLE OR OPENCV_SKIP_LAPACK_EXTERN_C) OR OPENCV_FORCE_LAPACK_EXTERN_C)
set(_lapack_content "// This file is auto-generated\n")
if(${_lapack_add_extern_c})
list(APPEND _lapack_content "extern \"C\" {")
endif()
if(NOT OPENCV_SKIP_LAPACK_MSVC_FIX)
list(APPEND _lapack_content "
#ifdef _MSC_VER
#include <complex.h>
#define lapack_complex_float _Fcomplex
#define lapack_complex_double _Dcomplex
#endif
")
endif()
list(APPEND _lapack_content "#include \"${OPENCV_CBLAS_H_PATH_${_lapack_impl}}\"")
if(NOT "${OPENCV_CBLAS_H_PATH_${_lapack_impl}}" STREQUAL "${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}")
set(_lapack_include_str "${_lapack_include_str}\n#include \"${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}\"")
endif()
set(_lapack_include_str "${_lapack_include_str}\n${_lapack_include_str_extern_C_end}")
# update file contents (if required)
set(__content_str "")
if(EXISTS "${CBLAS_H_PROXY_PATH}")
file(READ "${CBLAS_H_PROXY_PATH}" __content_str)
list(APPEND _lapack_content "#include \"${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}\"")
endif()
if(NOT " ${__content_str}" STREQUAL " ${_lapack_include_str}")
file(WRITE "${CBLAS_H_PROXY_PATH}" "${_lapack_include_str}")
if(${_lapack_add_extern_c})
list(APPEND _lapack_content "}")
endif()
string(REPLACE ";" "\n" _lapack_content "${_lapack_content}")
ocv_update_file("${CBLAS_H_PROXY_PATH}" "${_lapack_content}")
try_compile(__VALID_LAPACK
"${OpenCV_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/lapack_check.cpp"
......
......@@ -64,7 +64,7 @@ if(WITH_GTK AND NOT HAVE_QT)
if(WITH_OPENGL AND NOT HAVE_GTK3)
ocv_check_modules(GTKGLEXT gtkglext-1.0)
if(HAVE_GTKGLEXT)
ocv_append_build_options(GTKGLEXT GTHREAD)
ocv_append_build_options(HIGHGUI GTKGLEXT)
endif()
endif()
endif()
......
......@@ -40,19 +40,67 @@ To eliminate this warning remove WITH_CUDA=ON CMake configuration option.
endif(WITH_CUDA)
# --- Eigen ---
if(WITH_EIGEN)
if(WITH_EIGEN AND NOT HAVE_EIGEN)
find_package(Eigen3 QUIET)
if(Eigen3_FOUND)
if(TARGET Eigen3::Eigen)
# Use Eigen3 imported target if possible
list(APPEND OPENCV_LINKER_LIBS Eigen3::Eigen)
set(HAVE_EIGEN 1)
else()
if(DEFINED EIGEN3_INCLUDE_DIRS)
set(EIGEN_INCLUDE_PATH ${EIGEN3_INCLUDE_DIRS})
set(HAVE_EIGEN 1)
elseif(DEFINED EIGEN3_INCLUDE_DIR)
set(EIGEN_INCLUDE_PATH ${EIGEN3_INCLUDE_DIR})
set(HAVE_EIGEN 1)
endif()
endif()
if(HAVE_EIGEN)
if(DEFINED EIGEN3_WORLD_VERSION) # CMake module
set(EIGEN_WORLD_VERSION ${EIGEN3_WORLD_VERSION})
set(EIGEN_MAJOR_VERSION ${EIGEN3_MAJOR_VERSION})
set(EIGEN_MINOR_VERSION ${EIGEN3_MINOR_VERSION})
else() # Eigen config file
set(EIGEN_WORLD_VERSION ${EIGEN3_VERSION_MAJOR})
set(EIGEN_MAJOR_VERSION ${EIGEN3_VERSION_MINOR})
set(EIGEN_MINOR_VERSION ${EIGEN3_VERSION_PATCH})
endif()
endif()
endif()
if(NOT HAVE_EIGEN)
if(NOT EIGEN_INCLUDE_PATH OR NOT EXISTS "${EIGEN_INCLUDE_PATH}")
set(__find_paths "")
set(__find_path_extra_options "")
if(NOT CMAKE_CROSSCOMPILING)
list(APPEND __find_paths /opt)
endif()
if(DEFINED ENV{EIGEN_ROOT})
set(__find_paths "$ENV{EIGEN_ROOT}/include")
list(APPEND __find_path_extra_options NO_DEFAULT_PATH)
else()
set(__find_paths ENV ProgramFiles ENV ProgramW6432)
endif()
find_path(EIGEN_INCLUDE_PATH "Eigen/Core"
PATHS /usr/local /opt /usr $ENV{EIGEN_ROOT}/include ENV ProgramFiles ENV ProgramW6432
PATHS ${__find_paths}
PATH_SUFFIXES include/eigen3 include/eigen2 Eigen/include/eigen3 Eigen/include/eigen2
DOC "The path to Eigen3/Eigen2 headers"
CMAKE_FIND_ROOT_PATH_BOTH)
if(EIGEN_INCLUDE_PATH)
ocv_include_directories(${EIGEN_INCLUDE_PATH})
${__find_path_extra_options}
)
endif()
if(EIGEN_INCLUDE_PATH AND EXISTS "${EIGEN_INCLUDE_PATH}")
ocv_parse_header("${EIGEN_INCLUDE_PATH}/Eigen/src/Core/util/Macros.h" EIGEN_VERSION_LINES EIGEN_WORLD_VERSION EIGEN_MAJOR_VERSION EIGEN_MINOR_VERSION)
set(HAVE_EIGEN 1)
endif()
endif(WITH_EIGEN)
endif()
endif()
if(HAVE_EIGEN)
if(EIGEN_INCLUDE_PATH AND EXISTS "${EIGEN_INCLUDE_PATH}")
ocv_include_directories(SYSTEM ${EIGEN_INCLUDE_PATH})
endif()
endif()
# --- Clp ---
# Ubuntu: sudo apt-get install coinor-libclp-dev coinor-libcoinutils-dev
......
......@@ -209,7 +209,21 @@
hal_id = {inria-00350283},
hal_version = {v1},
}
@article{Collins14
year = {2014},
issn = {0920-5691},
journal = {International Journal of Computer Vision},
volume = {109},
number = {3},
doi = {10.1007/s11263-014-0725-5},
title = {Infinitesimal Plane-Based Pose Estimation},
url = {http://dx.doi.org/10.1007/s11263-014-0725-5},
publisher = {Springer US},
keywords = {Plane; Pose; SfM; PnP; Homography},
author = {Collins, Toby and Bartoli, Adrien},
pages = {252-286},
language = {English}
}
@article{Daniilidis98,
author = {Konstantinos Daniilidis},
title = {Hand-Eye Calibration Using Dual Quaternions},
......
......@@ -21,7 +21,6 @@ train_data, and next 250 samples as test_data. So let's prepare them first.
@code{.py}
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('digits.png')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
......@@ -89,7 +88,6 @@ alphabets directly.
@code{.py}
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# Load the data, converters convert the letter to a number
data= np.loadtxt('letter-recognition.data', dtype= 'float32', delimiter = ',',
......
This diff is collapsed.
#include "precomp.hpp"
#include "ap3p.h"
#include <cmath>
......@@ -154,10 +155,11 @@ ap3p::ap3p(double _fx, double _fy, double _cx, double _cy) {
// worldPoints: The positions of the 3 feature points stored as column vectors
// solutionsR: 4 possible solutions of rotation matrix of the world w.r.t the camera frame
// solutionsT: 4 possible solutions of translation of the world origin w.r.t the camera frame
int ap3p::computePoses(const double featureVectors[3][3],
const double worldPoints[3][3],
int ap3p::computePoses(const double featureVectors[3][4],
const double worldPoints[3][4],
double solutionsR[4][3][3],
double solutionsT[4][3]) {
double solutionsT[4][3],
bool p4p) {
//world point vectors
double w1[3] = {worldPoints[0][0], worldPoints[1][0], worldPoints[2][0]};
......@@ -246,6 +248,13 @@ int ap3p::computePoses(const double featureVectors[3][3],
double b3p[3];
vect_scale((delta / k3b3), b3, b3p);
double X3 = worldPoints[0][3];
double Y3 = worldPoints[1][3];
double Z3 = worldPoints[2][3];
double mu3 = featureVectors[0][3];
double mv3 = featureVectors[1][3];
double reproj_errors[4];
int nb_solutions = 0;
for (int i = 0; i < 4; ++i) {
double ctheta1p = s[i];
......@@ -290,9 +299,29 @@ int ap3p::computePoses(const double featureVectors[3][3],
solutionsR[nb_solutions][1][2] = R[2][1];
solutionsR[nb_solutions][2][2] = R[2][2];
if (p4p) {
double X3p = solutionsR[nb_solutions][0][0] * X3 + solutionsR[nb_solutions][0][1] * Y3 + solutionsR[nb_solutions][0][2] * Z3 + solutionsT[nb_solutions][0];
double Y3p = solutionsR[nb_solutions][1][0] * X3 + solutionsR[nb_solutions][1][1] * Y3 + solutionsR[nb_solutions][1][2] * Z3 + solutionsT[nb_solutions][1];
double Z3p = solutionsR[nb_solutions][2][0] * X3 + solutionsR[nb_solutions][2][1] * Y3 + solutionsR[nb_solutions][2][2] * Z3 + solutionsT[nb_solutions][2];
double mu3p = X3p / Z3p;
double mv3p = Y3p / Z3p;
reproj_errors[nb_solutions] = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
}
nb_solutions++;
}
//sort the solutions
if (p4p) {
for (int i = 1; i < nb_solutions; i++) {
for (int j = i; j > 0 && reproj_errors[j-1] > reproj_errors[j]; j--) {
std::swap(reproj_errors[j], reproj_errors[j-1]);
std::swap(solutionsR[j], solutionsR[j-1]);
std::swap(solutionsT[j], solutionsT[j-1]);
}
}
}
return nb_solutions;
}
......@@ -311,9 +340,10 @@ bool ap3p::solve(cv::Mat &R, cv::Mat &tvec, const cv::Mat &opoints, const cv::Ma
else
extract_points<cv::Point3d, cv::Point2f>(opoints, ipoints, points);
bool result = solve(rotation_matrix, translation, points[0], points[1], points[2], points[3], points[4], points[5],
points[6], points[7], points[8], points[9], points[10], points[11], points[12], points[13],
points[14],
bool result = solve(rotation_matrix, translation,
points[0], points[1], points[2], points[3], points[4],
points[5], points[6], points[7], points[8], points[9],
points[10], points[11], points[12], points[13],points[14],
points[15], points[16], points[17], points[18], points[19]);
cv::Mat(3, 1, CV_64F, translation).copyTo(tvec);
cv::Mat(3, 3, CV_64F, rotation_matrix).copyTo(R);
......@@ -335,10 +365,13 @@ int ap3p::solve(std::vector<cv::Mat> &Rs, std::vector<cv::Mat> &tvecs, const cv:
else
extract_points<cv::Point3d, cv::Point2f>(opoints, ipoints, points);
const bool p4p = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F)) == 4;
int solutions = solve(rotation_matrix, translation,
points[0], points[1], points[2], points[3], points[4],
points[5], points[6], points[7], points[8], points[9],
points[10], points[11], points[12], points[13], points[14]);
points[10], points[11], points[12], points[13], points[14],
points[15], points[16], points[17], points[18], points[19],
p4p);
for (int i = 0; i < solutions; i++) {
cv::Mat R, tvec;
......@@ -353,42 +386,33 @@ int ap3p::solve(std::vector<cv::Mat> &Rs, std::vector<cv::Mat> &tvecs, const cv:
}
bool
ap3p::solve(double R[3][3], double t[3], double mu0, double mv0, double X0, double Y0, double Z0, double mu1,
double mv1,
double X1, double Y1, double Z1, double mu2, double mv2, double X2, double Y2, double Z2, double mu3,
double mv3, double X3, double Y3, double Z3) {
ap3p::solve(double R[3][3], double t[3],
double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2,
double mu3, double mv3, double X3, double Y3, double Z3) {
double Rs[4][3][3], ts[4][3];
int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2);
const bool p4p = true;
int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2, mu3, mv3, X3, Y3, Z3, p4p);
if (n == 0)
return false;
int ns = 0;
double min_reproj = 0;
for (int i = 0; i < n; i++) {
double X3p = Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0];
double Y3p = Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1];
double Z3p = Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2];
double mu3p = cx + fx * X3p / Z3p;
double mv3p = cy + fy * Y3p / Z3p;
double reproj = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
if (i == 0 || min_reproj > reproj) {
ns = i;
min_reproj = reproj;
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
R[i][j] = Rs[ns][i][j];
t[i] = ts[ns][i];
R[i][j] = Rs[0][i][j];
t[i] = ts[0][i];
}
return true;
}
int ap3p::solve(double R[4][3][3], double t[4][3], double mu0, double mv0, double X0, double Y0, double Z0, double mu1,
double mv1, double X1, double Y1, double Z1, double mu2, double mv2, double X2, double Y2, double Z2) {
int ap3p::solve(double R[4][3][3], double t[4][3],
double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2,
double mu3, double mv3, double X3, double Y3, double Z3,
bool p4p) {
double mk0, mk1, mk2;
double norm;
......@@ -413,13 +437,17 @@ int ap3p::solve(double R[4][3][3], double t[4][3], double mu0, double mv0, doubl
mu2 *= mk2;
mv2 *= mk2;
double featureVectors[3][3] = {{mu0, mu1, mu2},
{mv0, mv1, mv2},
{mk0, mk1, mk2}};
double worldPoints[3][3] = {{X0, X1, X2},
{Y0, Y1, Y2},
{Z0, Z1, Z2}};
mu3 = inv_fx * mu3 - cx_fx;
mv3 = inv_fy * mv3 - cy_fy;
double mk3 = 1; //not used
double featureVectors[3][4] = {{mu0, mu1, mu2, mu3},
{mv0, mv1, mv2, mv3},
{mk0, mk1, mk2, mk3}};
double worldPoints[3][4] = {{X0, X1, X2, X3},
{Y0, Y1, Y2, Y3},
{Z0, Z1, Z2, Z3}};
return computePoses(featureVectors, worldPoints, R, t);
return computePoses(featureVectors, worldPoints, R, t, p4p);
}
}
#ifndef P3P_P3P_H
#define P3P_P3P_H
#include "precomp.hpp"
#include <opencv2/core.hpp>
namespace cv {
class ap3p {
......@@ -18,7 +18,7 @@ private:
void extract_points(const cv::Mat &opoints, const cv::Mat &ipoints, std::vector<double> &points) {
points.clear();
int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
points.resize(5*npoints);
points.resize(5*4); //resize vector to fit for p4p case
for (int i = 0; i < npoints; i++) {
points[i * 5] = ipoints.at<IpointType>(i).x * fx + cx;
points[i * 5 + 1] = ipoints.at<IpointType>(i).y * fy + cy;
......@@ -26,6 +26,12 @@ private:
points[i * 5 + 3] = opoints.at<OpointType>(i).y;
points[i * 5 + 4] = opoints.at<OpointType>(i).z;
}
//Fill vectors with unused values for p3p case
for (int i = npoints; i < 4; i++) {
for (int j = 0; j < 5; j++) {
points[i * 5 + j] = 0;
}
}
}
void init_inverse_parameters();
......@@ -45,7 +51,9 @@ public:
int solve(double R[4][3][3], double t[4][3],
double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2);
double mu2, double mv2, double X2, double Y2, double Z2,
double mu3, double mv3, double X3, double Y3, double Z3,
bool p4p);
bool solve(double R[3][3], double t[3],
double mu0, double mv0, double X0, double Y0, double Z0,
......@@ -59,8 +67,8 @@ public:
// worldPoints: Positions of the 3 feature points stored as column vectors
// solutionsR: 4 possible solutions of rotation matrix of the world w.r.t the camera frame
// solutionsT: 4 possible solutions of translation of the world origin w.r.t the camera frame
int computePoses(const double featureVectors[3][3], const double worldPoints[3][3], double solutionsR[4][3][3],
double solutionsT[4][3]);
int computePoses(const double featureVectors[3][4], const double worldPoints[3][4], double solutionsR[4][3][3],
double solutionsT[4][3], bool p4p);
};
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -49,8 +49,10 @@ bool p3p::solve(cv::Mat& R, cv::Mat& tvec, const cv::Mat& opoints, const cv::Mat
else
extract_points<cv::Point3d,cv::Point2f>(opoints, ipoints, points);
bool result = solve(rotation_matrix, translation, points[0], points[1], points[2], points[3], points[4], points[5],
points[6], points[7], points[8], points[9], points[10], points[11], points[12], points[13], points[14],
bool result = solve(rotation_matrix, translation,
points[0], points[1], points[2], points[3], points[4],
points[5], points[6], points[7], points[8], points[9],
points[10], points[11], points[12], points[13], points[14],
points[15], points[16], points[17], points[18], points[19]);
cv::Mat(3, 1, CV_64F, translation).copyTo(tvec);
cv::Mat(3, 3, CV_64F, rotation_matrix).copyTo(R);
......@@ -75,10 +77,13 @@ int p3p::solve(std::vector<cv::Mat>& Rs, std::vector<cv::Mat>& tvecs, const cv::
else
extract_points<cv::Point3d,cv::Point2f>(opoints, ipoints, points);
const bool p4p = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F)) == 4;
int solutions = solve(rotation_matrix, translation,
points[0], points[1], points[2], points[3], points[4],
points[5], points[6], points[7], points[8], points[9],
points[10], points[11], points[12], points[13], points[14]);
points[10], points[11], points[12], points[13], points[14],
points[15], points[16], points[17], points[18], points[19],
p4p);
for (int i = 0; i < solutions; i++) {
cv::Mat R, tvec;
......@@ -100,30 +105,16 @@ bool p3p::solve(double R[3][3], double t[3],
{
double Rs[4][3][3], ts[4][3];
int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2);
const bool p4p = true;
int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2, mu3, mv3, X3, Y3, Z3, p4p);
if (n == 0)
return false;
int ns = 0;
double min_reproj = 0;
for(int i = 0; i < n; i++) {
double X3p = Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0];
double Y3p = Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1];
double Z3p = Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2];
double mu3p = cx + fx * X3p / Z3p;
double mv3p = cy + fy * Y3p / Z3p;
double reproj = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
if (i == 0 || min_reproj > reproj) {
ns = i;
min_reproj = reproj;
}
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++)
R[i][j] = Rs[ns][i][j];
t[i] = ts[ns][i];
R[i][j] = Rs[0][i][j];
t[i] = ts[0][i];
}
return true;
......@@ -132,7 +123,9 @@ bool p3p::solve(double R[3][3], double t[3],
int p3p::solve(double R[4][3][3], double t[4][3],
double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2)
double mu2, double mv2, double X2, double Y2, double Z2,
double mu3, double mv3, double X3, double Y3, double Z3,
bool p4p)
{
double mk0, mk1, mk2;
double norm;
......@@ -152,6 +145,9 @@ int p3p::solve(double R[4][3][3], double t[4][3],
norm = sqrt(mu2 * mu2 + mv2 * mv2 + 1);
mk2 = 1. / norm; mu2 *= mk2; mv2 *= mk2;
mu3 = inv_fx * mu3 - cx_fx;
mv3 = inv_fy * mv3 - cy_fy;
double distances[3];
distances[0] = sqrt( (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2) );
distances[1] = sqrt( (X0 - X2) * (X0 - X2) + (Y0 - Y2) * (Y0 - Y2) + (Z0 - Z2) * (Z0 - Z2) );
......@@ -167,6 +163,7 @@ int p3p::solve(double R[4][3][3], double t[4][3],
int n = solve_for_lengths(lengths, distances, cosines);
int nb_solutions = 0;
double reproj_errors[4];
for(int i = 0; i < n; i++) {
double M_orig[3][3];
......@@ -185,9 +182,29 @@ int p3p::solve(double R[4][3][3], double t[4][3],
if (!align(M_orig, X0, Y0, Z0, X1, Y1, Z1, X2, Y2, Z2, R[nb_solutions], t[nb_solutions]))
continue;
if (p4p) {
double X3p = R[nb_solutions][0][0] * X3 + R[nb_solutions][0][1] * Y3 + R[nb_solutions][0][2] * Z3 + t[nb_solutions][0];
double Y3p = R[nb_solutions][1][0] * X3 + R[nb_solutions][1][1] * Y3 + R[nb_solutions][1][2] * Z3 + t[nb_solutions][1];
double Z3p = R[nb_solutions][2][0] * X3 + R[nb_solutions][2][1] * Y3 + R[nb_solutions][2][2] * Z3 + t[nb_solutions][2];
double mu3p = X3p / Z3p;
double mv3p = Y3p / Z3p;
reproj_errors[nb_solutions] = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
}
nb_solutions++;
}
if (p4p) {
//sort the solutions
for (int i = 1; i < nb_solutions; i++) {
for (int j = i; j > 0 && reproj_errors[j-1] > reproj_errors[j]; j--) {
std::swap(reproj_errors[j], reproj_errors[j-1]);
std::swap(R[j], R[j-1]);
std::swap(t[j], t[j-1]);
}
}
}
return nb_solutions;
}
......
......@@ -15,7 +15,9 @@ class p3p
int solve(double R[4][3][3], double t[4][3],
double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2);
double mu2, double mv2, double X2, double Y2, double Z2,
double mu3, double mv3, double X3, double Y3, double Z3,
bool p4p);
bool solve(double R[3][3], double t[3],
double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1,
......@@ -36,7 +38,7 @@ class p3p
{
points.clear();
int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
points.resize(5*npoints);
points.resize(5*4); //resize vector to fit for p4p case
for(int i = 0; i < npoints; i++)
{
points[i*5] = ipoints.at<IpointType>(i).x*fx + cx;
......@@ -45,6 +47,12 @@ class p3p
points[i*5+3] = opoints.at<OpointType>(i).y;
points[i*5+4] = opoints.at<OpointType>(i).z;
}
//Fill vectors with unused values for p3p case
for (int i = npoints; i < 4; i++) {
for (int j = 0; j < 5; j++) {
points[i * 5 + j] = 0;
}
}
}
void init_inverse_parameters();
int solve_for_lengths(double lengths[4][3], double distances[3], double cosines[3]);
......
This diff is collapsed.
......@@ -188,7 +188,7 @@ enum NormTypes {
norm = \forkthree
{ \| \texttt{src1} \| _{L_2} ^{2} = \sum_I \texttt{src1}(I)^2} {if \(\texttt{normType} = \texttt{NORM_L2SQR}\)}
{ \| \texttt{src1} - \texttt{src2} \| _{L_2} ^{2} = \sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2 }{if \(\texttt{normType} = \texttt{NORM_L2SQR}\) }
{ \left(\frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}}\right)^2 }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2}\) }
{ \left(\frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}}\right)^2 }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2SQR}\) }
\f]
*/
NORM_L2SQR = 5,
......
......@@ -34,11 +34,11 @@ public final class CvType {
public static final int makeType(int depth, int channels) {
if (channels <= 0 || channels >= CV_CN_MAX) {
throw new java.lang.UnsupportedOperationException(
throw new UnsupportedOperationException(
"Channels count should be 1.." + (CV_CN_MAX - 1));
}
if (depth < 0 || depth >= CV_DEPTH_MAX) {
throw new java.lang.UnsupportedOperationException(
throw new UnsupportedOperationException(
"Data type depth should be 0.." + (CV_DEPTH_MAX - 1));
}
return (depth & (CV_DEPTH_MAX - 1)) + ((channels - 1) << CV_CN_SHIFT);
......@@ -103,7 +103,7 @@ public final class CvType {
case CV_64F:
return 8 * channels(type);
default:
throw new java.lang.UnsupportedOperationException(
throw new UnsupportedOperationException(
"Unsupported CvType value: " + type);
}
}
......@@ -136,7 +136,7 @@ public final class CvType {
s = "CV_16F";
break;
default:
throw new java.lang.UnsupportedOperationException(
throw new UnsupportedOperationException(
"Unsupported CvType value: " + type);
}
......
......@@ -816,6 +816,7 @@ CV__DNN_INLINE_NS_BEGIN
* * `*.t7` | `*.net` (Torch, http://torch.ch/)
* * `*.weights` (Darknet, https://pjreddie.com/darknet/)
* * `*.bin` (DLDT, https://software.intel.com/openvino-toolkit)
* * `*.onnx` (ONNX, https://onnx.ai/)
* @param[in] config Text file contains network configuration. It could be a
* file with the following extensions:
* * `*.prototxt` (Caffe, http://caffe.berkeleyvision.org/)
......@@ -864,6 +865,23 @@ CV__DNN_INLINE_NS_BEGIN
*/
CV_EXPORTS_W Net readNetFromONNX(const String &onnxFile);
/** @brief Reads a network model from <a href="https://onnx.ai/">ONNX</a>
* in-memory buffer.
* @param buffer memory address of the first byte of the buffer.
* @param sizeBuffer size of the buffer.
* @returns Network object that ready to do forward, throw an exception
* in failure cases.
*/
CV_EXPORTS Net readNetFromONNX(const char* buffer, size_t sizeBuffer);
/** @brief Reads a network model from <a href="https://onnx.ai/">ONNX</a>
* in-memory buffer.
* @param buffer in-memory buffer that stores the ONNX model bytes.
* @returns Network object that ready to do forward, throw an exception
* in failure cases.
*/
CV_EXPORTS_W Net readNetFromONNX(const std::vector<uchar>& buffer);
/** @brief Creates blob from .pb file.
* @param path to the .pb file with input tensor.
* @returns Mat.
......
......@@ -29,6 +29,8 @@ class BatchNormLayerImpl CV_FINAL : public BatchNormLayer
public:
Mat weights_, bias_;
UMat umat_weight, umat_bias;
mutable int dims;
BatchNormLayerImpl(const LayerParams& params)
{
......@@ -142,6 +144,7 @@ public:
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE
{
dims = inputs[0].size();
if (!useGlobalStats && inputs[0][0] != 1)
CV_Error(Error::StsNotImplemented, "Batch normalization in training mode with batch size > 1");
Layer::getMemoryShapes(inputs, requiredOutputs, outputs, internals);
......@@ -150,9 +153,9 @@ public:
virtual bool supportBackend(int backendId) CV_OVERRIDE
{
return backendId == DNN_BACKEND_OPENCV ||
return (backendId == DNN_BACKEND_OPENCV) ||
(backendId == DNN_BACKEND_HALIDE && haveHalide()) ||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && (preferableTarget == DNN_TARGET_CPU || dims == 4));
}
#ifdef HAVE_OPENCL
......@@ -178,11 +181,12 @@ public:
}
UMat &inpBlob = inputs[0];
CV_Assert(inpBlob.dims == 2 || inpBlob.dims == 4);
int groups = inpBlob.size[0];
int channels = inpBlob.size[1];
int rows = inpBlob.dims > 2 ? inpBlob.size[2] : 1;
int cols = inpBlob.dims > 2 ? inpBlob.size[3] : 1;
int planeSize = 1;
for (size_t i = 2; i < inpBlob.dims; i++) {
planeSize *= inpBlob.size[i];
}
String opts = (use_half) ? " -DDtype=half" : " -DDtype=float";
for (size_t ii = 0; ii < outputs.size(); ii++)
......@@ -196,7 +200,7 @@ public:
}
else
{
MatShape s = shape(groups * channels, rows * cols);
MatShape s = shape(groups * channels, planeSize);
UMat src = inputs[ii].reshape(1, s.size(), &s[0]);
UMat dst = outputs[ii].reshape(1, s.size(), &s[0]);
int number = (s[1] % 8 == 0) ? 8 : ((s[1] % 4 == 0) ? 4 : 1);
......@@ -248,9 +252,10 @@ public:
CV_Assert(inputs.size() == 1);
Mat &inpBlob = inputs[0];
CV_Assert(inpBlob.dims == 2 || inpBlob.dims == 4);
int rows = inpBlob.dims > 2 ? inpBlob.size[2] : 1;
int cols = inpBlob.dims > 2 ? inpBlob.size[3] : 1;
int planeSize = 1;
for (size_t i = 2; i < inpBlob.dims; i++) {
planeSize *= inpBlob.size[i];
}
for (size_t ii = 0; ii < outputs.size(); ii++)
{
......@@ -262,8 +267,8 @@ public:
{
float w = weights_.at<float>(n);
float b = bias_.at<float>(n);
Mat inpBlobPlane(rows, cols, CV_32F, inpBlob.ptr<float>(num, n));
Mat outBlobPlane(rows, cols, CV_32F, outBlob.ptr<float>(num, n));
Mat inpBlobPlane(1, planeSize, CV_32F, inpBlob.ptr<float>(num, n));
Mat outBlobPlane(1, planeSize, CV_32F, outBlob.ptr<float>(num, n));
inpBlobPlane.convertTo(outBlobPlane, CV_32F, w, b);
}
}
......
......@@ -57,6 +57,24 @@ public:
CV_Error(Error::StsUnsupportedFormat, "Failed to parse onnx model");
}
ONNXImporter(const char* buffer, size_t sizeBuffer)
{
struct _Buf : public std::streambuf
{
_Buf(const char* buffer, size_t sizeBuffer)
{
char* p = const_cast<char*>(buffer);
setg(p, p, p + sizeBuffer);
}
};
_Buf buf(buffer, sizeBuffer);
std::istream input(&buf);
if (!model_proto.ParseFromIstream(&input))
CV_Error(Error::StsUnsupportedFormat, "Failed to parse onnx model from in-memory byte array.");
}
void populateNet(Net dstNet);
};
......@@ -768,6 +786,11 @@ void ONNXImporter::populateNet(Net dstNet)
}
replaceLayerParam(layerParams, "mode", "interpolation");
}
else if (layer_type == "LogSoftmax")
{
layerParams.type = "Softmax";
layerParams.set("log_softmax", true);
}
else
{
for (int j = 0; j < node_proto.input_size(); j++) {
......@@ -798,7 +821,7 @@ void ONNXImporter::populateNet(Net dstNet)
CV_Assert(!layerOutShapes.empty());
outShapes[layerParams.name] = layerOutShapes[0];
}
}
}
Net readNetFromONNX(const String& onnxFile)
{
......@@ -808,6 +831,19 @@ Net readNetFromONNX(const String& onnxFile)
return net;
}
Net readNetFromONNX(const char* buffer, size_t sizeBuffer)
{
ONNXImporter onnxImporter(buffer, sizeBuffer);
Net net;
onnxImporter.populateNet(net);
return net;
}
Net readNetFromONNX(const std::vector<uchar>& buffer)
{
return readNetFromONNX(reinterpret_cast<const char*>(buffer.data()), buffer.size());
}
Mat readTensorFromONNX(const String& path)
{
opencv_onnx::TensorProto tensor_proto = opencv_onnx::TensorProto();
......
......@@ -1423,6 +1423,43 @@ void TFImporter::populateNet(Net dstNet)
connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0);
}
else if (type == "StridedSlice")
{
CV_Assert(layer.input_size() == 4);
Mat begins = getTensorContent(getConstBlob(layer, value_id, 1));
Mat ends = getTensorContent(getConstBlob(layer, value_id, 2));
Mat strides = getTensorContent(getConstBlob(layer, value_id, 3));
CV_CheckTypeEQ(begins.type(), CV_32SC1, "");
CV_CheckTypeEQ(ends.type(), CV_32SC1, "");
CV_CheckTypeEQ(strides.type(), CV_32SC1, "");
const int num = begins.total();
CV_Assert_N(num == ends.total(), num == strides.total());
int end_mask = getLayerAttr(layer, "end_mask").i();
for (int i = 0; i < num; ++i)
{
if (end_mask & (1 << i))
ends.at<int>(i) = -1;
if (strides.at<int>(i) != 1)
CV_Error(Error::StsNotImplemented,
format("StridedSlice with stride %d", strides.at<int>(i)));
}
if (begins.total() == 4 && getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC)
{
// Swap NHWC parameters' order to NCHW.
std::swap(begins.at<int>(2), begins.at<int>(3));
std::swap(begins.at<int>(1), begins.at<int>(2));
std::swap(ends.at<int>(2), ends.at<int>(3));
std::swap(ends.at<int>(1), ends.at<int>(2));
}
layerParams.set("begin", DictValue::arrayInt((int*)begins.data, begins.total()));
layerParams.set("end", DictValue::arrayInt((int*)ends.data, ends.total()));
int id = dstNet.addLayer(name, "Slice", layerParams);
layer_id[name] = id;
connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0);
}
else if (type == "Mul")
{
bool haveConst = false;
......
......@@ -167,6 +167,13 @@ TEST_P(Test_ONNX_layers, BatchNormalization)
testONNXModels("batch_norm");
}
TEST_P(Test_ONNX_layers, BatchNormalization3D)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
throw SkipTestException("");
testONNXModels("batch_norm_3d");
}
TEST_P(Test_ONNX_layers, Transpose)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
......@@ -238,6 +245,12 @@ TEST_P(Test_ONNX_layers, Reshape)
testONNXModels("unsqueeze");
}
TEST_P(Test_ONNX_layers, Softmax)
{
testONNXModels("softmax");
testONNXModels("log_softmax", npy, 0, 0, false, false);
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_ONNX_layers, dnnBackendsAndTargets());
class Test_ONNX_nets : public Test_ONNX_layers {};
......
......@@ -188,6 +188,13 @@ TEST_P(Test_TensorFlow_layers, batch_norm)
runTensorFlowNet("mvn_batch_norm_1x1");
}
TEST_P(Test_TensorFlow_layers, batch_norm3D)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
throw SkipTestException("");
runTensorFlowNet("batch_norm3d");
}
TEST_P(Test_TensorFlow_layers, slim_batch_norm)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
......@@ -656,6 +663,7 @@ TEST_P(Test_TensorFlow_layers, slice)
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
runTensorFlowNet("slice_4d");
runTensorFlowNet("strided_slice");
}
TEST_P(Test_TensorFlow_layers, softmax)
......
package org.opencv.imgproc;
import java.lang.Math;
//javadoc:Moments
public class Moments {
......
This diff is collapsed.
......@@ -544,21 +544,41 @@ float cv::intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p1
return 0.f;
}
if( pointPolygonTest(_InputArray(fp1, n), fp2[0], false) >= 0 )
bool intersected = false;
// check if all of fp2's vertices is inside/on the edge of fp1.
int nVertices = 0;
for (int i=0; i<m; ++i)
nVertices += pointPolygonTest(_InputArray(fp1, n), fp2[i], false) >= 0;
// if all of fp2's vertices is inside/on the edge of fp1.
if (nVertices == m)
{
intersected = true;
result = fp2;
nr = m;
}
else if( pointPolygonTest(_InputArray(fp2, m), fp1[0], false) >= 0 )
else // otherwise check if fp2 is inside fp1.
{
nVertices = 0;
for (int i=0; i<n; ++i)
nVertices += pointPolygonTest(_InputArray(fp2, m), fp1[i], false) >= 0;
// // if all of fp1's vertices is inside/on the edge of fp2.
if (nVertices == n)
{
intersected = true;
result = fp1;
nr = n;
}
else
}
if (!intersected)
{
_p12.release();
return 0.f;
}
area = (float)contourArea(_InputArray(result, nr), false);
}
......
......@@ -2687,9 +2687,9 @@ TEST(Imgproc_ColorLab_Full, bitExactness)
<< "Iteration: " << iter << endl
<< "Hash vs Correct hash: " << h << ", " << goodHash << endl
<< "Error in: (" << x << ", " << y << ")" << endl
<< "Reference value: " << gx[0] << " " << gx[1] << " " << gx[2] << endl
<< "Actual value: " << rx[0] << " " << rx[1] << " " << rx[2] << endl
<< "Src value: " << px[0] << " " << px[1] << " " << px[2] << endl
<< "Reference value: " << int(gx[0]) << " " << int(gx[1]) << " " << int(gx[2]) << endl
<< "Actual value: " << int(rx[0]) << " " << int(rx[1]) << " " << int(rx[2]) << endl
<< "Src value: " << int(px[0]) << " " << int(px[1]) << " " << int(px[2]) << endl
<< "Size: (" << probe.rows << ", " << probe.cols << ")" << endl;
break;
......@@ -2780,9 +2780,9 @@ TEST(Imgproc_ColorLuv_Full, bitExactness)
<< "Iteration: " << iter << endl
<< "Hash vs Correct hash: " << h << ", " << goodHash << endl
<< "Error in: (" << x << ", " << y << ")" << endl
<< "Reference value: " << gx[0] << " " << gx[1] << " " << gx[2] << endl
<< "Actual value: " << rx[0] << " " << rx[1] << " " << rx[2] << endl
<< "Src value: " << px[0] << " " << px[1] << " " << px[2] << endl
<< "Reference value: " << int(gx[0]) << " " << int(gx[1]) << " " << int(gx[2]) << endl
<< "Actual value: " << int(rx[0]) << " " << int(rx[1]) << " " << int(rx[2]) << endl
<< "Src value: " << int(px[0]) << " " << int(px[1]) << " " << int(px[2]) << endl
<< "Size: (" << probe.rows << ", " << probe.cols << ")" << endl;
break;
......
This diff is collapsed.
......@@ -87,9 +87,9 @@ public class Utils {
*/
public static void bitmapToMat(Bitmap bmp, Mat mat, boolean unPremultiplyAlpha) {
if (bmp == null)
throw new java.lang.IllegalArgumentException("bmp == null");
throw new IllegalArgumentException("bmp == null");
if (mat == null)
throw new java.lang.IllegalArgumentException("mat == null");
throw new IllegalArgumentException("mat == null");
nBitmapToMat2(bmp, mat.nativeObj, unPremultiplyAlpha);
}
......@@ -117,9 +117,9 @@ public class Utils {
*/
public static void matToBitmap(Mat mat, Bitmap bmp, boolean premultiplyAlpha) {
if (mat == null)
throw new java.lang.IllegalArgumentException("mat == null");
throw new IllegalArgumentException("mat == null");
if (bmp == null)
throw new java.lang.IllegalArgumentException("bmp == null");
throw new IllegalArgumentException("bmp == null");
nMatToBitmap2(mat.nativeObj, bmp, premultiplyAlpha);
}
......
......@@ -31,7 +31,13 @@ def createFasterRCNNGraph(modelPath, configPath, outputPath):
aspect_ratios = [float(ar) for ar in grid_anchor_generator['aspect_ratios']]
width_stride = float(grid_anchor_generator['width_stride'][0])
height_stride = float(grid_anchor_generator['height_stride'][0])
features_stride = float(config['feature_extractor'][0]['first_stage_features_stride'][0])
feature_extractor = config['feature_extractor'][0]
if 'type' in feature_extractor and feature_extractor['type'][0] == 'faster_rcnn_nas':
features_stride = 16.0
else:
features_stride = float(feature_extractor['first_stage_features_stride'][0])
first_stage_nms_iou_threshold = float(config['first_stage_nms_iou_threshold'][0])
first_stage_max_proposals = int(config['first_stage_max_proposals'][0])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment