Compare commits
192 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83391ac59d | |||
| a8a93a57e7 | |||
| 93aa94e71e | |||
| 26f36f2ff9 | |||
| a494c75bfe | |||
| 139bd30247 | |||
| 1339c7f30c | |||
| 44dfe62af0 | |||
| d44c58a1fb | |||
| 7463e9b8bb | |||
| 07ed5e5346 | |||
| 5855eba9f3 | |||
| eace6adb6d | |||
| 6b50410336 | |||
| 6e3700593f | |||
| 6a8c5a1d27 | |||
| b7b08fa0c3 | |||
| 52709c7771 | |||
| aff375808d | |||
| 3f5f09e730 | |||
| 253a4c113e | |||
| c2ecbc76ce | |||
| 727feda935 | |||
| ebaee3ea21 | |||
| 423bc515e5 | |||
| d1ff87d94d | |||
| 4792837f2e | |||
| 416830fb59 | |||
| 07b1bc2e88 | |||
| d16b3b2487 | |||
| 74d0b4cc78 | |||
| 8832a9dbd5 | |||
| d4dc6b509b | |||
| 71a1150c95 | |||
| aba2167d9c | |||
| 5db4f1f7df | |||
| 2a5da50902 | |||
| 51758b2dd6 | |||
| 90b144cf0a | |||
| 6c36cd5d6e | |||
| c63a6c472d | |||
| 5b3f721efa | |||
| e5bea2bde4 | |||
| e9d64e0a8c | |||
| f0df78b7e7 | |||
| 7592d58f0c | |||
| d9f66413ee | |||
| 1b1bbe4262 | |||
| 54531f8e3b | |||
| b5a68f235a | |||
| 5bf64e7dfe | |||
| f5e852cdf0 | |||
| b418eb112c | |||
| 028d4d83d3 | |||
| c0a84dcc85 | |||
| e309a06b47 | |||
| 86dad3aebe | |||
| 5a9fe9dedb | |||
| c7d24c0fb3 | |||
| ea5ca16036 | |||
| 2991717191 | |||
| 085fb78e85 | |||
| a565aa6db9 | |||
| bbcc1752b1 | |||
| d480e2e51b | |||
| 4a4b2a0ce6 | |||
| 4103567776 | |||
| ab5279f4ad | |||
| 2f79b1b087 | |||
| 572d4f4491 | |||
| 38c9c20a35 | |||
| 4dfbbabf8b | |||
| c34c4b50d0 | |||
| 0c238c9e72 | |||
| 3d9f27b877 | |||
| bfeeb0ad70 | |||
| 3f4abcb228 | |||
| f2ccce23f3 | |||
| 0ab4872032 | |||
| 377fdf5ae5 | |||
| 2e15582799 | |||
| 65bdb3a544 | |||
| 6481cfd048 | |||
| d885242b61 | |||
| 619e038de9 | |||
| 5408949951 | |||
| e2a9cff3dc | |||
| c3b83b8354 | |||
| e24382691f | |||
| 9074b3e980 | |||
| a72074b33f | |||
| 7834a465d5 | |||
| 1f0bfc8d83 | |||
| 837e41f9a7 | |||
| 8eb4f72531 | |||
| 88115811a9 | |||
| eea05f5078 | |||
| e1305e8d05 | |||
| 2dd3408caa | |||
| ef570e4e13 | |||
| 56baf4ed87 | |||
| 7ffb103758 | |||
| 27bfab4e6e | |||
| cc8add9f66 | |||
| d0d115321d | |||
| 99683e958a | |||
| 3d8614cb47 | |||
| 48afe1586a | |||
| 496eed950f | |||
| 75bb6aa9a1 | |||
| 44b2f9637a | |||
| 1893b37e23 | |||
| 2ffa7ac0da | |||
| 26ac81df3e | |||
| 1ec10ca565 | |||
| 15f0e2e7cb | |||
| 4c9364a803 | |||
| e7a787aa41 | |||
| 5bf3991f55 | |||
| 0862d69a6e | |||
| 6ce2f1316f | |||
| 294348939b | |||
| e2db95184f | |||
| f8597fc150 | |||
| 85b0b0cd77 | |||
| f729202272 | |||
| db53f4533e | |||
| a016f6022c | |||
| b3269b08a1 | |||
| e59cff47d4 | |||
| 47912431e6 | |||
| 701d0d9905 | |||
| 1feabf4275 | |||
| 697acf7f6a | |||
| c9e10e1d0b | |||
| bd54ba911d | |||
| a9354fc743 | |||
| 1377f0147e | |||
| d2b1e38207 | |||
| afe1c70f2d | |||
| 45fbb67aba | |||
| 914005174f | |||
| 2a82467a6f | |||
| a233232b7d | |||
| ed4bf13960 | |||
| 3135063100 | |||
| 87ef6a9cc1 | |||
| fa613e393f | |||
| db70676933 | |||
| 70492c2127 | |||
| 0a88f84847 | |||
| a630ad73cb | |||
| 366e8217c2 | |||
| 01226cb8ac | |||
| 3891b72f33 | |||
| c54ccaac31 | |||
| 79731cb0ff | |||
| 2920a8e0ec | |||
| 6a4c3b61e6 | |||
| 6360c3bf46 | |||
| e313603aac | |||
| 0f3de805f4 | |||
| 56e19e3494 | |||
| 8ae06b4648 | |||
| eb7add1828 | |||
| b152b8cbcd | |||
| 2336b0706d | |||
| 300b57dd70 | |||
| 5e1c9099e8 | |||
| 397e9bc8d6 | |||
| 2366f2cb2e | |||
| 9faefa0c96 | |||
| 82010bf5c1 | |||
| 6234f01a6d | |||
| ef94275eb6 | |||
| dd7b9000ad | |||
| f1328c7395 | |||
| 9d06e58c3c | |||
| 711b136191 | |||
| a04f9e7a59 | |||
| db5b22e895 | |||
| 0d52c37e11 | |||
| 3efc645975 | |||
| 572812217b | |||
| ff41fbc5c1 | |||
| cac864192c | |||
| 7a46d7efde | |||
| ed9524e125 | |||
| c103b63fe1 | |||
| a3d0882317 | |||
| f28e191d70 | |||
| 38b6c44b4c |
@@ -6,11 +6,29 @@ on:
|
||||
- 3.4
|
||||
|
||||
jobs:
|
||||
ARM64:
|
||||
Ubuntu2004-ARM64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-ARM64.yaml@main
|
||||
|
||||
U20:
|
||||
Ubuntu1404-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-U14.yaml@main
|
||||
|
||||
Ubuntu2004-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-U20.yaml@main
|
||||
|
||||
W10:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-W10.yaml@main
|
||||
Windows10-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-W10.yaml@main
|
||||
|
||||
macOS-ARM64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-macOS-ARM64.yaml@main
|
||||
|
||||
macOS-x64:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-macOS-x86_64.yaml@main
|
||||
|
||||
iOS:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-iOS.yaml@main
|
||||
|
||||
Android:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-Android.yaml@main
|
||||
|
||||
docs:
|
||||
uses: opencv/ci-gha-workflow/.github/workflows/OCV-PR-3.4-docs.yaml@main
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
|
||||
|
||||
project(Carotene)
|
||||
|
||||
@@ -27,6 +27,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND CV_CLANG AND WITH_NEON)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-unused-function)
|
||||
endif()
|
||||
|
||||
add_library(carotene_objs OBJECT EXCLUDE_FROM_ALL
|
||||
${carotene_headers}
|
||||
${carotene_sources}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION ${MIN_VER_CMAKE} FATAL_ERROR)
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
@@ -1296,13 +1296,13 @@ struct MorphCtx
|
||||
CAROTENE_NS::BORDER_MODE border;
|
||||
uchar borderValues[4];
|
||||
};
|
||||
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int, int,
|
||||
inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int width, int height,
|
||||
int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
|
||||
int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace)
|
||||
{
|
||||
if(!context || !kernel_data || src_type != dst_type ||
|
||||
CV_MAT_DEPTH(src_type) != CV_8U || src_type < 0 || (src_type >> CV_CN_SHIFT) > 3 ||
|
||||
|
||||
width < kernel_width || height < kernel_height ||
|
||||
allowSubmatrix || allowInplace || iterations != 1 ||
|
||||
!CAROTENE_NS::isSupportedConfiguration())
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
@@ -109,9 +109,9 @@ template <> struct wAdd<s32>
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<s32>::vec128 & v_src0,
|
||||
const typename VecTraits<s32>::vec128 & v_src1,
|
||||
typename VecTraits<s32>::vec128 & v_dst) const
|
||||
void operator() (const VecTraits<s32>::vec128 & v_src0,
|
||||
const VecTraits<s32>::vec128 & v_src1,
|
||||
VecTraits<s32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vcvtq_f32_s32(v_src0);
|
||||
float32x4_t vs2 = vcvtq_f32_s32(v_src1);
|
||||
@@ -121,9 +121,9 @@ template <> struct wAdd<s32>
|
||||
v_dst = vcvtq_s32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<s32>::vec64 & v_src0,
|
||||
const typename VecTraits<s32>::vec64 & v_src1,
|
||||
typename VecTraits<s32>::vec64 & v_dst) const
|
||||
void operator() (const VecTraits<s32>::vec64 & v_src0,
|
||||
const VecTraits<s32>::vec64 & v_src1,
|
||||
VecTraits<s32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vcvt_f32_s32(v_src0);
|
||||
float32x2_t vs2 = vcvt_f32_s32(v_src1);
|
||||
@@ -153,9 +153,9 @@ template <> struct wAdd<u32>
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<u32>::vec128 & v_src0,
|
||||
const typename VecTraits<u32>::vec128 & v_src1,
|
||||
typename VecTraits<u32>::vec128 & v_dst) const
|
||||
void operator() (const VecTraits<u32>::vec128 & v_src0,
|
||||
const VecTraits<u32>::vec128 & v_src1,
|
||||
VecTraits<u32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vcvtq_f32_u32(v_src0);
|
||||
float32x4_t vs2 = vcvtq_f32_u32(v_src1);
|
||||
@@ -165,9 +165,9 @@ template <> struct wAdd<u32>
|
||||
v_dst = vcvtq_u32_f32(vs1);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<u32>::vec64 & v_src0,
|
||||
const typename VecTraits<u32>::vec64 & v_src1,
|
||||
typename VecTraits<u32>::vec64 & v_dst) const
|
||||
void operator() (const VecTraits<u32>::vec64 & v_src0,
|
||||
const VecTraits<u32>::vec64 & v_src1,
|
||||
VecTraits<u32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vcvt_f32_u32(v_src0);
|
||||
float32x2_t vs2 = vcvt_f32_u32(v_src1);
|
||||
@@ -197,17 +197,17 @@ template <> struct wAdd<f32>
|
||||
vgamma = vdupq_n_f32(_gamma + 0.5);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<f32>::vec128 & v_src0,
|
||||
const typename VecTraits<f32>::vec128 & v_src1,
|
||||
typename VecTraits<f32>::vec128 & v_dst) const
|
||||
void operator() (const VecTraits<f32>::vec128 & v_src0,
|
||||
const VecTraits<f32>::vec128 & v_src1,
|
||||
VecTraits<f32>::vec128 & v_dst) const
|
||||
{
|
||||
float32x4_t vs1 = vmlaq_f32(vgamma, v_src0, valpha);
|
||||
v_dst = vmlaq_f32(vs1, v_src1, vbeta);
|
||||
}
|
||||
|
||||
void operator() (const typename VecTraits<f32>::vec64 & v_src0,
|
||||
const typename VecTraits<f32>::vec64 & v_src1,
|
||||
typename VecTraits<f32>::vec64 & v_dst) const
|
||||
void operator() (const VecTraits<f32>::vec64 & v_src0,
|
||||
const VecTraits<f32>::vec64 & v_src1,
|
||||
VecTraits<f32>::vec64 & v_dst) const
|
||||
{
|
||||
float32x2_t vs1 = vmla_f32(vget_low(vgamma), v_src0, vget_low(valpha));
|
||||
v_dst = vmla_f32(vs1, v_src1, vget_low(vbeta));
|
||||
|
||||
@@ -119,6 +119,7 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4334) # vs2005 Win64
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4267) # vs2008 Win64
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4456) # vs2015
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4819) # vs2019 Win64
|
||||
|
||||
if(MSVC AND CV_ICC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qrestrict")
|
||||
|
||||
@@ -102,4 +102,4 @@ if(NOT BUILD_SHARED_LIBS)
|
||||
ocv_install_target(${ZLIB_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
|
||||
ocv_install_3rdparty_licenses(zlib README)
|
||||
ocv_install_3rdparty_licenses(zlib LICENSE)
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
|
||||
ChangeLog file for zlib
|
||||
|
||||
Changes in 1.2.13 (13 Oct 2022)
|
||||
- Fix configure issue that discarded provided CC definition
|
||||
- Correct incorrect inputs provided to the CRC functions
|
||||
- Repair prototypes and exporting of new CRC functions
|
||||
- Fix inflateBack to detect invalid input with distances too far
|
||||
- Have infback() deliver all of the available output up to any error
|
||||
- Fix a bug when getting a gzip header extra field with inflate()
|
||||
- Fix bug in block type selection when Z_FIXED used
|
||||
- Tighten deflateBound bounds
|
||||
- Remove deleted assembler code references
|
||||
- Various portability and appearance improvements
|
||||
|
||||
Changes in 1.2.12 (27 Mar 2022)
|
||||
- Cygwin does not have _wopen(), so do not create gzopen_w() there
|
||||
- Permit a deflateParams() parameter change as soon as possible
|
||||
@@ -159,7 +171,7 @@ Changes in 1.2.7.1 (24 Mar 2013)
|
||||
- Fix types in contrib/minizip to match result of get_crc_table()
|
||||
- Simplify contrib/vstudio/vc10 with 'd' suffix
|
||||
- Add TOP support to win32/Makefile.msc
|
||||
- Suport i686 and amd64 assembler builds in CMakeLists.txt
|
||||
- Support i686 and amd64 assembler builds in CMakeLists.txt
|
||||
- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
|
||||
- Add vc11 and vc12 build files to contrib/vstudio
|
||||
- Add gzvprintf() as an undocumented function in zlib
|
||||
@@ -359,14 +371,14 @@ Changes in 1.2.5.1 (10 Sep 2011)
|
||||
- Use u4 type for crc_table to avoid conversion warnings
|
||||
- Apply casts in zlib.h to avoid conversion warnings
|
||||
- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
|
||||
- Improve inflateSync() documentation to note indeterminancy
|
||||
- Improve inflateSync() documentation to note indeterminacy
|
||||
- Add deflatePending() function to return the amount of pending output
|
||||
- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
|
||||
- Add a check in configure for stdarg.h, use for gzprintf()
|
||||
- Check that pointers fit in ints when gzprint() compiled old style
|
||||
- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
|
||||
- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
|
||||
- Add debug records in assmebler code [Londer]
|
||||
- Add debug records in assembler code [Londer]
|
||||
- Update RFC references to use http://tools.ietf.org/html/... [Li]
|
||||
- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
|
||||
|
||||
@@ -1033,7 +1045,7 @@ Changes in 1.2.0.1 (17 March 2003)
|
||||
- Include additional header file on VMS for off_t typedef
|
||||
- Try to use _vsnprintf where it supplants vsprintf [Vollant]
|
||||
- Add some casts in inffast.c
|
||||
- Enchance comments in zlib.h on what happens if gzprintf() tries to
|
||||
- Enhance comments in zlib.h on what happens if gzprintf() tries to
|
||||
write more than 4095 bytes before compression
|
||||
- Remove unused state from inflateBackEnd()
|
||||
- Remove exit(0) from minigzip.c, example.c
|
||||
@@ -1211,7 +1223,7 @@ Changes in 1.0.9 (17 Feb 1998)
|
||||
- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
|
||||
- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
|
||||
- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
|
||||
the declaration of FAR (Gilles VOllant)
|
||||
the declaration of FAR (Gilles Vollant)
|
||||
- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
|
||||
- read_buf buf parameter of type Bytef* instead of charf*
|
||||
- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
|
||||
@@ -1567,7 +1579,7 @@ Changes in 0.4:
|
||||
- renamed deflateOptions as deflateInit2, call one or the other but not both
|
||||
- added the method parameter for deflateInit2
|
||||
- added inflateInit2
|
||||
- simplied considerably deflateInit and inflateInit by not supporting
|
||||
- simplified considerably deflateInit and inflateInit by not supporting
|
||||
user-provided history buffer. This is supported only in deflateInit2
|
||||
and inflateInit2
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright notice:
|
||||
|
||||
(C) 1995-2022 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
@@ -1,6 +1,6 @@
|
||||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.12 is a general purpose data compression library. All the code is
|
||||
zlib 1.2.13 is a general purpose data compression library. All the code is
|
||||
thread safe. The data format used by the zlib library is described by RFCs
|
||||
(Request for Comments) 1950 to 1952 in the files
|
||||
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
|
||||
@@ -31,7 +31,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||
issue of Dr. Dobb's Journal; a copy of the article is available at
|
||||
http://marknelson.us/1997/01/01/zlib-engine/ .
|
||||
|
||||
The changes made in version 1.2.12 are documented in the file ChangeLog.
|
||||
The changes made in version 1.2.13 are documented in the file ChangeLog.
|
||||
|
||||
Unsupported third party contributions are provided in directory contrib/ .
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
||||
Z_STREAM_ERROR if the level parameter is invalid.
|
||||
*/
|
||||
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
@@ -65,7 +65,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
|
||||
/* ===========================================================================
|
||||
*/
|
||||
int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
int ZEXPORT compress(dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
@@ -78,7 +78,7 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
If the default memLevel or windowBits for deflateInit() is changed, then
|
||||
this function needs to be updated.
|
||||
*/
|
||||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong ZEXPORT compressBound(sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
|
||||
@@ -98,13 +98,22 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If available, use the ARM processor CRC32 instruction. */
|
||||
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
|
||||
# define ARMCRC32
|
||||
#endif
|
||||
|
||||
/* Local functions. */
|
||||
local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
|
||||
local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
|
||||
|
||||
/* If available, use the ARM processor CRC32 instruction. */
|
||||
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
|
||||
# define ARMCRC32
|
||||
#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
|
||||
local z_word_t byte_swap OF((z_word_t word));
|
||||
#endif
|
||||
|
||||
#if defined(W) && !defined(ARMCRC32)
|
||||
local z_crc_t crc_word OF((z_word_t data));
|
||||
local z_word_t crc_word_big OF((z_word_t data));
|
||||
#endif
|
||||
|
||||
#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
|
||||
@@ -630,7 +639,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
/* Pre-condition the CRC */
|
||||
crc ^= 0xffffffff;
|
||||
crc = (~crc) & 0xffffffff;
|
||||
|
||||
/* Compute the CRC up to a word boundary. */
|
||||
while (len && ((z_size_t)buf & 7) != 0) {
|
||||
@@ -645,8 +654,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
|
||||
len &= 7;
|
||||
|
||||
/* Do three interleaved CRCs to realize the throughput of one crc32x
|
||||
instruction per cycle. Each CRC is calcuated on Z_BATCH words. The three
|
||||
CRCs are combined into a single CRC after each set of batches. */
|
||||
instruction per cycle. Each CRC is calculated on Z_BATCH words. The
|
||||
three CRCs are combined into a single CRC after each set of batches. */
|
||||
while (num >= 3 * Z_BATCH) {
|
||||
crc1 = 0;
|
||||
crc2 = 0;
|
||||
@@ -749,7 +758,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
/* Pre-condition the CRC */
|
||||
crc ^= 0xffffffff;
|
||||
crc = (~crc) & 0xffffffff;
|
||||
|
||||
#ifdef W
|
||||
|
||||
@@ -1077,7 +1086,7 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
once(&made, make_crc_table);
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
return multmodp(x2nmodp(len2, 3), crc1) ^ crc2;
|
||||
return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@@ -1086,7 +1095,7 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
{
|
||||
return crc32_combine64(crc1, crc2, len2);
|
||||
return crc32_combine64(crc1, crc2, (z_off64_t)len2);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@@ -1103,14 +1112,14 @@ uLong ZEXPORT crc32_combine_gen64(len2)
|
||||
uLong ZEXPORT crc32_combine_gen(len2)
|
||||
z_off_t len2;
|
||||
{
|
||||
return crc32_combine_gen64(len2);
|
||||
return crc32_combine_gen64((z_off64_t)len2);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong crc32_combine_op(crc1, crc2, op)
|
||||
uLong ZEXPORT crc32_combine_op(crc1, crc2, op)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
uLong op;
|
||||
{
|
||||
return multmodp(op, crc1) ^ crc2;
|
||||
return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#include "deflate.h"
|
||||
|
||||
const char deflate_copyright[] =
|
||||
" deflate 1.2.12 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
|
||||
" deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@@ -87,13 +87,7 @@ local void lm_init OF((deflate_state *s));
|
||||
local void putShortMSB OF((deflate_state *s, uInt b));
|
||||
local void flush_pending OF((z_streamp strm));
|
||||
local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
|
||||
#ifdef ASMV
|
||||
# pragma message("Assembler code may have bugs -- use at your own risk")
|
||||
void match_init OF((void)); /* asm code initialization */
|
||||
uInt longest_match OF((deflate_state *s, IPos cur_match));
|
||||
#else
|
||||
local uInt longest_match OF((deflate_state *s, IPos cur_match));
|
||||
#endif
|
||||
|
||||
#ifdef ZLIB_DEBUG
|
||||
local void check_match OF((deflate_state *s, IPos start, IPos match,
|
||||
@@ -160,7 +154,7 @@ local const config configuration_table[10] = {
|
||||
* characters, so that a running hash key can be computed from the previous
|
||||
* key instead of complete recalculation each time.
|
||||
*/
|
||||
#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
|
||||
#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask)
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
@@ -191,9 +185,9 @@ local const config configuration_table[10] = {
|
||||
*/
|
||||
#define CLEAR_HASH(s) \
|
||||
do { \
|
||||
s->head[s->hash_size-1] = NIL; \
|
||||
s->head[s->hash_size - 1] = NIL; \
|
||||
zmemzero((Bytef *)s->head, \
|
||||
(unsigned)(s->hash_size-1)*sizeof(*s->head)); \
|
||||
(unsigned)(s->hash_size - 1)*sizeof(*s->head)); \
|
||||
} while (0)
|
||||
|
||||
/* ===========================================================================
|
||||
@@ -285,6 +279,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
|
||||
if (windowBits < 0) { /* suppress zlib wrapper */
|
||||
wrap = 0;
|
||||
if (windowBits < -15)
|
||||
return Z_STREAM_ERROR;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
#ifdef GZIP
|
||||
@@ -314,7 +310,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
s->hash_bits = (uInt)memLevel + 7;
|
||||
s->hash_size = 1 << s->hash_bits;
|
||||
s->hash_mask = s->hash_size - 1;
|
||||
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
|
||||
s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH);
|
||||
|
||||
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
|
||||
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
|
||||
@@ -340,11 +336,11 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
* sym_buf value to read moves forward three bytes. From that symbol, up to
|
||||
* 31 bits are written to pending_buf. The closest the written pending_buf
|
||||
* bits gets to the next sym_buf symbol to read is just before the last
|
||||
* code is written. At that time, 31*(n-2) bits have been written, just
|
||||
* after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
|
||||
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
|
||||
* code is written. At that time, 31*(n - 2) bits have been written, just
|
||||
* after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at
|
||||
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1
|
||||
* symbols are written.) The closest the writing gets to what is unread is
|
||||
* then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
|
||||
* then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and
|
||||
* can range from 128 to 32768.
|
||||
*
|
||||
* Therefore, at a minimum, there are 142 bits of space between what is
|
||||
@@ -390,7 +386,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
/* =========================================================================
|
||||
* Check for a valid deflate stream state. Return 0 if ok, 1 if not.
|
||||
*/
|
||||
local int deflateStateCheck (strm)
|
||||
local int deflateStateCheck(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
deflate_state *s;
|
||||
@@ -413,7 +409,7 @@ local int deflateStateCheck (strm)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
||||
int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
const Bytef *dictionary;
|
||||
uInt dictLength;
|
||||
@@ -482,7 +478,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
|
||||
int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
Bytef *dictionary;
|
||||
uInt *dictLength;
|
||||
@@ -504,7 +500,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateResetKeep (strm)
|
||||
int ZEXPORT deflateResetKeep(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
deflate_state *s;
|
||||
@@ -542,7 +538,7 @@ int ZEXPORT deflateResetKeep (strm)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateReset (strm)
|
||||
int ZEXPORT deflateReset(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
int ret;
|
||||
@@ -554,7 +550,7 @@ int ZEXPORT deflateReset (strm)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateSetHeader (strm, head)
|
||||
int ZEXPORT deflateSetHeader(strm, head)
|
||||
z_streamp strm;
|
||||
gz_headerp head;
|
||||
{
|
||||
@@ -565,7 +561,7 @@ int ZEXPORT deflateSetHeader (strm, head)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflatePending (strm, pending, bits)
|
||||
int ZEXPORT deflatePending(strm, pending, bits)
|
||||
unsigned *pending;
|
||||
int *bits;
|
||||
z_streamp strm;
|
||||
@@ -579,7 +575,7 @@ int ZEXPORT deflatePending (strm, pending, bits)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflatePrime (strm, bits, value)
|
||||
int ZEXPORT deflatePrime(strm, bits, value)
|
||||
z_streamp strm;
|
||||
int bits;
|
||||
int value;
|
||||
@@ -674,36 +670,50 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* For the default windowBits of 15 and memLevel of 8, this function returns
|
||||
* a close to exact, as well as small, upper bound on the compressed size.
|
||||
* They are coded as constants here for a reason--if the #define's are
|
||||
* changed, then this function needs to be changed as well. The return
|
||||
* value for 15 and 8 only works for those exact settings.
|
||||
* For the default windowBits of 15 and memLevel of 8, this function returns a
|
||||
* close to exact, as well as small, upper bound on the compressed size. This
|
||||
* is an expansion of ~0.03%, plus a small constant.
|
||||
*
|
||||
* For any setting other than those defaults for windowBits and memLevel,
|
||||
* the value returned is a conservative worst case for the maximum expansion
|
||||
* resulting from using fixed blocks instead of stored blocks, which deflate
|
||||
* can emit on compressed data for some combinations of the parameters.
|
||||
* For any setting other than those defaults for windowBits and memLevel, one
|
||||
* of two worst case bounds is returned. This is at most an expansion of ~4% or
|
||||
* ~13%, plus a small constant.
|
||||
*
|
||||
* This function could be more sophisticated to provide closer upper bounds for
|
||||
* every combination of windowBits and memLevel. But even the conservative
|
||||
* upper bound of about 14% expansion does not seem onerous for output buffer
|
||||
* allocation.
|
||||
* Both the 0.03% and 4% derive from the overhead of stored blocks. The first
|
||||
* one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second
|
||||
* is for stored blocks of 127 bytes (the worst case memLevel == 1). The
|
||||
* expansion results from five bytes of header for each stored block.
|
||||
*
|
||||
* The larger expansion of 13% results from a window size less than or equal to
|
||||
* the symbols buffer size (windowBits <= memLevel + 7). In that case some of
|
||||
* the data being compressed may have slid out of the sliding window, impeding
|
||||
* a stored block from being emitted. Then the only choice is a fixed or
|
||||
* dynamic block, where a fixed block limits the maximum expansion to 9 bits
|
||||
* per 8-bit byte, plus 10 bits for every block. The smallest block size for
|
||||
* which this can occur is 255 (memLevel == 2).
|
||||
*
|
||||
* Shifts are used to approximate divisions, for speed.
|
||||
*/
|
||||
uLong ZEXPORT deflateBound(strm, sourceLen)
|
||||
z_streamp strm;
|
||||
uLong sourceLen;
|
||||
{
|
||||
deflate_state *s;
|
||||
uLong complen, wraplen;
|
||||
uLong fixedlen, storelen, wraplen;
|
||||
|
||||
/* conservative upper bound for compressed data */
|
||||
complen = sourceLen +
|
||||
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
|
||||
/* upper bound for fixed blocks with 9-bit literals and length 255
|
||||
(memLevel == 2, which is the lowest that may not use stored blocks) --
|
||||
~13% overhead plus a small constant */
|
||||
fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) +
|
||||
(sourceLen >> 9) + 4;
|
||||
|
||||
/* if can't get parameters, return conservative bound plus zlib wrapper */
|
||||
/* upper bound for stored blocks with length 127 (memLevel == 1) --
|
||||
~4% overhead plus a small constant */
|
||||
storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) +
|
||||
(sourceLen >> 11) + 7;
|
||||
|
||||
/* if can't get parameters, return larger bound plus a zlib wrapper */
|
||||
if (deflateStateCheck(strm))
|
||||
return complen + 6;
|
||||
return (fixedlen > storelen ? fixedlen : storelen) + 6;
|
||||
|
||||
/* compute wrapper length */
|
||||
s = strm->state;
|
||||
@@ -740,11 +750,12 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
|
||||
wraplen = 6;
|
||||
}
|
||||
|
||||
/* if not default parameters, return conservative bound */
|
||||
/* if not default parameters, return one of the conservative bounds */
|
||||
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
|
||||
return complen + wraplen;
|
||||
return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen;
|
||||
|
||||
/* default settings: return tight bound for that case */
|
||||
/* default settings: return tight bound for that case -- ~0.03% overhead
|
||||
plus a small constant */
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
(sourceLen >> 25) + 13 - 6 + wraplen;
|
||||
}
|
||||
@@ -754,7 +765,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
|
||||
* IN assertion: the stream state is correct and there is enough room in
|
||||
* pending_buf.
|
||||
*/
|
||||
local void putShortMSB (s, b)
|
||||
local void putShortMSB(s, b)
|
||||
deflate_state *s;
|
||||
uInt b;
|
||||
{
|
||||
@@ -801,7 +812,7 @@ local void flush_pending(strm)
|
||||
} while (0)
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflate (strm, flush)
|
||||
int ZEXPORT deflate(strm, flush)
|
||||
z_streamp strm;
|
||||
int flush;
|
||||
{
|
||||
@@ -856,7 +867,7 @@ int ZEXPORT deflate (strm, flush)
|
||||
s->status = BUSY_STATE;
|
||||
if (s->status == INIT_STATE) {
|
||||
/* zlib header */
|
||||
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
|
||||
uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8;
|
||||
uInt level_flags;
|
||||
|
||||
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
|
||||
@@ -1116,7 +1127,7 @@ int ZEXPORT deflate (strm, flush)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateEnd (strm)
|
||||
int ZEXPORT deflateEnd(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
int status;
|
||||
@@ -1142,7 +1153,7 @@ int ZEXPORT deflateEnd (strm)
|
||||
* To simplify the source, this is not supported for 16-bit MSDOS (which
|
||||
* doesn't have enough memory anyway to duplicate compression states).
|
||||
*/
|
||||
int ZEXPORT deflateCopy (dest, source)
|
||||
int ZEXPORT deflateCopy(dest, source)
|
||||
z_streamp dest;
|
||||
z_streamp source;
|
||||
{
|
||||
@@ -1231,7 +1242,7 @@ local unsigned read_buf(strm, buf, size)
|
||||
/* ===========================================================================
|
||||
* Initialize the "longest match" routines for a new zlib stream
|
||||
*/
|
||||
local void lm_init (s)
|
||||
local void lm_init(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
s->window_size = (ulg)2L*s->w_size;
|
||||
@@ -1252,11 +1263,6 @@ local void lm_init (s)
|
||||
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||
s->match_available = 0;
|
||||
s->ins_h = 0;
|
||||
#ifndef FASTEST
|
||||
#ifdef ASMV
|
||||
match_init(); /* initialize the asm code */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef FASTEST
|
||||
@@ -1269,10 +1275,6 @@ local void lm_init (s)
|
||||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||||
* OUT assertion: the match length is not greater than s->lookahead.
|
||||
*/
|
||||
#ifndef ASMV
|
||||
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
|
||||
* match.S. The code will be functionally equivalent.
|
||||
*/
|
||||
local uInt longest_match(s, cur_match)
|
||||
deflate_state *s;
|
||||
IPos cur_match; /* current match */
|
||||
@@ -1297,10 +1299,10 @@ local uInt longest_match(s, cur_match)
|
||||
*/
|
||||
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
|
||||
register ush scan_start = *(ushf*)scan;
|
||||
register ush scan_end = *(ushf*)(scan+best_len-1);
|
||||
register ush scan_end = *(ushf*)(scan + best_len - 1);
|
||||
#else
|
||||
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
||||
register Byte scan_end1 = scan[best_len-1];
|
||||
register Byte scan_end1 = scan[best_len - 1];
|
||||
register Byte scan_end = scan[best_len];
|
||||
#endif
|
||||
|
||||
@@ -1318,7 +1320,8 @@ local uInt longest_match(s, cur_match)
|
||||
*/
|
||||
if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
|
||||
|
||||
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
||||
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||
"need lookahead");
|
||||
|
||||
do {
|
||||
Assert(cur_match < s->strstart, "no future");
|
||||
@@ -1336,43 +1339,44 @@ local uInt longest_match(s, cur_match)
|
||||
/* This code assumes sizeof(unsigned short) == 2. Do not use
|
||||
* UNALIGNED_OK if your compiler uses a different size.
|
||||
*/
|
||||
if (*(ushf*)(match+best_len-1) != scan_end ||
|
||||
if (*(ushf*)(match + best_len - 1) != scan_end ||
|
||||
*(ushf*)match != scan_start) continue;
|
||||
|
||||
/* It is not necessary to compare scan[2] and match[2] since they are
|
||||
* always equal when the other bytes match, given that the hash keys
|
||||
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
|
||||
* strstart+3, +5, ... up to strstart+257. We check for insufficient
|
||||
* strstart + 3, + 5, up to strstart + 257. We check for insufficient
|
||||
* lookahead only every 4th comparison; the 128th check will be made
|
||||
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
|
||||
* at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is
|
||||
* necessary to put more guard bytes at the end of the window, or
|
||||
* to check more often for insufficient lookahead.
|
||||
*/
|
||||
Assert(scan[2] == match[2], "scan[2]?");
|
||||
scan++, match++;
|
||||
do {
|
||||
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
} while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
scan < strend);
|
||||
/* The funny "do {}" generates better code on most compilers */
|
||||
|
||||
/* Here, scan <= window+strstart+257 */
|
||||
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||||
/* Here, scan <= window + strstart + 257 */
|
||||
Assert(scan <= s->window + (unsigned)(s->window_size - 1),
|
||||
"wild scan");
|
||||
if (*scan == *match) scan++;
|
||||
|
||||
len = (MAX_MATCH - 1) - (int)(strend-scan);
|
||||
len = (MAX_MATCH - 1) - (int)(strend - scan);
|
||||
scan = strend - (MAX_MATCH-1);
|
||||
|
||||
#else /* UNALIGNED_OK */
|
||||
|
||||
if (match[best_len] != scan_end ||
|
||||
match[best_len-1] != scan_end1 ||
|
||||
*match != *scan ||
|
||||
*++match != scan[1]) continue;
|
||||
if (match[best_len] != scan_end ||
|
||||
match[best_len - 1] != scan_end1 ||
|
||||
*match != *scan ||
|
||||
*++match != scan[1]) continue;
|
||||
|
||||
/* The check at best_len-1 can be removed because it will be made
|
||||
/* The check at best_len - 1 can be removed because it will be made
|
||||
* again later. (This heuristic is not always a win.)
|
||||
* It is not necessary to compare scan[2] and match[2] since they
|
||||
* are always equal when the other bytes match, given that
|
||||
@@ -1382,7 +1386,7 @@ local uInt longest_match(s, cur_match)
|
||||
Assert(*scan == *match, "match[2]?");
|
||||
|
||||
/* We check for insufficient lookahead only every 8th comparison;
|
||||
* the 256th check will be made at strstart+258.
|
||||
* the 256th check will be made at strstart + 258.
|
||||
*/
|
||||
do {
|
||||
} while (*++scan == *++match && *++scan == *++match &&
|
||||
@@ -1391,7 +1395,8 @@ local uInt longest_match(s, cur_match)
|
||||
*++scan == *++match && *++scan == *++match &&
|
||||
scan < strend);
|
||||
|
||||
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||||
Assert(scan <= s->window + (unsigned)(s->window_size - 1),
|
||||
"wild scan");
|
||||
|
||||
len = MAX_MATCH - (int)(strend - scan);
|
||||
scan = strend - MAX_MATCH;
|
||||
@@ -1403,9 +1408,9 @@ local uInt longest_match(s, cur_match)
|
||||
best_len = len;
|
||||
if (len >= nice_match) break;
|
||||
#ifdef UNALIGNED_OK
|
||||
scan_end = *(ushf*)(scan+best_len-1);
|
||||
scan_end = *(ushf*)(scan + best_len - 1);
|
||||
#else
|
||||
scan_end1 = scan[best_len-1];
|
||||
scan_end1 = scan[best_len - 1];
|
||||
scan_end = scan[best_len];
|
||||
#endif
|
||||
}
|
||||
@@ -1415,7 +1420,6 @@ local uInt longest_match(s, cur_match)
|
||||
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
|
||||
return s->lookahead;
|
||||
}
|
||||
#endif /* ASMV */
|
||||
|
||||
#else /* FASTEST */
|
||||
|
||||
@@ -1436,7 +1440,8 @@ local uInt longest_match(s, cur_match)
|
||||
*/
|
||||
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
|
||||
|
||||
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
||||
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||
"need lookahead");
|
||||
|
||||
Assert(cur_match < s->strstart, "no future");
|
||||
|
||||
@@ -1446,7 +1451,7 @@ local uInt longest_match(s, cur_match)
|
||||
*/
|
||||
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
|
||||
|
||||
/* The check at best_len-1 can be removed because it will be made
|
||||
/* The check at best_len - 1 can be removed because it will be made
|
||||
* again later. (This heuristic is not always a win.)
|
||||
* It is not necessary to compare scan[2] and match[2] since they
|
||||
* are always equal when the other bytes match, given that
|
||||
@@ -1456,7 +1461,7 @@ local uInt longest_match(s, cur_match)
|
||||
Assert(*scan == *match, "match[2]?");
|
||||
|
||||
/* We check for insufficient lookahead only every 8th comparison;
|
||||
* the 256th check will be made at strstart+258.
|
||||
* the 256th check will be made at strstart + 258.
|
||||
*/
|
||||
do {
|
||||
} while (*++scan == *++match && *++scan == *++match &&
|
||||
@@ -1465,7 +1470,7 @@ local uInt longest_match(s, cur_match)
|
||||
*++scan == *++match && *++scan == *++match &&
|
||||
scan < strend);
|
||||
|
||||
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||||
Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan");
|
||||
|
||||
len = MAX_MATCH - (int)(strend - scan);
|
||||
|
||||
@@ -1501,7 +1506,7 @@ local void check_match(s, start, match, length)
|
||||
z_error("invalid match");
|
||||
}
|
||||
if (z_verbose > 1) {
|
||||
fprintf(stderr,"\\[%d,%d]", start-match, length);
|
||||
fprintf(stderr,"\\[%d,%d]", start - match, length);
|
||||
do { putc(s->window[start++], stderr); } while (--length != 0);
|
||||
}
|
||||
}
|
||||
@@ -1547,9 +1552,9 @@ local void fill_window(s)
|
||||
/* If the window is almost full and there is insufficient lookahead,
|
||||
* move the upper half to the lower one to make room in the upper half.
|
||||
*/
|
||||
if (s->strstart >= wsize+MAX_DIST(s)) {
|
||||
if (s->strstart >= wsize + MAX_DIST(s)) {
|
||||
|
||||
zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
|
||||
zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
|
||||
s->match_start -= wsize;
|
||||
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
|
||||
s->block_start -= (long) wsize;
|
||||
@@ -1680,7 +1685,7 @@ local void fill_window(s)
|
||||
*
|
||||
* deflate_stored() is written to minimize the number of times an input byte is
|
||||
* copied. It is most efficient with large input and output buffers, which
|
||||
* maximizes the opportunites to have a single copy from next_in to next_out.
|
||||
* maximizes the opportunities to have a single copy from next_in to next_out.
|
||||
*/
|
||||
local block_state deflate_stored(s, flush)
|
||||
deflate_state *s;
|
||||
@@ -1890,7 +1895,7 @@ local block_state deflate_fast(s, flush)
|
||||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
}
|
||||
|
||||
/* Insert the string window[strstart .. strstart+2] in the
|
||||
/* Insert the string window[strstart .. strstart + 2] in the
|
||||
* dictionary, and set hash_head to the head of the hash chain:
|
||||
*/
|
||||
hash_head = NIL;
|
||||
@@ -1938,7 +1943,7 @@ local block_state deflate_fast(s, flush)
|
||||
s->strstart += s->match_length;
|
||||
s->match_length = 0;
|
||||
s->ins_h = s->window[s->strstart];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]);
|
||||
#if MIN_MATCH != 3
|
||||
Call UPDATE_HASH() MIN_MATCH-3 more times
|
||||
#endif
|
||||
@@ -1949,7 +1954,7 @@ local block_state deflate_fast(s, flush)
|
||||
} else {
|
||||
/* No match, output a literal byte */
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
_tr_tally_lit(s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
}
|
||||
@@ -1993,7 +1998,7 @@ local block_state deflate_slow(s, flush)
|
||||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
}
|
||||
|
||||
/* Insert the string window[strstart .. strstart+2] in the
|
||||
/* Insert the string window[strstart .. strstart + 2] in the
|
||||
* dictionary, and set hash_head to the head of the hash chain:
|
||||
*/
|
||||
hash_head = NIL;
|
||||
@@ -2035,17 +2040,17 @@ local block_state deflate_slow(s, flush)
|
||||
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
|
||||
/* Do not insert strings in hash table beyond this. */
|
||||
|
||||
check_match(s, s->strstart-1, s->prev_match, s->prev_length);
|
||||
check_match(s, s->strstart - 1, s->prev_match, s->prev_length);
|
||||
|
||||
_tr_tally_dist(s, s->strstart -1 - s->prev_match,
|
||||
_tr_tally_dist(s, s->strstart - 1 - s->prev_match,
|
||||
s->prev_length - MIN_MATCH, bflush);
|
||||
|
||||
/* Insert in hash table all strings up to the end of the match.
|
||||
* strstart-1 and strstart are already inserted. If there is not
|
||||
* strstart - 1 and strstart are already inserted. If there is not
|
||||
* enough lookahead, the last two strings are not inserted in
|
||||
* the hash table.
|
||||
*/
|
||||
s->lookahead -= s->prev_length-1;
|
||||
s->lookahead -= s->prev_length - 1;
|
||||
s->prev_length -= 2;
|
||||
do {
|
||||
if (++s->strstart <= max_insert) {
|
||||
@@ -2063,8 +2068,8 @@ local block_state deflate_slow(s, flush)
|
||||
* single literal. If there was a match but the current match
|
||||
* is longer, truncate the previous match to a single literal.
|
||||
*/
|
||||
Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||
Tracevv((stderr,"%c", s->window[s->strstart - 1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart - 1], bflush);
|
||||
if (bflush) {
|
||||
FLUSH_BLOCK_ONLY(s, 0);
|
||||
}
|
||||
@@ -2082,8 +2087,8 @@ local block_state deflate_slow(s, flush)
|
||||
}
|
||||
Assert (flush != Z_NO_FLUSH, "no flush?");
|
||||
if (s->match_available) {
|
||||
Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||
Tracevv((stderr,"%c", s->window[s->strstart - 1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart - 1], bflush);
|
||||
s->match_available = 0;
|
||||
}
|
||||
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||
@@ -2140,7 +2145,8 @@ local block_state deflate_rle(s, flush)
|
||||
if (s->match_length > s->lookahead)
|
||||
s->match_length = s->lookahead;
|
||||
}
|
||||
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
||||
Assert(scan <= s->window + (uInt)(s->window_size - 1),
|
||||
"wild scan");
|
||||
}
|
||||
|
||||
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||||
@@ -2155,7 +2161,7 @@ local block_state deflate_rle(s, flush)
|
||||
} else {
|
||||
/* No match, output a literal byte */
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
_tr_tally_lit(s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
}
|
||||
@@ -2195,7 +2201,7 @@ local block_state deflate_huff(s, flush)
|
||||
/* Output a literal byte */
|
||||
s->match_length = 0;
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
_tr_tally_lit(s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
|
||||
@@ -329,8 +329,8 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (uch)(length); \
|
||||
ush dist = (ush)(distance); \
|
||||
s->sym_buf[s->sym_next++] = dist; \
|
||||
s->sym_buf[s->sym_next++] = dist >> 8; \
|
||||
s->sym_buf[s->sym_next++] = (uch)dist; \
|
||||
s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \
|
||||
s->sym_buf[s->sym_next++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
||||
|
||||
@@ -30,7 +30,7 @@ local gzFile gz_open OF((const void *, int, const char *));
|
||||
|
||||
The gz_strwinerror function does not change the current setting of
|
||||
GetLastError. */
|
||||
char ZLIB_INTERNAL *gz_strwinerror (error)
|
||||
char ZLIB_INTERNAL *gz_strwinerror(error)
|
||||
DWORD error;
|
||||
{
|
||||
static char buf[1024];
|
||||
|
||||
@@ -157,11 +157,9 @@ local int gz_look(state)
|
||||
the output buffer is larger than the input buffer, which also assures
|
||||
space for gzungetc() */
|
||||
state->x.next = state->out;
|
||||
if (strm->avail_in) {
|
||||
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||
state->x.have = strm->avail_in;
|
||||
strm->avail_in = 0;
|
||||
}
|
||||
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||
state->x.have = strm->avail_in;
|
||||
strm->avail_in = 0;
|
||||
state->how = COPY;
|
||||
state->direct = 1;
|
||||
return 0;
|
||||
|
||||
@@ -474,7 +474,7 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
|
||||
#else /* !STDC && !Z_HAVE_STDARG_H */
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||
int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
gzFile file;
|
||||
const char *format;
|
||||
|
||||
@@ -66,6 +66,7 @@ int stream_size;
|
||||
state->window = window;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
state->sane = 1;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
@@ -605,25 +606,27 @@ void FAR *out_desc;
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
/* inflate stream terminated properly -- write leftover output */
|
||||
/* inflate stream terminated properly */
|
||||
ret = Z_STREAM_END;
|
||||
if (left < state->wsize) {
|
||||
if (out(out_desc, state->window, state->wsize - left))
|
||||
ret = Z_BUF_ERROR;
|
||||
}
|
||||
goto inf_leave;
|
||||
|
||||
case BAD:
|
||||
ret = Z_DATA_ERROR;
|
||||
goto inf_leave;
|
||||
|
||||
default: /* can't happen, but makes compilers happy */
|
||||
default:
|
||||
/* can't happen, but makes compilers happy */
|
||||
ret = Z_STREAM_ERROR;
|
||||
goto inf_leave;
|
||||
}
|
||||
|
||||
/* Return unused input */
|
||||
/* Write leftover output and return unused input */
|
||||
inf_leave:
|
||||
if (left < state->wsize) {
|
||||
if (out(out_desc, state->window, state->wsize - left) &&
|
||||
ret == Z_STREAM_END)
|
||||
ret = Z_BUF_ERROR;
|
||||
}
|
||||
strm->next_in = next;
|
||||
strm->avail_in = have;
|
||||
return ret;
|
||||
|
||||
@@ -168,6 +168,8 @@ int windowBits;
|
||||
|
||||
/* extract wrap request from windowBits parameter */
|
||||
if (windowBits < 0) {
|
||||
if (windowBits < -15)
|
||||
return Z_STREAM_ERROR;
|
||||
wrap = 0;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
@@ -765,8 +767,9 @@ int flush;
|
||||
if (copy > have) copy = have;
|
||||
if (copy) {
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->extra != Z_NULL) {
|
||||
len = state->head->extra_len - state->length;
|
||||
state->head->extra != Z_NULL &&
|
||||
(len = state->head->extra_len - state->length) <
|
||||
state->head->extra_max) {
|
||||
zmemcpy(state->head->extra + len, next,
|
||||
len + copy > state->head->extra_max ?
|
||||
state->head->extra_max - len : copy);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.12 Copyright 1995-2022 Mark Adler ";
|
||||
" inflate 1.2.13 Copyright 1995-2022 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@@ -62,7 +62,7 @@ unsigned short FAR *work;
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 202};
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct {
|
||||
/* Maximum size of the dynamic table. The maximum number of code structures is
|
||||
1444, which is the sum of 852 for literal/length codes and 592 for distance
|
||||
codes. These values were found by exhaustive searches using the program
|
||||
examples/enough.c found in the zlib distribtution. The arguments to that
|
||||
examples/enough.c found in the zlib distribution. The arguments to that
|
||||
program are the number of symbols, the initial root table size, and the
|
||||
maximum bit length of a code. "enough 286 9 15" for literal/length codes
|
||||
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
|
||||
|
||||
@@ -193,7 +193,7 @@ local void send_bits(s, value, length)
|
||||
s->bits_sent += (ulg)length;
|
||||
|
||||
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid))
|
||||
* unused bits in value.
|
||||
*/
|
||||
if (s->bi_valid > (int)Buf_size - length) {
|
||||
@@ -256,7 +256,7 @@ local void tr_static_init()
|
||||
length = 0;
|
||||
for (code = 0; code < LENGTH_CODES-1; code++) {
|
||||
base_length[code] = length;
|
||||
for (n = 0; n < (1<<extra_lbits[code]); n++) {
|
||||
for (n = 0; n < (1 << extra_lbits[code]); n++) {
|
||||
_length_code[length++] = (uch)code;
|
||||
}
|
||||
}
|
||||
@@ -265,13 +265,13 @@ local void tr_static_init()
|
||||
* in two different ways: code 284 + 5 bits or code 285, so we
|
||||
* overwrite length_code[255] to use the best encoding:
|
||||
*/
|
||||
_length_code[length-1] = (uch)code;
|
||||
_length_code[length - 1] = (uch)code;
|
||||
|
||||
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
|
||||
dist = 0;
|
||||
for (code = 0 ; code < 16; code++) {
|
||||
base_dist[code] = dist;
|
||||
for (n = 0; n < (1<<extra_dbits[code]); n++) {
|
||||
for (n = 0; n < (1 << extra_dbits[code]); n++) {
|
||||
_dist_code[dist++] = (uch)code;
|
||||
}
|
||||
}
|
||||
@@ -279,11 +279,11 @@ local void tr_static_init()
|
||||
dist >>= 7; /* from now on, all distances are divided by 128 */
|
||||
for ( ; code < D_CODES; code++) {
|
||||
base_dist[code] = dist << 7;
|
||||
for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
|
||||
for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
|
||||
_dist_code[256 + dist++] = (uch)code;
|
||||
}
|
||||
}
|
||||
Assert (dist == 256, "tr_static_init: 256+dist != 512");
|
||||
Assert (dist == 256, "tr_static_init: 256 + dist != 512");
|
||||
|
||||
/* Construct the codes of the static literal tree */
|
||||
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
|
||||
@@ -312,7 +312,7 @@ local void tr_static_init()
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Genererate the file trees.h describing the static trees.
|
||||
* Generate the file trees.h describing the static trees.
|
||||
*/
|
||||
#ifdef GEN_TREES_H
|
||||
# ifndef ZLIB_DEBUG
|
||||
@@ -321,7 +321,7 @@ local void tr_static_init()
|
||||
|
||||
# define SEPARATOR(i, last, width) \
|
||||
((i) == (last)? "\n};\n\n" : \
|
||||
((i) % (width) == (width)-1 ? ",\n" : ", "))
|
||||
((i) % (width) == (width) - 1 ? ",\n" : ", "))
|
||||
|
||||
void gen_trees_header()
|
||||
{
|
||||
@@ -458,7 +458,7 @@ local void pqdownheap(s, tree, k)
|
||||
while (j <= s->heap_len) {
|
||||
/* Set j to the smallest of the two sons: */
|
||||
if (j < s->heap_len &&
|
||||
smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
|
||||
smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) {
|
||||
j++;
|
||||
}
|
||||
/* Exit if v is smaller than both sons */
|
||||
@@ -507,7 +507,7 @@ local void gen_bitlen(s, desc)
|
||||
*/
|
||||
tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
|
||||
|
||||
for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
|
||||
for (h = s->heap_max + 1; h < HEAP_SIZE; h++) {
|
||||
n = s->heap[h];
|
||||
bits = tree[tree[n].Dad].Len + 1;
|
||||
if (bits > max_length) bits = max_length, overflow++;
|
||||
@@ -518,7 +518,7 @@ local void gen_bitlen(s, desc)
|
||||
|
||||
s->bl_count[bits]++;
|
||||
xbits = 0;
|
||||
if (n >= base) xbits = extra[n-base];
|
||||
if (n >= base) xbits = extra[n - base];
|
||||
f = tree[n].Freq;
|
||||
s->opt_len += (ulg)f * (unsigned)(bits + xbits);
|
||||
if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
|
||||
@@ -530,10 +530,10 @@ local void gen_bitlen(s, desc)
|
||||
|
||||
/* Find the first bit length which could increase: */
|
||||
do {
|
||||
bits = max_length-1;
|
||||
bits = max_length - 1;
|
||||
while (s->bl_count[bits] == 0) bits--;
|
||||
s->bl_count[bits]--; /* move one leaf down the tree */
|
||||
s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
|
||||
s->bl_count[bits]--; /* move one leaf down the tree */
|
||||
s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */
|
||||
s->bl_count[max_length]--;
|
||||
/* The brother of the overflow item also moves one step up,
|
||||
* but this does not affect bl_count[max_length]
|
||||
@@ -569,7 +569,7 @@ local void gen_bitlen(s, desc)
|
||||
* OUT assertion: the field code is set for all tree elements of non
|
||||
* zero code length.
|
||||
*/
|
||||
local void gen_codes (tree, max_code, bl_count)
|
||||
local void gen_codes(tree, max_code, bl_count)
|
||||
ct_data *tree; /* the tree to decorate */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
ushf *bl_count; /* number of codes at each bit length */
|
||||
@@ -583,13 +583,13 @@ local void gen_codes (tree, max_code, bl_count)
|
||||
* without bit reversal.
|
||||
*/
|
||||
for (bits = 1; bits <= MAX_BITS; bits++) {
|
||||
code = (code + bl_count[bits-1]) << 1;
|
||||
code = (code + bl_count[bits - 1]) << 1;
|
||||
next_code[bits] = (ush)code;
|
||||
}
|
||||
/* Check that the bit counts in bl_count are consistent. The last code
|
||||
* must be all ones.
|
||||
*/
|
||||
Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
|
||||
Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
|
||||
"inconsistent bit counts");
|
||||
Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
|
||||
|
||||
@@ -600,7 +600,7 @@ local void gen_codes (tree, max_code, bl_count)
|
||||
tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
|
||||
|
||||
Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
|
||||
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
|
||||
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,7 +624,7 @@ local void build_tree(s, desc)
|
||||
int node; /* new node being created */
|
||||
|
||||
/* Construct the initial heap, with least frequent element in
|
||||
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
|
||||
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1].
|
||||
* heap[0] is not used.
|
||||
*/
|
||||
s->heap_len = 0, s->heap_max = HEAP_SIZE;
|
||||
@@ -652,7 +652,7 @@ local void build_tree(s, desc)
|
||||
}
|
||||
desc->max_code = max_code;
|
||||
|
||||
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
|
||||
/* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree,
|
||||
* establish sub-heaps of increasing lengths:
|
||||
*/
|
||||
for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
|
||||
@@ -700,7 +700,7 @@ local void build_tree(s, desc)
|
||||
* Scan a literal or distance tree to determine the frequencies of the codes
|
||||
* in the bit length tree.
|
||||
*/
|
||||
local void scan_tree (s, tree, max_code)
|
||||
local void scan_tree(s, tree, max_code)
|
||||
deflate_state *s;
|
||||
ct_data *tree; /* the tree to be scanned */
|
||||
int max_code; /* and its largest code of non zero frequency */
|
||||
@@ -714,10 +714,10 @@ local void scan_tree (s, tree, max_code)
|
||||
int min_count = 4; /* min repeat count */
|
||||
|
||||
if (nextlen == 0) max_count = 138, min_count = 3;
|
||||
tree[max_code+1].Len = (ush)0xffff; /* guard */
|
||||
tree[max_code + 1].Len = (ush)0xffff; /* guard */
|
||||
|
||||
for (n = 0; n <= max_code; n++) {
|
||||
curlen = nextlen; nextlen = tree[n+1].Len;
|
||||
curlen = nextlen; nextlen = tree[n + 1].Len;
|
||||
if (++count < max_count && curlen == nextlen) {
|
||||
continue;
|
||||
} else if (count < min_count) {
|
||||
@@ -745,7 +745,7 @@ local void scan_tree (s, tree, max_code)
|
||||
* Send a literal or distance tree in compressed form, using the codes in
|
||||
* bl_tree.
|
||||
*/
|
||||
local void send_tree (s, tree, max_code)
|
||||
local void send_tree(s, tree, max_code)
|
||||
deflate_state *s;
|
||||
ct_data *tree; /* the tree to be scanned */
|
||||
int max_code; /* and its largest code of non zero frequency */
|
||||
@@ -758,11 +758,11 @@ local void send_tree (s, tree, max_code)
|
||||
int max_count = 7; /* max repeat count */
|
||||
int min_count = 4; /* min repeat count */
|
||||
|
||||
/* tree[max_code+1].Len = -1; */ /* guard already set */
|
||||
/* tree[max_code + 1].Len = -1; */ /* guard already set */
|
||||
if (nextlen == 0) max_count = 138, min_count = 3;
|
||||
|
||||
for (n = 0; n <= max_code; n++) {
|
||||
curlen = nextlen; nextlen = tree[n+1].Len;
|
||||
curlen = nextlen; nextlen = tree[n + 1].Len;
|
||||
if (++count < max_count && curlen == nextlen) {
|
||||
continue;
|
||||
} else if (count < min_count) {
|
||||
@@ -773,13 +773,13 @@ local void send_tree (s, tree, max_code)
|
||||
send_code(s, curlen, s->bl_tree); count--;
|
||||
}
|
||||
Assert(count >= 3 && count <= 6, " 3_6?");
|
||||
send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
|
||||
send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2);
|
||||
|
||||
} else if (count <= 10) {
|
||||
send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
|
||||
send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3);
|
||||
|
||||
} else {
|
||||
send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
|
||||
send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7);
|
||||
}
|
||||
count = 0; prevlen = curlen;
|
||||
if (nextlen == 0) {
|
||||
@@ -807,8 +807,8 @@ local int build_bl_tree(s)
|
||||
|
||||
/* Build the bit length tree: */
|
||||
build_tree(s, (tree_desc *)(&(s->bl_desc)));
|
||||
/* opt_len now includes the length of the tree representations, except
|
||||
* the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
|
||||
/* opt_len now includes the length of the tree representations, except the
|
||||
* lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts.
|
||||
*/
|
||||
|
||||
/* Determine the number of bit length codes to send. The pkzip format
|
||||
@@ -819,7 +819,7 @@ local int build_bl_tree(s)
|
||||
if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
|
||||
}
|
||||
/* Update opt_len to include the bit length tree and counts */
|
||||
s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
|
||||
s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4;
|
||||
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
|
||||
s->opt_len, s->static_len));
|
||||
|
||||
@@ -841,19 +841,19 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
|
||||
Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
|
||||
"too many codes");
|
||||
Tracev((stderr, "\nbl counts: "));
|
||||
send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
|
||||
send_bits(s, dcodes-1, 5);
|
||||
send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
|
||||
send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
|
||||
send_bits(s, dcodes - 1, 5);
|
||||
send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
|
||||
for (rank = 0; rank < blcodes; rank++) {
|
||||
Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
|
||||
send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
|
||||
}
|
||||
Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
|
||||
|
||||
send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
|
||||
send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */
|
||||
Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
|
||||
|
||||
send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
|
||||
send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */
|
||||
Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
|
||||
}
|
||||
|
||||
@@ -866,7 +866,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
||||
ulg stored_len; /* length of input block */
|
||||
int last; /* one if this is the last block for a file */
|
||||
{
|
||||
send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
|
||||
send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */
|
||||
bi_windup(s); /* align on byte boundary */
|
||||
put_short(s, (ush)stored_len);
|
||||
put_short(s, (ush)~stored_len);
|
||||
@@ -877,7 +877,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
||||
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
|
||||
s->compressed_len += (stored_len + 4) << 3;
|
||||
s->bits_sent += 2*16;
|
||||
s->bits_sent += stored_len<<3;
|
||||
s->bits_sent += stored_len << 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -943,14 +943,17 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
max_blindex = build_bl_tree(s);
|
||||
|
||||
/* Determine the best encoding. Compute the block lengths in bytes. */
|
||||
opt_lenb = (s->opt_len+3+7)>>3;
|
||||
static_lenb = (s->static_len+3+7)>>3;
|
||||
opt_lenb = (s->opt_len + 3 + 7) >> 3;
|
||||
static_lenb = (s->static_len + 3 + 7) >> 3;
|
||||
|
||||
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
|
||||
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
||||
s->sym_next / 3));
|
||||
|
||||
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
|
||||
#ifndef FORCE_STATIC
|
||||
if (static_lenb <= opt_lenb || s->strategy == Z_FIXED)
|
||||
#endif
|
||||
opt_lenb = static_lenb;
|
||||
|
||||
} else {
|
||||
Assert(buf != (char*)0, "lost buf");
|
||||
@@ -960,7 +963,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
#ifdef FORCE_STORED
|
||||
if (buf != (char*)0) { /* force stored block */
|
||||
#else
|
||||
if (stored_len+4 <= opt_lenb && buf != (char*)0) {
|
||||
if (stored_len + 4 <= opt_lenb && buf != (char*)0) {
|
||||
/* 4: two words for the lengths */
|
||||
#endif
|
||||
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
|
||||
@@ -971,21 +974,17 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
*/
|
||||
_tr_stored_block(s, buf, stored_len, last);
|
||||
|
||||
#ifdef FORCE_STATIC
|
||||
} else if (static_lenb >= 0) { /* force static trees */
|
||||
#else
|
||||
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
|
||||
#endif
|
||||
send_bits(s, (STATIC_TREES<<1)+last, 3);
|
||||
} else if (static_lenb == opt_lenb) {
|
||||
send_bits(s, (STATIC_TREES<<1) + last, 3);
|
||||
compress_block(s, (const ct_data *)static_ltree,
|
||||
(const ct_data *)static_dtree);
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len += 3 + s->static_len;
|
||||
#endif
|
||||
} else {
|
||||
send_bits(s, (DYN_TREES<<1)+last, 3);
|
||||
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
||||
max_blindex+1);
|
||||
send_bits(s, (DYN_TREES<<1) + last, 3);
|
||||
send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1,
|
||||
max_blindex + 1);
|
||||
compress_block(s, (const ct_data *)s->dyn_ltree,
|
||||
(const ct_data *)s->dyn_dtree);
|
||||
#ifdef ZLIB_DEBUG
|
||||
@@ -1004,22 +1003,22 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
s->compressed_len += 7; /* align on byte boundary */
|
||||
#endif
|
||||
}
|
||||
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
||||
s->compressed_len-7*last));
|
||||
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3,
|
||||
s->compressed_len - 7*last));
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Save the match info and tally the frequency counts. Return true if
|
||||
* the current block must be flushed.
|
||||
*/
|
||||
int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
int ZLIB_INTERNAL _tr_tally(s, dist, lc)
|
||||
deflate_state *s;
|
||||
unsigned dist; /* distance of matched string */
|
||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
unsigned lc; /* match length - MIN_MATCH or unmatched char (dist==0) */
|
||||
{
|
||||
s->sym_buf[s->sym_next++] = dist;
|
||||
s->sym_buf[s->sym_next++] = dist >> 8;
|
||||
s->sym_buf[s->sym_next++] = lc;
|
||||
s->sym_buf[s->sym_next++] = (uch)dist;
|
||||
s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
|
||||
s->sym_buf[s->sym_next++] = (uch)lc;
|
||||
if (dist == 0) {
|
||||
/* lc is the unmatched char */
|
||||
s->dyn_ltree[lc].Freq++;
|
||||
@@ -1031,7 +1030,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
|
||||
(ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
|
||||
|
||||
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
|
||||
s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++;
|
||||
s->dyn_dtree[d_code(dist)].Freq++;
|
||||
}
|
||||
return (s->sym_next == s->sym_end);
|
||||
@@ -1061,7 +1060,7 @@ local void compress_block(s, ltree, dtree)
|
||||
} else {
|
||||
/* Here, lc is the match length - MIN_MATCH */
|
||||
code = _length_code[lc];
|
||||
send_code(s, code+LITERALS+1, ltree); /* send the length code */
|
||||
send_code(s, code + LITERALS + 1, ltree); /* send length code */
|
||||
extra = extra_lbits[code];
|
||||
if (extra != 0) {
|
||||
lc -= base_length[code];
|
||||
@@ -1177,6 +1176,6 @@ local void bi_windup(s)
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->bits_sent = (s->bits_sent+7) & ~7;
|
||||
s->bits_sent = (s->bits_sent + 7) & ~7;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
Z_DATA_ERROR if the input data was corrupted, including if the input data is
|
||||
an incomplete zlib stream.
|
||||
*/
|
||||
int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
|
||||
int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
@@ -83,7 +83,7 @@ int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
|
||||
err;
|
||||
}
|
||||
|
||||
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
||||
int ZEXPORT uncompress(dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define crc32_combine_gen z_crc32_combine_gen
|
||||
# define crc32_combine_gen64 z_crc32_combine_gen64
|
||||
# define crc32_combine_op z_crc32_combine_op
|
||||
# define crc32_z z_crc32_z
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
@@ -349,6 +352,9 @@
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
@@ -467,11 +473,18 @@ typedef uLong FAR uLongf;
|
||||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# ifdef __WATCOMC__
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# if defined(Z_HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.12, March 11th, 2022
|
||||
version 1.2.13, October 13th, 2022
|
||||
|
||||
Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.2.12"
|
||||
#define ZLIB_VERNUM 0x12c0
|
||||
#define ZLIB_VERSION "1.2.13"
|
||||
#define ZLIB_VERNUM 0x12d0
|
||||
#define ZLIB_VER_MAJOR 1
|
||||
#define ZLIB_VER_MINOR 2
|
||||
#define ZLIB_VER_REVISION 12
|
||||
#define ZLIB_VER_REVISION 13
|
||||
#define ZLIB_VER_SUBREVISION 0
|
||||
|
||||
/*
|
||||
@@ -276,7 +276,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
== 0), or after each call of deflate(). If deflate returns Z_OK and with
|
||||
zero avail_out, it must be called again after making room in the output
|
||||
buffer because there might be more output pending. See deflatePending(),
|
||||
which can be used if desired to determine whether or not there is more ouput
|
||||
which can be used if desired to determine whether or not there is more output
|
||||
in that case.
|
||||
|
||||
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
|
||||
@@ -660,7 +660,7 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
|
||||
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||
always enough. If deflateGetDictionary() is called with dictionary equal to
|
||||
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||
Similary, if dictLength is Z_NULL, then it is not set.
|
||||
Similarly, if dictLength is Z_NULL, then it is not set.
|
||||
|
||||
deflateGetDictionary() may return a length less than the window size, even
|
||||
when more than the window size in input has been provided. It may return up
|
||||
@@ -915,7 +915,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
|
||||
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||
always enough. If inflateGetDictionary() is called with dictionary equal to
|
||||
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||
Similary, if dictLength is Z_NULL, then it is not set.
|
||||
Similarly, if dictLength is Z_NULL, then it is not set.
|
||||
|
||||
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
|
||||
stream state is inconsistent.
|
||||
@@ -1437,12 +1437,12 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
|
||||
|
||||
In the event that the end of file is reached and only a partial item is
|
||||
available at the end, i.e. the remaining uncompressed data length is not a
|
||||
multiple of size, then the final partial item is nevetheless read into buf
|
||||
multiple of size, then the final partial item is nevertheless read into buf
|
||||
and the end-of-file flag is set. The length of the partial item read is not
|
||||
provided, but could be inferred from the result of gztell(). This behavior
|
||||
is the same as the behavior of fread() implementations in common libraries,
|
||||
but it prevents the direct use of gzfread() to read a concurrently written
|
||||
file, reseting and retrying on end-of-file, when size is not 1.
|
||||
file, resetting and retrying on end-of-file, when size is not 1.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
|
||||
@@ -1913,7 +1913,7 @@ ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
||||
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
|
||||
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
||||
ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
|
||||
ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
|
||||
ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp));
|
||||
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
|
||||
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
|
||||
#if defined(_WIN32) && !defined(Z_SOLO)
|
||||
|
||||
@@ -61,9 +61,11 @@ uLong ZEXPORT zlibCompileFlags()
|
||||
#ifdef ZLIB_DEBUG
|
||||
flags += 1 << 8;
|
||||
#endif
|
||||
/*
|
||||
#if defined(ASMV) || defined(ASMINF)
|
||||
flags += 1 << 9;
|
||||
#endif
|
||||
*/
|
||||
#ifdef ZLIB_WINAPI
|
||||
flags += 1 << 10;
|
||||
#endif
|
||||
@@ -119,7 +121,7 @@ uLong ZEXPORT zlibCompileFlags()
|
||||
# endif
|
||||
int ZLIB_INTERNAL z_verbose = verbose;
|
||||
|
||||
void ZLIB_INTERNAL z_error (m)
|
||||
void ZLIB_INTERNAL z_error(m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
@@ -214,7 +216,7 @@ local ptr_table table[MAX_PTR];
|
||||
* a protected system like OS/2. Use Microsoft C instead.
|
||||
*/
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
voidpf buf;
|
||||
ulg bsize = (ulg)items*size;
|
||||
@@ -240,7 +242,7 @@ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
return buf;
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
int n;
|
||||
|
||||
@@ -277,13 +279,13 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
# define _hfree hfree
|
||||
#endif
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
|
||||
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
(void)opaque;
|
||||
return _halloc((long)items, size);
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
(void)opaque;
|
||||
_hfree(ptr);
|
||||
@@ -302,7 +304,7 @@ extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
||||
voidpf ZLIB_INTERNAL zcalloc(opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
@@ -312,7 +314,7 @@ voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
||||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||
void ZLIB_INTERNAL zcfree(opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
|
||||
@@ -193,6 +193,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
||||
@@ -86,6 +86,9 @@ int main( int argc, const char** argv )
|
||||
"{ image i | | (required) path to reference image }"
|
||||
"{ model m | | (required) path to cascade xml file }"
|
||||
"{ data d | | (optional) path to video output folder }"
|
||||
"{ ext | avi | (optional) output video file extension e.g. avi (default) or mp4 }"
|
||||
"{ fourcc | XVID | (optional) output video file's 4-character codec e.g. XVID (default) or H264 }"
|
||||
"{ fps | 15 | (optional) output video file's frames-per-second rate }"
|
||||
);
|
||||
// Read in the input arguments
|
||||
if (parser.has("help")){
|
||||
@@ -96,7 +99,9 @@ int main( int argc, const char** argv )
|
||||
string model(parser.get<string>("model"));
|
||||
string output_folder(parser.get<string>("data"));
|
||||
string image_ref = (parser.get<string>("image"));
|
||||
if (model.empty() || image_ref.empty()){
|
||||
string fourcc = (parser.get<string>("fourcc"));
|
||||
int fps = parser.get<int>("fps");
|
||||
if (model.empty() || image_ref.empty() || fourcc.size()!=4 || fps<1){
|
||||
parser.printMessage();
|
||||
printLimits();
|
||||
return -1;
|
||||
@@ -166,11 +171,19 @@ int main( int argc, const char** argv )
|
||||
// each stage, containing all weak classifiers for that stage.
|
||||
bool draw_planes = false;
|
||||
stringstream output_video;
|
||||
output_video << output_folder << "model_visualization.avi";
|
||||
output_video << output_folder << "model_visualization." << parser.get<string>("ext");
|
||||
VideoWriter result_video;
|
||||
if( output_folder.compare("") != 0 ){
|
||||
draw_planes = true;
|
||||
result_video.open(output_video.str(), VideoWriter::fourcc('X','V','I','D'), 15, Size(reference_image.cols * resize_factor, reference_image.rows * resize_factor), false);
|
||||
result_video.open(output_video.str(), VideoWriter::fourcc(fourcc[0],fourcc[1],fourcc[2],fourcc[3]), fps, visualization.size(), false);
|
||||
if (!result_video.isOpened()){
|
||||
cerr << "the output video '" << output_video.str() << "' could not be opened."
|
||||
<< " fourcc=" << fourcc
|
||||
<< " fps=" << fps
|
||||
<< " frameSize=" << visualization.size()
|
||||
<< endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(haar){
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
set(CPU_ALL_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;SSE4_2;POPCNT;AVX;FP16;AVX2;FMA3;AVX_512F")
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS "AVX512_COMMON;AVX512_KNL;AVX512_KNM;AVX512_SKX;AVX512_CNL;AVX512_CLX;AVX512_ICL")
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS NEON VFPV3 FP16)
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS NEON VFPV3 FP16 NEON_DOTPROD)
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS MSA)
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS VSX VSX3)
|
||||
list(REMOVE_DUPLICATES CPU_ALL_OPTIMIZATIONS)
|
||||
@@ -326,6 +326,7 @@ if(X86 OR X86_64)
|
||||
elseif(ARM OR AARCH64)
|
||||
ocv_update(CPU_NEON_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_neon.cpp")
|
||||
ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
|
||||
ocv_update(CPU_NEON_DOTPROD_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_dotprod.cpp")
|
||||
if(NOT AARCH64)
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "VFPV3;NEON;FP16")
|
||||
if(NOT MSVC)
|
||||
@@ -337,9 +338,11 @@ elseif(ARM OR AARCH64)
|
||||
endif()
|
||||
ocv_update(CPU_FP16_IMPLIES "NEON")
|
||||
else()
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "NEON;FP16")
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "NEON;FP16;NEON_DOTPROD")
|
||||
ocv_update(CPU_NEON_FLAGS_ON "")
|
||||
ocv_update(CPU_FP16_IMPLIES "NEON")
|
||||
ocv_update(CPU_NEON_DOTPROD_FLAGS_ON "-march=armv8.2-a+dotprod")
|
||||
ocv_update(CPU_NEON_DOTPROD_IMPLIES "NEON")
|
||||
set(CPU_BASELINE "NEON;FP16" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
endif()
|
||||
elseif(MIPS)
|
||||
@@ -677,7 +680,7 @@ macro(ocv_compiler_optimization_process_sources SOURCES_VAR_NAME LIBS_VAR_NAME T
|
||||
if(fname_LOWER MATCHES "\\.${OPT_LOWER}\\.cpp$")
|
||||
#message("${fname} BASELINE-${OPT}")
|
||||
set(__opt_found 1)
|
||||
list(APPEND __result "${fname}")
|
||||
list(APPEND __result_${OPT} "${fname}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -711,7 +714,7 @@ macro(ocv_compiler_optimization_process_sources SOURCES_VAR_NAME LIBS_VAR_NAME T
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPT ${CPU_DISPATCH_FINAL})
|
||||
foreach(OPT ${CPU_BASELINE_FINAL} ${CPU_DISPATCH_FINAL})
|
||||
if(__result_${OPT})
|
||||
#message("${OPT}: ${__result_${OPT}}")
|
||||
if(CMAKE_GENERATOR MATCHES "^Visual"
|
||||
|
||||
@@ -134,7 +134,7 @@ if(CV_GCC OR CV_CLANG)
|
||||
add_extra_compiler_option(-Wshadow)
|
||||
add_extra_compiler_option(-Wsign-promo)
|
||||
add_extra_compiler_option(-Wuninitialized)
|
||||
if(CV_GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0) AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
|
||||
if(CV_GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0) AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0 OR ARM))
|
||||
add_extra_compiler_option(-Wno-psabi)
|
||||
endif()
|
||||
if(HAVE_CXX11)
|
||||
@@ -426,6 +426,7 @@ if(MSVC)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4275) # non dll-interface class 'std::exception' used as base for dll-interface class 'cv::Exception'
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4512) # Assignment operator could not be generated
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4589) # Constructor of abstract class 'cv::ORB' ignores initializer for virtual base class 'cv::Algorithm'
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4819) # Symbols like delta or epsilon cannot be represented
|
||||
endif()
|
||||
|
||||
if(CV_ICC AND NOT ENABLE_NOISY_WARNINGS)
|
||||
|
||||
@@ -243,12 +243,13 @@ if(CUDA_FOUND)
|
||||
endif()
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
# TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0)
|
||||
# TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0) Orin (8.7)
|
||||
ocv_filter_available_architecture(__cuda_arch_bin
|
||||
5.3
|
||||
6.2
|
||||
7.2
|
||||
7.0
|
||||
8.7
|
||||
)
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
cmake_minimum_required(VERSION ${MIN_VER_CMAKE})
|
||||
|
||||
if(" ${HALIDE_ROOT_DIR}" STREQUAL " ")
|
||||
unset(HALIDE_ROOT_DIR CACHE)
|
||||
|
||||
@@ -866,7 +866,10 @@ macro(ocv_check_modules define)
|
||||
foreach(flag ${${define}_LDFLAGS})
|
||||
if(flag MATCHES "^-L(.*)")
|
||||
list(APPEND _libs_paths ${CMAKE_MATCH_1})
|
||||
elseif(IS_ABSOLUTE "${flag}")
|
||||
elseif(IS_ABSOLUTE "${flag}"
|
||||
OR flag STREQUAL "-lstdc++"
|
||||
OR flag STREQUAL "-latomic"
|
||||
)
|
||||
list(APPEND _libs "${flag}")
|
||||
elseif(flag MATCHES "^-l(.*)")
|
||||
set(_lib "${CMAKE_MATCH_1}")
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined __GNUC__ && (defined __arm__ || defined __aarch64__)
|
||||
#include "arm_neon.h"
|
||||
int test()
|
||||
{
|
||||
const unsigned int src[] = { 0, 0, 0, 0 };
|
||||
unsigned int dst[4];
|
||||
uint32x4_t v_src = *(uint32x4_t*)src;
|
||||
uint8x16_t v_m0 = *(uint8x16_t*)src;
|
||||
uint8x16_t v_m1 = *(uint8x16_t*)src;
|
||||
uint32x4_t v_dst = vdotq_u32(v_src, v_m0, v_m1);
|
||||
*(uint32x4_t*)dst = v_dst;
|
||||
return (int)dst[0];
|
||||
}
|
||||
#else
|
||||
#error "DOTPROD is not supported"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("%d\n", test());
|
||||
return 0;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ We will see each one of them.
|
||||
|
||||
### 1. Sobel and Scharr Derivatives
|
||||
|
||||
Sobel operators is a joint Gausssian smoothing plus differentiation operation, so it is more
|
||||
Sobel operators is a joint Gaussian smoothing plus differentiation operation, so it is more
|
||||
resistant to noise. You can specify the direction of derivatives to be taken, vertical or horizontal
|
||||
(by the arguments, yorder and xorder respectively). You can also specify the size of kernel by the
|
||||
argument ksize. If ksize = -1, a 3x3 Scharr filter is used which gives better results than 3x3 Sobel
|
||||
@@ -97,4 +97,4 @@ Try it
|
||||
<iframe src="../../js_gradients_absSobel.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
\endhtmlonly
|
||||
|
||||
@@ -232,7 +232,7 @@ The following is an adaptation of @ref tutorial_js_face_detection.
|
||||
@code{.js}
|
||||
const { Canvas, createCanvas, Image, ImageData, loadImage } = require('canvas');
|
||||
const { JSDOM } = require('jsdom');
|
||||
const { writeFileSync, readFileSync } = require('fs');
|
||||
const { writeFileSync, existsSync, mkdirSync } = require('fs');
|
||||
|
||||
(async () => {
|
||||
await loadOpenCV();
|
||||
|
||||
@@ -8,14 +8,18 @@
|
||||
url = {https://www.doc.ic.ac.uk/~ajd/Publications/alcantarilla_etal_eccv2012.pdf}
|
||||
}
|
||||
@article{ANB13,
|
||||
author = {Alcantarilla, Pablo F and Nuevo, Jes{\'u}s and Bartoli, Adrien},
|
||||
author = {Pablo Fern{\'{a}}ndez Alcantarilla and Jes{\'{u}}s Nuevo and Adrien Bartoli},
|
||||
editor = {Tilo Burghardt and Dima Damen and Walterio W. Mayol{-}Cuevas and Majid Mirmehdi},
|
||||
title = {Fast Explicit Diffusion for Accelerated Features in Nonlinear Scale Spaces},
|
||||
year = {2011},
|
||||
pages = {1281--1298},
|
||||
journal = {Trans. Pattern Anal. Machine Intell},
|
||||
volume = {34},
|
||||
number = {7},
|
||||
url = {http://www.bmva.org/bmvc/2013/Papers/paper0013/paper0013.pdf}
|
||||
booktitle = {British Machine Vision Conference, {BMVC} 2013, Bristol, UK, September 9-13, 2013},
|
||||
pages = {13.1--13.11},
|
||||
publisher = {{BMVA} Press},
|
||||
year = {2013},
|
||||
url = {https://doi.org/10.5244/C.27.13},
|
||||
doi = {10.5244/C.27.13},
|
||||
timestamp = {Sat, 09 Apr 2022 12:44:13 +0200},
|
||||
biburl = {https://dblp.org/rec/conf/bmvc/AlcantarillaNB13.bib},
|
||||
bibsource = {dblp computer science bibliography, https://dblp.org}
|
||||
}
|
||||
@inproceedings{Andreff99,
|
||||
author = {Andreff, Nicolas and Horaud, Radu and Espiau, Bernard},
|
||||
@@ -543,7 +547,7 @@
|
||||
title = {Multiple view geometry in computer vision},
|
||||
year = {2003},
|
||||
publisher = {Cambridge university press},
|
||||
url = {http://cds.cern.ch/record/1598612/files/0521540518_TOC.pdf}
|
||||
url = {https://www.robots.ox.ac.uk/~vgg/hzbook/}
|
||||
}
|
||||
@article{Horaud95,
|
||||
author = {Horaud, Radu and Dornaika, Fadi},
|
||||
@@ -745,10 +749,17 @@
|
||||
isbn = {0387008934},
|
||||
publisher = {Springer}
|
||||
}
|
||||
@article{Malis,
|
||||
author = {Malis, Ezio and Vargas, Manuel and others},
|
||||
title = {Deeper understanding of the homography decomposition for vision-based control},
|
||||
year = {2007}
|
||||
@article{Malis2007,
|
||||
author = {Malis, Ezio and Vargas, Manuel},
|
||||
title = {{Deeper understanding of the homography decomposition for vision-based control}},
|
||||
year = {2007},
|
||||
url = {https://hal.inria.fr/inria-00174036},
|
||||
type = {Research Report},
|
||||
number = {RR-6303},
|
||||
pages = {90},
|
||||
institution = {{INRIA}},
|
||||
keywords = {Visual servoing ; planar objects ; homography ; decomposition ; camera calibration errors ; structure from motion ; Euclidean},
|
||||
pdf = {https://hal.inria.fr/inria-00174036v3/file/RR-6303.pdf},
|
||||
}
|
||||
@article{Marchand16,
|
||||
author = {Marchand, Eric and Uchiyama, Hideaki and Spindler, Fabien},
|
||||
@@ -905,7 +916,8 @@
|
||||
author = {Szeliski, Richard},
|
||||
title = {Computer vision: algorithms and applications},
|
||||
year = {2010},
|
||||
publisher = {Springer}
|
||||
publisher = {Springer},
|
||||
url = {https://szeliski.org/Book/}
|
||||
}
|
||||
@article{Rafael12,
|
||||
author = {von Gioi, Rafael Grompone and Jakubowicz, J{\'e}r{\'e}mie and Morel, Jean-Michel and Randall, Gregory},
|
||||
|
||||
@@ -127,7 +127,7 @@ for fname in images:
|
||||
objpoints.append(objp)
|
||||
|
||||
corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
|
||||
imgpoints.append(corners)
|
||||
imgpoints.append(corners2)
|
||||
|
||||
# Draw and display the corners
|
||||
cv.drawChessboardCorners(img, (7,6), corners2, ret)
|
||||
|
||||
@@ -14,7 +14,7 @@ So in this chapter, you will learn:
|
||||
Apart from OpenCV, Python also provides a module **time** which is helpful in measuring the time of
|
||||
execution. Another module **profile** helps to get a detailed report on the code, like how much time
|
||||
each function in the code took, how many times the function was called, etc. But, if you are using
|
||||
IPython, all these features are integrated in an user-friendly manner. We will see some important
|
||||
IPython, all these features are integrated in a user-friendly manner. We will see some important
|
||||
ones, and for more details, check links in the **Additional Resources** section.
|
||||
|
||||
Measuring Performance with OpenCV
|
||||
|
||||
@@ -17,7 +17,7 @@ We will see each one of them.
|
||||
|
||||
### 1. Sobel and Scharr Derivatives
|
||||
|
||||
Sobel operators is a joint Gausssian smoothing plus differentiation operation, so it is more
|
||||
Sobel operators is a joint Gaussian smoothing plus differentiation operation, so it is more
|
||||
resistant to noise. You can specify the direction of derivatives to be taken, vertical or horizontal
|
||||
(by the arguments, yorder and xorder respectively). You can also specify the size of kernel by the
|
||||
argument ksize. If ksize = -1, a 3x3 Scharr filter is used which gives better results than 3x3 Sobel
|
||||
|
||||
@@ -10,9 +10,11 @@ Introduction {#tutorial_homography_Introduction}
|
||||
|
||||
This tutorial will demonstrate the basic concepts of the homography with some codes.
|
||||
For detailed explanations about the theory, please refer to a computer vision course or a computer vision book, e.g.:
|
||||
* Multiple View Geometry in Computer Vision, @cite HartleyZ00.
|
||||
* An Invitation to 3-D Vision: From Images to Geometric Models, @cite Ma:2003:IVI
|
||||
* Computer Vision: Algorithms and Applications, @cite RS10
|
||||
* Multiple View Geometry in Computer Vision, Richard Hartley and Andrew Zisserman, @cite HartleyZ00 (some sample chapters are available [here](https://www.robots.ox.ac.uk/~vgg/hzbook/), CVPR Tutorials are available [here](https://www.robots.ox.ac.uk/~az/tutorials/))
|
||||
* An Invitation to 3-D Vision: From Images to Geometric Models, Yi Ma, Stefano Soatto, Jana Kosecka, and S. Shankar Sastry, @cite Ma:2003:IVI (a computer vision book handout is available [here](https://cs.gmu.edu/%7Ekosecka/cs685/VisionBookHandout.pdf))
|
||||
* Computer Vision: Algorithms and Applications, Richard Szeliski, @cite RS10 (an electronic version is available [here](https://szeliski.org/Book/))
|
||||
* Deeper understanding of the homography decomposition for vision-based control, Ezio Malis, Manuel Vargas, @cite Malis2007 (open access [here](https://hal.inria.fr/inria-00174036))
|
||||
* Pose Estimation for Augmented Reality: A Hands-On Survey, Eric Marchand, Hideaki Uchiyama, Fabien Spindler, @cite Marchand16 (open access [here](https://hal.inria.fr/hal-01246370))
|
||||
|
||||
The tutorial code can be found here [C++](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/features2D/Homography),
|
||||
[Python](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/features2D/Homography),
|
||||
@@ -32,7 +34,7 @@ Briefly, the planar homography relates the transformation between two planes (up
|
||||
x^{'} \\
|
||||
y^{'} \\
|
||||
1
|
||||
\end{bmatrix} = H
|
||||
\end{bmatrix} = \mathbf{H}
|
||||
\begin{bmatrix}
|
||||
x \\
|
||||
y \\
|
||||
@@ -123,22 +125,22 @@ A quick solution to retrieve the pose from the homography matrix is (see \ref po
|
||||
|
||||
\f[
|
||||
\begin{align*}
|
||||
\boldsymbol{X} &= \left( X, Y, 0, 1 \right ) \\
|
||||
\boldsymbol{x} &= \boldsymbol{P}\boldsymbol{X} \\
|
||||
&= \boldsymbol{K} \left[ \boldsymbol{r_1} \hspace{0.5em} \boldsymbol{r_2} \hspace{0.5em} \boldsymbol{r_3} \hspace{0.5em} \boldsymbol{t} \right ]
|
||||
\mathbf{X} &= \left( X, Y, 0, 1 \right ) \\
|
||||
\mathbf{x} &= \mathbf{P}\mathbf{X} \\
|
||||
&= \mathbf{K} \left[ \mathbf{r_1} \hspace{0.5em} \mathbf{r_2} \hspace{0.5em} \mathbf{r_3} \hspace{0.5em} \mathbf{t} \right ]
|
||||
\begin{pmatrix}
|
||||
X \\
|
||||
Y \\
|
||||
0 \\
|
||||
1
|
||||
\end{pmatrix} \\
|
||||
&= \boldsymbol{K} \left[ \boldsymbol{r_1} \hspace{0.5em} \boldsymbol{r_2} \hspace{0.5em} \boldsymbol{t} \right ]
|
||||
&= \mathbf{K} \left[ \mathbf{r_1} \hspace{0.5em} \mathbf{r_2} \hspace{0.5em} \mathbf{t} \right ]
|
||||
\begin{pmatrix}
|
||||
X \\
|
||||
Y \\
|
||||
1
|
||||
\end{pmatrix} \\
|
||||
&= \boldsymbol{H}
|
||||
&= \mathbf{H}
|
||||
\begin{pmatrix}
|
||||
X \\
|
||||
Y \\
|
||||
@@ -149,16 +151,16 @@ A quick solution to retrieve the pose from the homography matrix is (see \ref po
|
||||
|
||||
\f[
|
||||
\begin{align*}
|
||||
\boldsymbol{H} &= \lambda \boldsymbol{K} \left[ \boldsymbol{r_1} \hspace{0.5em} \boldsymbol{r_2} \hspace{0.5em} \boldsymbol{t} \right ] \\
|
||||
\boldsymbol{K}^{-1} \boldsymbol{H} &= \lambda \left[ \boldsymbol{r_1} \hspace{0.5em} \boldsymbol{r_2} \hspace{0.5em} \boldsymbol{t} \right ] \\
|
||||
\boldsymbol{P} &= \boldsymbol{K} \left[ \boldsymbol{r_1} \hspace{0.5em} \boldsymbol{r_2} \hspace{0.5em} \left( \boldsymbol{r_1} \times \boldsymbol{r_2} \right ) \hspace{0.5em} \boldsymbol{t} \right ]
|
||||
\mathbf{H} &= \lambda \mathbf{K} \left[ \mathbf{r_1} \hspace{0.5em} \mathbf{r_2} \hspace{0.5em} \mathbf{t} \right ] \\
|
||||
\mathbf{K}^{-1} \mathbf{H} &= \lambda \left[ \mathbf{r_1} \hspace{0.5em} \mathbf{r_2} \hspace{0.5em} \mathbf{t} \right ] \\
|
||||
\mathbf{P} &= \mathbf{K} \left[ \mathbf{r_1} \hspace{0.5em} \mathbf{r_2} \hspace{0.5em} \left( \mathbf{r_1} \times \mathbf{r_2} \right ) \hspace{0.5em} \mathbf{t} \right ]
|
||||
\end{align*}
|
||||
\f]
|
||||
|
||||
This is a quick solution (see also \ref projective_transformations "2") as this does not ensure that the resulting rotation matrix will be orthogonal and the scale is estimated roughly by normalize the first column to 1.
|
||||
|
||||
A solution to have a proper rotation matrix (with the properties of a rotation matrix) consists to apply a polar decomposition
|
||||
(see \ref polar_decomposition "6" or \ref polar_decomposition_svd "7" for some information):
|
||||
A solution to have a proper rotation matrix (with the properties of a rotation matrix) consists to apply a polar decomposition, or orthogonalization of the rotation matrix
|
||||
(see \ref polar_decomposition "6" or \ref polar_decomposition_svd "7" or \ref polar_decomposition_svd_2 "8" or \ref Kabsch_algorithm "9" for some information):
|
||||
|
||||
@snippet pose_from_homography.cpp polar-decomposition-of-the-rotation-matrix
|
||||
|
||||
@@ -239,7 +241,7 @@ To check the correctness of the calculation, the matching lines are displayed:
|
||||
|
||||
### Demo 3: Homography from the camera displacement {#tutorial_homography_Demo3}
|
||||
|
||||
The homography relates the transformation between two planes and it is possible to retrieve the corresponding camera displacement that allows to go from the first to the second plane view (see @cite Malis for more information).
|
||||
The homography relates the transformation between two planes and it is possible to retrieve the corresponding camera displacement that allows to go from the first to the second plane view (see @cite Malis2007 for more information).
|
||||
Before going into the details that allow to compute the homography from the camera displacement, some recalls about camera pose and homogeneous transformation.
|
||||
|
||||
The function @ref cv::solvePnP allows to compute the camera pose from the correspondences 3D object points (points expressed in the object frame) and the projected 2D image points (object points viewed in the image).
|
||||
@@ -269,7 +271,7 @@ The intrinsic parameters and the distortion coefficients are required (see the c
|
||||
Z_o \\
|
||||
1
|
||||
\end{bmatrix} \\
|
||||
&= \boldsymbol{K} \hspace{0.2em} ^{c}\textrm{M}_o
|
||||
&= \mathbf{K} \hspace{0.2em} ^{c}\mathbf{M}_o
|
||||
\begin{bmatrix}
|
||||
X_o \\
|
||||
Y_o \\
|
||||
@@ -279,9 +281,9 @@ The intrinsic parameters and the distortion coefficients are required (see the c
|
||||
\end{align*}
|
||||
\f]
|
||||
|
||||
\f$ \boldsymbol{K} \f$ is the intrinsic matrix and \f$ ^{c}\textrm{M}_o \f$ is the camera pose. The output of @ref cv::solvePnP is exactly this: `rvec` is the Rodrigues rotation vector and `tvec` the translation vector.
|
||||
\f$ \mathbf{K} \f$ is the intrinsic matrix and \f$ ^{c}\mathbf{M}_o \f$ is the camera pose. The output of @ref cv::solvePnP is exactly this: `rvec` is the Rodrigues rotation vector and `tvec` the translation vector.
|
||||
|
||||
\f$ ^{c}\textrm{M}_o \f$ can be represented in a homogeneous form and allows to transform a point expressed in the object frame into the camera frame:
|
||||
\f$ ^{c}\mathbf{M}_o \f$ can be represented in a homogeneous form and allows to transform a point expressed in the object frame into the camera frame:
|
||||
|
||||
\f[
|
||||
\begin{align*}
|
||||
@@ -291,7 +293,7 @@ The intrinsic parameters and the distortion coefficients are required (see the c
|
||||
Z_c \\
|
||||
1
|
||||
\end{bmatrix} &=
|
||||
\hspace{0.2em} ^{c}\textrm{M}_o
|
||||
\hspace{0.2em} ^{c}\mathbf{M}_o
|
||||
\begin{bmatrix}
|
||||
X_o \\
|
||||
Y_o \\
|
||||
@@ -300,7 +302,7 @@ The intrinsic parameters and the distortion coefficients are required (see the c
|
||||
\end{bmatrix} \\
|
||||
&=
|
||||
\begin{bmatrix}
|
||||
^{c}\textrm{R}_o & ^{c}\textrm{t}_o \\
|
||||
^{c}\mathbf{R}_o & ^{c}\mathbf{t}_o \\
|
||||
0_{1\times3} & 1
|
||||
\end{bmatrix}
|
||||
\begin{bmatrix}
|
||||
@@ -327,19 +329,19 @@ The intrinsic parameters and the distortion coefficients are required (see the c
|
||||
|
||||
Transform a point expressed in one frame to another frame can be easily done with matrix multiplication:
|
||||
|
||||
* \f$ ^{c_1}\textrm{M}_o \f$ is the camera pose for the camera 1
|
||||
* \f$ ^{c_2}\textrm{M}_o \f$ is the camera pose for the camera 2
|
||||
* \f$ ^{c_1}\mathbf{M}_o \f$ is the camera pose for the camera 1
|
||||
* \f$ ^{c_2}\mathbf{M}_o \f$ is the camera pose for the camera 2
|
||||
|
||||
To transform a 3D point expressed in the camera 1 frame to the camera 2 frame:
|
||||
|
||||
\f[
|
||||
^{c_2}\textrm{M}_{c_1} = \hspace{0.2em} ^{c_2}\textrm{M}_{o} \cdot \hspace{0.1em} ^{o}\textrm{M}_{c_1} = \hspace{0.2em} ^{c_2}\textrm{M}_{o} \cdot \hspace{0.1em} \left( ^{c_1}\textrm{M}_{o} \right )^{-1} =
|
||||
^{c_2}\mathbf{M}_{c_1} = \hspace{0.2em} ^{c_2}\mathbf{M}_{o} \cdot \hspace{0.1em} ^{o}\mathbf{M}_{c_1} = \hspace{0.2em} ^{c_2}\mathbf{M}_{o} \cdot \hspace{0.1em} \left( ^{c_1}\mathbf{M}_{o} \right )^{-1} =
|
||||
\begin{bmatrix}
|
||||
^{c_2}\textrm{R}_{o} & ^{c_2}\textrm{t}_{o} \\
|
||||
^{c_2}\mathbf{R}_{o} & ^{c_2}\mathbf{t}_{o} \\
|
||||
0_{3 \times 1} & 1
|
||||
\end{bmatrix} \cdot
|
||||
\begin{bmatrix}
|
||||
^{c_1}\textrm{R}_{o}^T & - \hspace{0.2em} ^{c_1}\textrm{R}_{o}^T \cdot \hspace{0.2em} ^{c_1}\textrm{t}_{o} \\
|
||||
^{c_1}\mathbf{R}_{o}^T & - \hspace{0.2em} ^{c_1}\mathbf{R}_{o}^T \cdot \hspace{0.2em} ^{c_1}\mathbf{t}_{o} \\
|
||||
0_{1 \times 3} & 1
|
||||
\end{bmatrix}
|
||||
\f]
|
||||
@@ -362,11 +364,11 @@ On this figure, `n` is the normal vector of the plane and `d` the distance betwe
|
||||
The [equation](https://en.wikipedia.org/wiki/Homography_(computer_vision)#3D_plane_to_plane_equation) to compute the homography from the camera displacement is:
|
||||
|
||||
\f[
|
||||
^{2}\textrm{H}_{1} = \hspace{0.2em} ^{2}\textrm{R}_{1} - \hspace{0.1em} \frac{^{2}\textrm{t}_{1} \cdot n^T}{d}
|
||||
^{2}\mathbf{H}_{1} = \hspace{0.2em} ^{2}\mathbf{R}_{1} - \hspace{0.1em} \frac{^{2}\mathbf{t}_{1} \cdot \hspace{0.1em} ^{1}\mathbf{n}^\top}{^1d}
|
||||
\f]
|
||||
|
||||
Where \f$ ^{2}\textrm{H}_{1} \f$ is the homography matrix that maps the points in the first camera frame to the corresponding points in the second camera frame, \f$ ^{2}\textrm{R}_{1} = \hspace{0.2em} ^{c_2}\textrm{R}_{o} \cdot \hspace{0.1em} ^{c_1}\textrm{R}_{o}^{T} \f$
|
||||
is the rotation matrix that represents the rotation between the two camera frames and \f$ ^{2}\textrm{t}_{1} = \hspace{0.2em} ^{c_2}\textrm{R}_{o} \cdot \left( - \hspace{0.1em} ^{c_1}\textrm{R}_{o}^{T} \cdot \hspace{0.1em} ^{c_1}\textrm{t}_{o} \right ) + \hspace{0.1em} ^{c_2}\textrm{t}_{o} \f$
|
||||
Where \f$ ^{2}\mathbf{H}_{1} \f$ is the homography matrix that maps the points in the first camera frame to the corresponding points in the second camera frame, \f$ ^{2}\mathbf{R}_{1} = \hspace{0.2em} ^{c_2}\mathbf{R}_{o} \cdot \hspace{0.1em} ^{c_1}\mathbf{R}_{o}^{\top} \f$
|
||||
is the rotation matrix that represents the rotation between the two camera frames and \f$ ^{2}\mathbf{t}_{1} = \hspace{0.2em} ^{c_2}\mathbf{R}_{o} \cdot \left( - \hspace{0.1em} ^{c_1}\mathbf{R}_{o}^{\top} \cdot \hspace{0.1em} ^{c_1}\mathbf{t}_{o} \right ) + \hspace{0.1em} ^{c_2}\mathbf{t}_{o} \f$
|
||||
the translation vector between the two camera frames.
|
||||
|
||||
Here the normal vector `n` is the plane normal expressed in the camera frame 1 and can be computed as the cross product of 2 vectors (using 3 non collinear points that lie on the plane) or in our case directly with:
|
||||
@@ -377,7 +379,7 @@ The distance `d` can be computed as the dot product between the plane normal and
|
||||
|
||||
@snippet homography_from_camera_displacement.cpp compute-plane-distance-to-the-camera-frame-1
|
||||
|
||||
The projective homography matrix \f$ \textbf{G} \f$ can be computed from the Euclidean homography \f$ \textbf{H} \f$ using the intrinsic matrix \f$ \textbf{K} \f$ (see @cite Malis), here assuming the same camera between the two plane views:
|
||||
The projective homography matrix \f$ \textbf{G} \f$ can be computed from the Euclidean homography \f$ \textbf{H} \f$ using the intrinsic matrix \f$ \textbf{K} \f$ (see @cite Malis2007), here assuming the same camera between the two plane views:
|
||||
|
||||
\f[
|
||||
\textbf{G} = \gamma \textbf{K} \textbf{H} \textbf{K}^{-1}
|
||||
@@ -388,7 +390,7 @@ The projective homography matrix \f$ \textbf{G} \f$ can be computed from the Euc
|
||||
In our case, the Z-axis of the chessboard goes inside the object whereas in the homography figure it goes outside. This is just a matter of sign:
|
||||
|
||||
\f[
|
||||
^{2}\textrm{H}_{1} = \hspace{0.2em} ^{2}\textrm{R}_{1} + \hspace{0.1em} \frac{^{2}\textrm{t}_{1} \cdot n^T}{d}
|
||||
^{2}\mathbf{H}_{1} = \hspace{0.2em} ^{2}\mathbf{R}_{1} + \hspace{0.1em} \frac{^{2}\mathbf{t}_{1} \cdot \hspace{0.1em} ^{1}\mathbf{n}^\top}{^1d}
|
||||
\f]
|
||||
|
||||
@snippet homography_from_camera_displacement.cpp compute-homography-from-camera-displacement
|
||||
@@ -410,10 +412,18 @@ homography from camera displacement:
|
||||
|
||||
The homography matrices are similar. If we compare the image 1 warped using both homography matrices:
|
||||
|
||||

|
||||

|
||||
|
||||
Visually, it is hard to distinguish a difference between the result image from the homography computed from the camera displacement and the one estimated with @ref cv::findHomography function.
|
||||
|
||||
#### Exercise
|
||||
|
||||
This demo shows you how to compute the homography transformation from two camera poses. Try to perform the same operations, but by computing N inter homography this time. Instead of computing one homography to directly warp the source image to the desired camera viewpoint, perform N warping operations to see the different transformations operating.
|
||||
|
||||
You should get something similar to the following:
|
||||
|
||||

|
||||
|
||||
### Demo 4: Decompose the homography matrix {#tutorial_homography_Demo4}
|
||||
|
||||
OpenCV 3 contains the function @ref cv::decomposeHomographyMat which allows to decompose the homography matrix to a set of rotations, translations and plane normals.
|
||||
@@ -466,8 +476,8 @@ As you can see, there is one solution that matches almost perfectly with the com
|
||||
At least two of the solutions may further be invalidated if point correspondences are available by applying positive depth constraint (all points must be in front of the camera).
|
||||
```
|
||||
|
||||
As the result of the decomposition is a camera displacement, if we have the initial camera pose \f$ ^{c_1}\textrm{M}_{o} \f$, we can compute the current camera pose
|
||||
\f$ ^{c_2}\textrm{M}_{o} = \hspace{0.2em} ^{c_2}\textrm{M}_{c_1} \cdot \hspace{0.1em} ^{c_1}\textrm{M}_{o} \f$ and test if the 3D object points that belong to the plane are projected in front of the camera or not.
|
||||
As the result of the decomposition is a camera displacement, if we have the initial camera pose \f$ ^{c_1}\mathbf{M}_{o} \f$, we can compute the current camera pose
|
||||
\f$ ^{c_2}\mathbf{M}_{o} = \hspace{0.2em} ^{c_2}\mathbf{M}_{c_1} \cdot \hspace{0.1em} ^{c_1}\mathbf{M}_{o} \f$ and test if the 3D object points that belong to the plane are projected in front of the camera or not.
|
||||
Another solution could be to retain the solution with the closest normal if we know the plane normal expressed at the camera 1 pose.
|
||||
|
||||
The same thing but with the homography matrix estimated with @ref cv::findHomography
|
||||
@@ -516,7 +526,7 @@ The [stitching module](@ref stitching) provides a complete pipeline to stitch im
|
||||
The homography transformation applies only for planar structure. But in the case of a rotating camera (pure rotation around the camera axis of projection, no translation), an arbitrary world can be considered
|
||||
([see previously](@ref tutorial_homography_What_is_the_homography_matrix)).
|
||||
|
||||
The homography can then be computed using the rotation transformation and the camera intrinsic parameters as (see for instance \ref homography_course "8"):
|
||||
The homography can then be computed using the rotation transformation and the camera intrinsic parameters as (see for instance \ref homography_course "10"):
|
||||
|
||||
\f[
|
||||
s
|
||||
@@ -534,7 +544,7 @@ The homography can then be computed using the rotation transformation and the ca
|
||||
\f]
|
||||
|
||||
To illustrate, we used Blender, a free and open-source 3D computer graphics software, to generate two camera views with only a rotation transformation between each other.
|
||||
More information about how to retrieve the camera intrinsic parameters and the `3x4` extrinsic matrix with respect to the world can be found in \ref answer_blender "9" (an additional transformation
|
||||
More information about how to retrieve the camera intrinsic parameters and the `3x4` extrinsic matrix with respect to the world can be found in \ref answer_blender "11" (an additional transformation
|
||||
is needed to get the transformation between the camera and the object frames) with Blender.
|
||||
|
||||
The figure below shows the two generated views of the Suzanne model, with only a rotation transformation:
|
||||
@@ -603,11 +613,13 @@ Additional references {#tutorial_homography_Additional_references}
|
||||
---------------------
|
||||
|
||||
* \anchor lecture_16 1. [Lecture 16: Planar Homographies](http://www.cse.psu.edu/~rtc12/CSE486/lecture16.pdf), Robert Collins
|
||||
* \anchor projective_transformations 2. [2D projective transformations (homographies)](https://ags.cs.uni-kl.de/fileadmin/inf_ags/3dcv-ws11-12/3DCV_WS11-12_lec04.pdf), Christiano Gava, Gabriele Bleser
|
||||
* \anchor szeliski 3. [Computer Vision: Algorithms and Applications](http://szeliski.org/Book/drafts/SzeliskiBook_20100903_draft.pdf), Richard Szeliski
|
||||
* \anchor projective_transformations 2. [2D projective transformations (homographies)](https://web.archive.org/web/20171226115739/https://ags.cs.uni-kl.de/fileadmin/inf_ags/3dcv-ws11-12/3DCV_WS11-12_lec04.pdf), Christiano Gava, Gabriele Bleser
|
||||
* \anchor szeliski 3. [Computer Vision: Algorithms and Applications](https://szeliski.org/Book/), Richard Szeliski
|
||||
* \anchor answer_dsp 4. [Step by Step Camera Pose Estimation for Visual Tracking and Planar Markers](https://dsp.stackexchange.com/a/2737)
|
||||
* \anchor pose_ar 5. [Pose from homography estimation](https://team.inria.fr/lagadic/camera_localization/tutorial-pose-dlt-planar-opencv.html)
|
||||
* \anchor pose_ar 5. [Pose from homography estimation](https://visp-doc.inria.fr/doxygen/camera_localization/tutorial-pose-dlt-planar-opencv.html)
|
||||
* \anchor polar_decomposition 6. [Polar Decomposition (in Continuum Mechanics)](http://www.continuummechanics.org/polardecomposition.html)
|
||||
* \anchor polar_decomposition_svd 7. [A Personal Interview with the Singular Value Decomposition](https://web.stanford.edu/~gavish/documents/SVD_ans_you.pdf), Matan Gavish
|
||||
* \anchor homography_course 8. [Homography](http://people.scs.carleton.ca/~c_shu/Courses/comp4900d/notes/homography.pdf), Dr. Gerhard Roth
|
||||
* \anchor answer_blender 9. [3x4 camera matrix from blender camera](https://blender.stackexchange.com/a/38210)
|
||||
* \anchor polar_decomposition_svd 7. [Chapter 3 - 3.1.2 From matrices to rotations - Theorem 3.1 (Least-squares estimation of a rotation from a matrix K)](https://www-sop.inria.fr/asclepios/cours/MVA/Rotations.pdf)
|
||||
* \anchor polar_decomposition_svd_2 8. [A Personal Interview with the Singular Value Decomposition](https://web.stanford.edu/~gavish/documents/SVD_ans_you.pdf), Matan Gavish
|
||||
* \anchor Kabsch_algorithm 9. [Kabsch algorithm, Computation of the optimal rotation matrix](https://en.wikipedia.org/wiki/Kabsch_algorithm#Computation_of_the_optimal_rotation_matrix)
|
||||
* \anchor homography_course 10. [Homography](http://people.scs.carleton.ca/~c_shu/Courses/comp4900d/notes/homography.pdf), Dr. Gerhard Roth
|
||||
* \anchor answer_blender 11. [3x4 camera matrix from blender camera](https://blender.stackexchange.com/a/38210)
|
||||
|
||||
|
After Width: | Height: | Size: 78 KiB |
@@ -0,0 +1,92 @@
|
||||
Object detection with Generalized Ballard and Guil Hough Transform {#tutorial_generalized_hough_ballard_guil}
|
||||
==================================================================
|
||||
|
||||
@tableofcontents
|
||||
|
||||
@prev_tutorial{tutorial_hough_circle}
|
||||
@next_tutorial{tutorial_remap}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
In this tutorial you will learn how to:
|
||||
|
||||
- Use @ref cv::GeneralizedHoughBallard and @ref cv::GeneralizedHoughGuil to detect an object
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
### What does this program do?
|
||||
|
||||
1. Load the image and template
|
||||
|
||||

|
||||

|
||||
|
||||
2. Instantiate @ref cv::GeneralizedHoughBallard with the help of `createGeneralizedHoughBallard()`
|
||||
3. Instantiate @ref cv::GeneralizedHoughGuil with the help of `createGeneralizedHoughGuil()`
|
||||
4. Set the required parameters for both GeneralizedHough variants
|
||||
5. Detect and show found results
|
||||
|
||||
@note
|
||||
- Both variants can't be instantiated directly. Using the create methods is required.
|
||||
- Guil Hough is very slow. Calculating the results for the "mini" files used in this tutorial
|
||||
takes only a few seconds. With image and template in a higher resolution, as shown below,
|
||||
my notebook requires about 5 minutes to calculate a result.
|
||||
|
||||

|
||||

|
||||
|
||||
### Code
|
||||
|
||||
The complete code for this tutorial is shown below.
|
||||
@include samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
### Load image, template and setup variables
|
||||
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-load-and-setup
|
||||
|
||||
The position vectors will contain the matches the detectors will find.
|
||||
Every entry contains four floating point values:
|
||||
position vector
|
||||
|
||||
- *[0]*: x coordinate of center point
|
||||
- *[1]*: y coordinate of center point
|
||||
- *[2]*: scale of detected object compared to template
|
||||
- *[3]*: rotation of detected object in degree in relation to template
|
||||
|
||||
An example could look as follows: `[200, 100, 0.9, 120]`
|
||||
|
||||
### Setup parameters
|
||||
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-setup-parameters
|
||||
|
||||
Finding the optimal values can end up in trial and error and depends on many factors, such as the image resolution.
|
||||
|
||||
### Run detection
|
||||
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-run
|
||||
|
||||
As mentioned above, this step will take some time, especially with larger images and when using Guil.
|
||||
|
||||
### Draw results and show image
|
||||
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/generalizedHoughTransform.cpp generalized-hough-transform-draw-results
|
||||
|
||||
Result
|
||||
------
|
||||
|
||||

|
||||
|
||||
The blue rectangle shows the result of @ref cv::GeneralizedHoughBallard and the green rectangles the results of @ref
|
||||
cv::GeneralizedHoughGuil.
|
||||
|
||||
Getting perfect results like in this example is unlikely if the parameters are not perfectly adapted to the sample.
|
||||
An example with less perfect parameters is shown below.
|
||||
For the Ballard variant, only the center of the result is marked as a black dot on this image. The rectangle would be
|
||||
the same as on the previous image.
|
||||
|
||||

|
||||
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 42 KiB |
@@ -2,7 +2,7 @@ Hough Circle Transform {#tutorial_hough_circle}
|
||||
======================
|
||||
|
||||
@prev_tutorial{tutorial_hough_lines}
|
||||
@next_tutorial{tutorial_remap}
|
||||
@next_tutorial{tutorial_generalized_hough_ballard_guil}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Remapping {#tutorial_remap}
|
||||
=========
|
||||
|
||||
@prev_tutorial{tutorial_hough_circle}
|
||||
@prev_tutorial{tutorial_generalized_hough_ballard_guil}
|
||||
@next_tutorial{tutorial_warp_affine}
|
||||
|
||||
Goal
|
||||
|
||||
@@ -173,6 +173,16 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
Where we learn how to detect circles
|
||||
|
||||
- @subpage tutorial_generalized_hough_ballard_guil
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \>= OpenCV 3.4
|
||||
|
||||
*Author:* Markus Heck
|
||||
|
||||
Detect an object in a picture with the help of GeneralizedHoughBallard and GeneralizedHoughGuil.
|
||||
|
||||
- @subpage tutorial_remap
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
@@ -39,14 +39,14 @@ Open your Doxyfile using your favorite text editor and search for the key
|
||||
`TAGFILES`. Change it as follows:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.18
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.19
|
||||
@endcode
|
||||
|
||||
If you had other definitions already, you can append the line using a `\`:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.18
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.19
|
||||
@endcode
|
||||
|
||||
Doxygen can now use the information from the tag file to link to the OpenCV
|
||||
|
||||
@@ -3,6 +3,7 @@ Cascade Classifier Training {#tutorial_traincascade}
|
||||
|
||||
@prev_tutorial{tutorial_cascade_classifier}
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
||||
@@ -577,7 +577,7 @@ a vector\<Point2f\> .
|
||||
- @ref RHO - PROSAC-based robust method
|
||||
@param ransacReprojThreshold Maximum allowed reprojection error to treat a point pair as an inlier
|
||||
(used in the RANSAC and RHO methods only). That is, if
|
||||
\f[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} * \texttt{srcPoints} _i) \|_2 > \texttt{ransacReprojThreshold}\f]
|
||||
\f[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} \cdot \texttt{srcPoints} _i) \|_2 > \texttt{ransacReprojThreshold}\f]
|
||||
then the point \f$i\f$ is considered as an outlier. If srcPoints and dstPoints are measured in pixels,
|
||||
it usually makes sense to set this parameter somewhere in the range of 1 to 10.
|
||||
@param mask Optional output mask set by a robust method ( RANSAC or LMeDS ). Note that the input
|
||||
@@ -642,7 +642,7 @@ CV_EXPORTS Mat findHomography( InputArray srcPoints, InputArray dstPoints,
|
||||
@param Qz Optional output 3x3 rotation matrix around z-axis.
|
||||
|
||||
The function computes a RQ decomposition using the given rotations. This function is used in
|
||||
decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix into a camera
|
||||
#decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix into a camera
|
||||
and a rotation matrix.
|
||||
|
||||
It optionally returns three rotation matrices, one for each axis, and the three Euler angles in
|
||||
@@ -676,7 +676,7 @@ be used in OpenGL. Note, there is always more than one sequence of rotations abo
|
||||
principal axes that results in the same orientation of an object, e.g. see @cite Slabaugh . Returned
|
||||
tree rotation matrices and corresponding three Euler angles are only one of the possible solutions.
|
||||
|
||||
The function is based on RQDecomp3x3 .
|
||||
The function is based on #RQDecomp3x3 .
|
||||
*/
|
||||
CV_EXPORTS_W void decomposeProjectionMatrix( InputArray projMatrix, OutputArray cameraMatrix,
|
||||
OutputArray rotMatrix, OutputArray transVect,
|
||||
@@ -696,7 +696,7 @@ CV_EXPORTS_W void decomposeProjectionMatrix( InputArray projMatrix, OutputArray
|
||||
|
||||
The function computes partial derivatives of the elements of the matrix product \f$A*B\f$ with regard to
|
||||
the elements of each of the two input matrices. The function is used to compute the Jacobian
|
||||
matrices in stereoCalibrate but can also be used in any other similar optimization function.
|
||||
matrices in #stereoCalibrate but can also be used in any other similar optimization function.
|
||||
*/
|
||||
CV_EXPORTS_W void matMulDeriv( InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB );
|
||||
|
||||
@@ -722,10 +722,10 @@ The functions compute:
|
||||
\f[\begin{array}{l} \texttt{rvec3} = \mathrm{rodrigues} ^{-1} \left ( \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \mathrm{rodrigues} ( \texttt{rvec1} ) \right ) \\ \texttt{tvec3} = \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \texttt{tvec1} + \texttt{tvec2} \end{array} ,\f]
|
||||
|
||||
where \f$\mathrm{rodrigues}\f$ denotes a rotation vector to a rotation matrix transformation, and
|
||||
\f$\mathrm{rodrigues}^{-1}\f$ denotes the inverse transformation. See Rodrigues for details.
|
||||
\f$\mathrm{rodrigues}^{-1}\f$ denotes the inverse transformation. See #Rodrigues for details.
|
||||
|
||||
Also, the functions can compute the derivatives of the output vectors with regards to the input
|
||||
vectors (see matMulDeriv ). The functions are used inside stereoCalibrate but can also be used in
|
||||
vectors (see #matMulDeriv ). The functions are used inside #stereoCalibrate but can also be used in
|
||||
your own code where Levenberg-Marquardt or another gradient-based solver is used to optimize a
|
||||
function that contains a matrix multiplication.
|
||||
*/
|
||||
@@ -1084,7 +1084,7 @@ calibrateCamera for details.
|
||||
old interface all the per-view vectors are concatenated.
|
||||
@param imageSize Image size in pixels used to initialize the principal point.
|
||||
@param aspectRatio If it is zero or negative, both \f$f_x\f$ and \f$f_y\f$ are estimated independently.
|
||||
Otherwise, \f$f_x = f_y * \texttt{aspectRatio}\f$ .
|
||||
Otherwise, \f$f_x = f_y \cdot \texttt{aspectRatio}\f$ .
|
||||
|
||||
The function estimates and returns an initial camera intrinsic matrix for the camera calibration process.
|
||||
Currently, the function only supports planar calibration patterns, which are patterns where each
|
||||
@@ -1098,12 +1098,12 @@ CV_EXPORTS_W Mat initCameraMatrix2D( InputArrayOfArrays objectPoints,
|
||||
|
||||
@param image Source chessboard view. It must be an 8-bit grayscale or color image.
|
||||
@param patternSize Number of inner corners per a chessboard row and column
|
||||
( patternSize = cvSize(points_per_row,points_per_colum) = cvSize(columns,rows) ).
|
||||
( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) ).
|
||||
@param corners Output array of detected corners.
|
||||
@param flags Various operation flags that can be zero or a combination of the following values:
|
||||
- @ref CALIB_CB_ADAPTIVE_THRESH Use adaptive thresholding to convert the image to black
|
||||
and white, rather than a fixed threshold level (computed from the average image brightness).
|
||||
- @ref CALIB_CB_NORMALIZE_IMAGE Normalize the image gamma with equalizeHist before
|
||||
- @ref CALIB_CB_NORMALIZE_IMAGE Normalize the image gamma with #equalizeHist before
|
||||
applying fixed or adaptive thresholding.
|
||||
- @ref CALIB_CB_FILTER_QUADS Use additional criteria (like contour area, perimeter,
|
||||
square-like shape) to filter out false quads extracted at the contour retrieval stage.
|
||||
@@ -1117,7 +1117,7 @@ are found and they are placed in a certain order (row by row, left to right in e
|
||||
Otherwise, if the function fails to find all the corners or reorder them, it returns 0. For example,
|
||||
a regular chessboard has 8 x 8 squares and 7 x 7 internal corners, that is, points where the black
|
||||
squares touch each other. The detected coordinates are approximate, and to determine their positions
|
||||
more accurately, the function calls cornerSubPix. You also may use the function cornerSubPix with
|
||||
more accurately, the function calls #cornerSubPix. You also may use the function #cornerSubPix with
|
||||
different parameters if returned coordinates are not accurate enough.
|
||||
|
||||
Sample usage of detecting and drawing chessboard corners: :
|
||||
@@ -1154,9 +1154,9 @@ CV_EXPORTS_W bool find4QuadCornerSubpix( InputArray img, InputOutputArray corner
|
||||
@param image Destination image. It must be an 8-bit color image.
|
||||
@param patternSize Number of inner corners per a chessboard row and column
|
||||
(patternSize = cv::Size(points_per_row,points_per_column)).
|
||||
@param corners Array of detected corners, the output of findChessboardCorners.
|
||||
@param corners Array of detected corners, the output of #findChessboardCorners.
|
||||
@param patternWasFound Parameter indicating whether the complete board was found or not. The
|
||||
return value of findChessboardCorners should be passed here.
|
||||
return value of #findChessboardCorners should be passed here.
|
||||
|
||||
The function draws individual chessboard corners detected either as red circles if the board was not
|
||||
found, or as colored corners connected with lines if the board was found.
|
||||
@@ -1542,7 +1542,7 @@ Besides the stereo-related information, the function can also perform a full cal
|
||||
the two cameras. However, due to the high dimensionality of the parameter space and noise in the
|
||||
input data, the function can diverge from the correct solution. If the intrinsic parameters can be
|
||||
estimated with high accuracy for each of the cameras individually (for example, using
|
||||
calibrateCamera ), you are recommended to do so and then pass @ref CALIB_FIX_INTRINSIC flag to the
|
||||
#calibrateCamera ), you are recommended to do so and then pass @ref CALIB_FIX_INTRINSIC flag to the
|
||||
function along with the computed intrinsic parameters. Otherwise, if all the parameters are
|
||||
estimated at once, it makes sense to restrict some parameters, for example, pass
|
||||
@ref CALIB_SAME_FOCAL_LENGTH and @ref CALIB_ZERO_TANGENT_DIST flags, which is usually a
|
||||
@@ -1608,7 +1608,7 @@ pixels from the original images from the cameras are retained in the rectified i
|
||||
image pixels are lost). Any intermediate value yields an intermediate result between
|
||||
those two extreme cases.
|
||||
@param newImageSize New image resolution after rectification. The same size should be passed to
|
||||
initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
|
||||
#initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
|
||||
is passed (default), it is set to the original imageSize . Setting it to a larger value can help you
|
||||
preserve details in the original image, especially when there is a big radial distortion.
|
||||
@param validPixROI1 Optional output rectangles inside the rectified images where all the pixels
|
||||
@@ -1620,7 +1620,7 @@ are valid. If alpha=0 , the ROIs cover the whole images. Otherwise, they are lik
|
||||
|
||||
The function computes the rotation matrices for each camera that (virtually) make both camera image
|
||||
planes the same plane. Consequently, this makes all the epipolar lines parallel and thus simplifies
|
||||
the dense stereo correspondence problem. The function takes the matrices computed by stereoCalibrate
|
||||
the dense stereo correspondence problem. The function takes the matrices computed by #stereoCalibrate
|
||||
as input. As output, it provides two rotation matrices and also two projection matrices in the new
|
||||
coordinates. The function distinguishes the following two cases:
|
||||
|
||||
@@ -1636,11 +1636,18 @@ coordinates. The function distinguishes the following two cases:
|
||||
\end{bmatrix}\f]
|
||||
|
||||
\f[\texttt{P2} = \begin{bmatrix}
|
||||
f & 0 & cx_2 & T_x*f \\
|
||||
f & 0 & cx_2 & T_x \cdot f \\
|
||||
0 & f & cy & 0 \\
|
||||
0 & 0 & 1 & 0
|
||||
\end{bmatrix} ,\f]
|
||||
|
||||
\f[\texttt{Q} = \begin{bmatrix}
|
||||
1 & 0 & 0 & -cx_1 \\
|
||||
0 & 1 & 0 & -cy \\
|
||||
0 & 0 & 0 & f \\
|
||||
0 & 0 & -\frac{1}{T_x} & \frac{cx_1 - cx_2}{T_x}
|
||||
\end{bmatrix} \f]
|
||||
|
||||
where \f$T_x\f$ is a horizontal shift between the cameras and \f$cx_1=cx_2\f$ if
|
||||
@ref CALIB_ZERO_DISPARITY is set.
|
||||
|
||||
@@ -1656,15 +1663,22 @@ coordinates. The function distinguishes the following two cases:
|
||||
|
||||
\f[\texttt{P2} = \begin{bmatrix}
|
||||
f & 0 & cx & 0 \\
|
||||
0 & f & cy_2 & T_y*f \\
|
||||
0 & f & cy_2 & T_y \cdot f \\
|
||||
0 & 0 & 1 & 0
|
||||
\end{bmatrix},\f]
|
||||
|
||||
\f[\texttt{Q} = \begin{bmatrix}
|
||||
1 & 0 & 0 & -cx \\
|
||||
0 & 1 & 0 & -cy_1 \\
|
||||
0 & 0 & 0 & f \\
|
||||
0 & 0 & -\frac{1}{T_y} & \frac{cy_1 - cy_2}{T_y}
|
||||
\end{bmatrix} \f]
|
||||
|
||||
where \f$T_y\f$ is a vertical shift between the cameras and \f$cy_1=cy_2\f$ if
|
||||
@ref CALIB_ZERO_DISPARITY is set.
|
||||
|
||||
As you can see, the first three columns of P1 and P2 will effectively be the new "rectified" camera
|
||||
matrices. The matrices, together with R1 and R2 , can then be passed to initUndistortRectifyMap to
|
||||
matrices. The matrices, together with R1 and R2 , can then be passed to #initUndistortRectifyMap to
|
||||
initialize the rectification map for each camera.
|
||||
|
||||
See below the screenshot from the stereo_calib.cpp sample. Some red horizontal lines pass through
|
||||
@@ -1687,20 +1701,20 @@ CV_EXPORTS_W void stereoRectify( InputArray cameraMatrix1, InputArray distCoeffs
|
||||
|
||||
@param points1 Array of feature points in the first image.
|
||||
@param points2 The corresponding points in the second image. The same formats as in
|
||||
findFundamentalMat are supported.
|
||||
#findFundamentalMat are supported.
|
||||
@param F Input fundamental matrix. It can be computed from the same set of point pairs using
|
||||
findFundamentalMat .
|
||||
#findFundamentalMat .
|
||||
@param imgSize Size of the image.
|
||||
@param H1 Output rectification homography matrix for the first image.
|
||||
@param H2 Output rectification homography matrix for the second image.
|
||||
@param threshold Optional threshold used to filter out the outliers. If the parameter is greater
|
||||
than zero, all the point pairs that do not comply with the epipolar geometry (that is, the points
|
||||
for which \f$|\texttt{points2[i]}^T*\texttt{F}*\texttt{points1[i]}|>\texttt{threshold}\f$ ) are
|
||||
rejected prior to computing the homographies. Otherwise, all the points are considered inliers.
|
||||
for which \f$|\texttt{points2[i]}^T \cdot \texttt{F} \cdot \texttt{points1[i]}|>\texttt{threshold}\f$ )
|
||||
are rejected prior to computing the homographies. Otherwise, all the points are considered inliers.
|
||||
|
||||
The function computes the rectification transformations without knowing intrinsic parameters of the
|
||||
cameras and their relative position in the space, which explains the suffix "uncalibrated". Another
|
||||
related difference from stereoRectify is that the function outputs not the rectification
|
||||
related difference from #stereoRectify is that the function outputs not the rectification
|
||||
transformations in the object (3D) space, but the planar perspective transformations encoded by the
|
||||
homography matrices H1 and H2 . The function implements the algorithm @cite Hartley99 .
|
||||
|
||||
@@ -1709,8 +1723,8 @@ homography matrices H1 and H2 . The function implements the algorithm @cite Hart
|
||||
depends on the epipolar geometry. Therefore, if the camera lenses have a significant distortion,
|
||||
it would be better to correct it before computing the fundamental matrix and calling this
|
||||
function. For example, distortion coefficients can be estimated for each head of stereo camera
|
||||
separately by using calibrateCamera . Then, the images can be corrected using undistort , or
|
||||
just the point coordinates can be corrected with undistortPoints .
|
||||
separately by using #calibrateCamera . Then, the images can be corrected using #undistort , or
|
||||
just the point coordinates can be corrected with #undistortPoints .
|
||||
*/
|
||||
CV_EXPORTS_W bool stereoRectifyUncalibrated( InputArray points1, InputArray points2,
|
||||
InputArray F, Size imgSize,
|
||||
@@ -1738,10 +1752,10 @@ assumed.
|
||||
@param imageSize Original image size.
|
||||
@param alpha Free scaling parameter between 0 (when all the pixels in the undistorted image are
|
||||
valid) and 1 (when all the source image pixels are retained in the undistorted image). See
|
||||
stereoRectify for details.
|
||||
#stereoRectify for details.
|
||||
@param newImgSize Image size after rectification. By default, it is set to imageSize .
|
||||
@param validPixROI Optional output rectangle that outlines all-good-pixels region in the
|
||||
undistorted image. See roi1, roi2 description in stereoRectify .
|
||||
undistorted image. See roi1, roi2 description in #stereoRectify .
|
||||
@param centerPrincipalPoint Optional flag that indicates whether in the new camera intrinsic matrix the
|
||||
principal point should be at the image center or not. By default, the principal point is chosen to
|
||||
best fit a subset of the source image (determined by alpha) to the corrected image.
|
||||
@@ -1753,7 +1767,7 @@ image pixels if there is valuable information in the corners alpha=1 , or get so
|
||||
When alpha\>0 , the undistorted result is likely to have some black pixels corresponding to
|
||||
"virtual" pixels outside of the captured distorted image. The original camera intrinsic matrix, distortion
|
||||
coefficients, the computed new camera intrinsic matrix, and newImageSize should be passed to
|
||||
initUndistortRectifyMap to produce the maps for remap .
|
||||
#initUndistortRectifyMap to produce the maps for #remap .
|
||||
*/
|
||||
CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs,
|
||||
Size imageSize, double alpha, Size newImgSize = Size(),
|
||||
@@ -1920,7 +1934,7 @@ CV_EXPORTS_W void convertPointsFromHomogeneous( InputArray src, OutputArray dst
|
||||
@param dst Output vector of 2D, 3D, or 4D points.
|
||||
|
||||
The function converts 2D or 3D points from/to homogeneous coordinates by calling either
|
||||
convertPointsToHomogeneous or convertPointsFromHomogeneous.
|
||||
#convertPointsToHomogeneous or #convertPointsFromHomogeneous.
|
||||
|
||||
@note The function is obsolete. Use one of the previous two functions instead.
|
||||
*/
|
||||
@@ -1957,9 +1971,9 @@ the found fundamental matrix. Normally just one matrix is found. But in case of
|
||||
algorithm, the function may return up to 3 solutions ( \f$9 \times 3\f$ matrix that stores all 3
|
||||
matrices sequentially).
|
||||
|
||||
The calculated fundamental matrix may be passed further to computeCorrespondEpilines that finds the
|
||||
The calculated fundamental matrix may be passed further to #computeCorrespondEpilines that finds the
|
||||
epipolar lines corresponding to the specified points. It can also be passed to
|
||||
stereoRectifyUncalibrated to compute the rectification transformation. :
|
||||
#stereoRectifyUncalibrated to compute the rectification transformation. :
|
||||
@code
|
||||
// Example. Estimation of fundamental matrix using the RANSAC algorithm
|
||||
int point_count = 100;
|
||||
@@ -2023,7 +2037,7 @@ This function estimates essential matrix based on the five-point algorithm solve
|
||||
|
||||
where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the
|
||||
second images, respectively. The result of this function may be passed further to
|
||||
decomposeEssentialMat or recoverPose to recover the relative pose between cameras.
|
||||
#decomposeEssentialMat or #recoverPose to recover the relative pose between cameras.
|
||||
*/
|
||||
CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2,
|
||||
InputArray cameraMatrix, int method,
|
||||
@@ -2099,7 +2113,7 @@ unit length.
|
||||
CV_EXPORTS_W void decomposeEssentialMat( InputArray E, OutputArray R1, OutputArray R2, OutputArray t );
|
||||
|
||||
/** @brief Recovers the relative camera rotation and the translation from an estimated essential
|
||||
matrix and the corresponding points in two images, using cheirality check. Returns the number of
|
||||
matrix and the corresponding points in two images, using chirality check. Returns the number of
|
||||
inliers that pass the check.
|
||||
|
||||
@param E The input essential matrix.
|
||||
@@ -2117,11 +2131,11 @@ described below.
|
||||
therefore is only known up to scale, i.e. t is the direction of the translation vector and has unit
|
||||
length.
|
||||
@param mask Input/output mask for inliers in points1 and points2. If it is not empty, then it marks
|
||||
inliers in points1 and points2 for then given essential matrix E. Only these inliers will be used to
|
||||
recover pose. In the output mask only inliers which pass the cheirality check.
|
||||
inliers in points1 and points2 for the given essential matrix E. Only these inliers will be used to
|
||||
recover pose. In the output mask only inliers which pass the chirality check.
|
||||
|
||||
This function decomposes an essential matrix using @ref decomposeEssentialMat and then verifies
|
||||
possible pose hypotheses by doing cheirality check. The cheirality check means that the
|
||||
possible pose hypotheses by doing chirality check. The chirality check means that the
|
||||
triangulated 3D points should have positive depth. Some details can be found in @cite Nister03.
|
||||
|
||||
This function can be used to process the output E and mask from @ref findEssentialMat. In this
|
||||
@@ -2168,8 +2182,8 @@ length.
|
||||
are feature points from cameras with same focal length and principal point.
|
||||
@param pp principal point of the camera.
|
||||
@param mask Input/output mask for inliers in points1 and points2. If it is not empty, then it marks
|
||||
inliers in points1 and points2 for then given essential matrix E. Only these inliers will be used to
|
||||
recover pose. In the output mask only inliers which pass the cheirality check.
|
||||
inliers in points1 and points2 for the given essential matrix E. Only these inliers will be used to
|
||||
recover pose. In the output mask only inliers which pass the chirality check.
|
||||
|
||||
This function differs from the one above that it computes camera intrinsic matrix from focal length and
|
||||
principal point:
|
||||
@@ -2204,12 +2218,12 @@ length.
|
||||
@param distanceThresh threshold distance which is used to filter out far away points (i.e. infinite
|
||||
points).
|
||||
@param mask Input/output mask for inliers in points1 and points2. If it is not empty, then it marks
|
||||
inliers in points1 and points2 for then given essential matrix E. Only these inliers will be used to
|
||||
recover pose. In the output mask only inliers which pass the cheirality check.
|
||||
inliers in points1 and points2 for the given essential matrix E. Only these inliers will be used to
|
||||
recover pose. In the output mask only inliers which pass the chirality check.
|
||||
@param triangulatedPoints 3D points which were reconstructed by triangulation.
|
||||
|
||||
This function differs from the one above that it outputs the triangulated 3D point that are used for
|
||||
the cheirality check.
|
||||
the chirality check.
|
||||
*/
|
||||
CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2,
|
||||
InputArray cameraMatrix, OutputArray R, OutputArray t, double distanceThresh, InputOutputArray mask = noArray(),
|
||||
@@ -2220,14 +2234,14 @@ CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray point
|
||||
@param points Input points. \f$N \times 1\f$ or \f$1 \times N\f$ matrix of type CV_32FC2 or
|
||||
vector\<Point2f\> .
|
||||
@param whichImage Index of the image (1 or 2) that contains the points .
|
||||
@param F Fundamental matrix that can be estimated using findFundamentalMat or stereoRectify .
|
||||
@param F Fundamental matrix that can be estimated using #findFundamentalMat or #stereoRectify .
|
||||
@param lines Output vector of the epipolar lines corresponding to the points in the other image.
|
||||
Each line \f$ax + by + c=0\f$ is encoded by 3 numbers \f$(a, b, c)\f$ .
|
||||
|
||||
For every point in one of the two images of a stereo pair, the function finds the equation of the
|
||||
corresponding epipolar line in the other image.
|
||||
|
||||
From the fundamental matrix definition (see findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second
|
||||
From the fundamental matrix definition (see #findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second
|
||||
image for the point \f$p^{(1)}_i\f$ in the first image (when whichImage=1 ) is computed as:
|
||||
|
||||
\f[l^{(2)}_i = F p^{(1)}_i\f]
|
||||
@@ -2277,12 +2291,12 @@ CV_EXPORTS_W void triangulatePoints( InputArray projMatr1, InputArray projMatr2,
|
||||
@param newPoints1 The optimized points1.
|
||||
@param newPoints2 The optimized points2.
|
||||
|
||||
The function implements the Optimal Triangulation Method (see Multiple View Geometry for details).
|
||||
The function implements the Optimal Triangulation Method (see Multiple View Geometry @cite HartleyZ00 for details).
|
||||
For each given point correspondence points1[i] \<-\> points2[i], and a fundamental matrix F, it
|
||||
computes the corrected correspondences newPoints1[i] \<-\> newPoints2[i] that minimize the geometric
|
||||
error \f$d(points1[i], newPoints1[i])^2 + d(points2[i],newPoints2[i])^2\f$ (where \f$d(a,b)\f$ is the
|
||||
geometric distance between points \f$a\f$ and \f$b\f$ ) subject to the epipolar constraint
|
||||
\f$newPoints2^T * F * newPoints1 = 0\f$ .
|
||||
\f$newPoints2^T \cdot F \cdot newPoints1 = 0\f$ .
|
||||
*/
|
||||
CV_EXPORTS_W void correctMatches( InputArray F, InputArray points1, InputArray points2,
|
||||
OutputArray newPoints1, OutputArray newPoints2 );
|
||||
@@ -2559,7 +2573,7 @@ Check @ref tutorial_homography "the corresponding tutorial" for more details.
|
||||
|
||||
This function extracts relative camera motion between two views of a planar object and returns up to
|
||||
four mathematical solution tuples of rotation, translation, and plane normal. The decomposition of
|
||||
the homography matrix H is described in detail in @cite Malis.
|
||||
the homography matrix H is described in detail in @cite Malis2007.
|
||||
|
||||
If the homography H, induced by the plane, gives the constraint
|
||||
\f[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\f] on the source image points
|
||||
@@ -2584,10 +2598,10 @@ CV_EXPORTS_W int decomposeHomographyMat(InputArray H,
|
||||
@param beforePoints Vector of (rectified) visible reference points before the homography is applied
|
||||
@param afterPoints Vector of (rectified) visible reference points after the homography is applied
|
||||
@param possibleSolutions Vector of int indices representing the viable solution set after filtering
|
||||
@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the findHomography function
|
||||
@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the #findHomography function
|
||||
|
||||
This function is intended to filter the output of the decomposeHomographyMat based on additional
|
||||
information as described in @cite Malis . The summary of the method: the decomposeHomographyMat function
|
||||
This function is intended to filter the output of the #decomposeHomographyMat based on additional
|
||||
information as described in @cite Malis2007 . The summary of the method: the #decomposeHomographyMat function
|
||||
returns 2 unique solutions and their "opposites" for a total of 4 solutions. If we have access to the
|
||||
sets of points visible in the camera frame before and after the homography transformation is applied,
|
||||
we can determine which are the true potential solutions and which are the opposites by verifying which
|
||||
@@ -2977,14 +2991,14 @@ optimization. It stays at the center or at a different location specified when @
|
||||
camera.
|
||||
@param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second
|
||||
camera.
|
||||
@param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ).
|
||||
@param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see #reprojectImageTo3D ).
|
||||
@param flags Operation flags that may be zero or @ref fisheye::CALIB_ZERO_DISPARITY . If the flag is set,
|
||||
the function makes the principal points of each camera have the same pixel coordinates in the
|
||||
rectified views. And if the flag is not set, the function may still shift the images in the
|
||||
horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the
|
||||
useful image area.
|
||||
@param newImageSize New image resolution after rectification. The same size should be passed to
|
||||
initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
|
||||
#initUndistortRectifyMap (see the stereo_calib.cpp sample in OpenCV samples directory). When (0,0)
|
||||
is passed (default), it is set to the original imageSize . Setting it to larger value can help you
|
||||
preserve details in the original image, especially when there is a big radial distortion.
|
||||
@param balance Sets the new focal length in range between the min focal length and the max focal
|
||||
|
||||
@@ -699,10 +699,10 @@ public class Calib3dTest extends OpenCVTestCase {
|
||||
D.put(2,0,-0.021509225493198905);
|
||||
D.put(3,0,0.0043378096628297145);
|
||||
|
||||
K_new_truth.put(0,0, 387.4809086880343);
|
||||
K_new_truth.put(0,2, 1036.669802754649);
|
||||
K_new_truth.put(1,1, 373.6375700303157);
|
||||
K_new_truth.put(1,2, 538.8373261247601);
|
||||
K_new_truth.put(0,0, 387.5118215642316);
|
||||
K_new_truth.put(0,2, 1033.936556777084);
|
||||
K_new_truth.put(1,1, 373.6673784974842);
|
||||
K_new_truth.put(1,2, 538.794152656429);
|
||||
|
||||
Calib3d.fisheye_estimateNewCameraMatrixForUndistortRectify(K,D,new Size(1920,1080),
|
||||
new Mat().eye(3, 3, CvType.CV_64F), K_new, 0.0, new Size(1920,1080));
|
||||
|
||||
@@ -1232,7 +1232,7 @@ int ChessBoardDetector::cleanFoundConnectedQuads(std::vector<ChessBoardQuad*>& q
|
||||
centers[i] = ci;
|
||||
center += ci;
|
||||
}
|
||||
center.x *= (1.0f / quad_count);
|
||||
center *= (1.0f / quad_count);
|
||||
|
||||
// If we still have more quadrangles than we should,
|
||||
// we try to eliminate bad ones based on minimizing the bounding box.
|
||||
@@ -1256,7 +1256,7 @@ int ChessBoardDetector::cleanFoundConnectedQuads(std::vector<ChessBoardQuad*>& q
|
||||
Mat points(1, quad_count, CV_32FC2, ¢ers[0]);
|
||||
cv::convexHull(points, hull, true);
|
||||
centers[skip] = temp;
|
||||
double hull_area = contourArea(hull, true);
|
||||
double hull_area = contourArea(hull, false);
|
||||
|
||||
// remember smallest box area
|
||||
if (hull_area < min_box_area)
|
||||
@@ -1298,6 +1298,7 @@ int ChessBoardDetector::cleanFoundConnectedQuads(std::vector<ChessBoardQuad*>& q
|
||||
quad_group[min_box_area_index] = quad_group[quad_count];
|
||||
centers[min_box_area_index] = centers[quad_count];
|
||||
}
|
||||
quad_group.resize(quad_count);
|
||||
|
||||
return quad_count;
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted
|
||||
|
||||
if (theta_d > 1e-8)
|
||||
{
|
||||
// compensate distortion iteratively
|
||||
// compensate distortion iteratively using Newton method
|
||||
double theta = theta_d;
|
||||
|
||||
const double EPS = 1e-8; // or std::numeric_limits<double>::epsilon();
|
||||
@@ -572,7 +572,7 @@ void cv::fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, Input
|
||||
: K.getMat().at<double>(0,0)/K.getMat().at<double>(1,1);
|
||||
|
||||
// convert to identity ratio
|
||||
cn[0] *= aspect_ratio;
|
||||
cn[1] *= aspect_ratio;
|
||||
for(size_t i = 0; i < points.total(); ++i)
|
||||
pptr[i][1] *= aspect_ratio;
|
||||
|
||||
|
||||
@@ -520,7 +520,7 @@ int cv::recoverPose( InputArray E, InputArray _points1, InputArray _points2,
|
||||
P3(Range::all(), Range(0, 3)) = R1 * 1.0; P3.col(3) = -t * 1.0;
|
||||
P4(Range::all(), Range(0, 3)) = R2 * 1.0; P4.col(3) = -t * 1.0;
|
||||
|
||||
// Do the cheirality check.
|
||||
// Do the chirality check.
|
||||
// Notice here a threshold dist is used to filter
|
||||
// out far away points (i.e. infinite points) since
|
||||
// their depth may vary between positive and negative.
|
||||
|
||||
@@ -149,12 +149,13 @@ public:
|
||||
int runKernel( InputArray _m1, InputArray _m2, OutputArray _model ) const CV_OVERRIDE
|
||||
{
|
||||
Mat opoints = _m1.getMat(), ipoints = _m2.getMat();
|
||||
|
||||
Mat iter_rvec = rvec.clone();
|
||||
Mat iter_tvec = tvec.clone();
|
||||
bool correspondence = solvePnP( _m1, _m2, cameraMatrix, distCoeffs,
|
||||
rvec, tvec, useExtrinsicGuess, flags );
|
||||
iter_rvec, iter_tvec, useExtrinsicGuess, flags );
|
||||
|
||||
Mat _local_model;
|
||||
hconcat(rvec, tvec, _local_model);
|
||||
hconcat(iter_rvec, iter_tvec, _local_model);
|
||||
_local_model.copyTo(_model);
|
||||
|
||||
return correspondence;
|
||||
@@ -313,7 +314,13 @@ bool solvePnPRansac(InputArray _opoints, InputArray _ipoints,
|
||||
ipoints_inliers.resize(npoints1);
|
||||
try
|
||||
{
|
||||
result = solvePnP(opoints_inliers, ipoints_inliers, cameraMatrix,
|
||||
if (flags == SOLVEPNP_ITERATIVE && !useExtrinsicGuess)
|
||||
{
|
||||
rvec = _local_model.col(0).clone();
|
||||
tvec = _local_model.col(1).clone();
|
||||
useExtrinsicGuess = true;
|
||||
}
|
||||
result = solvePnP(opoints_inliers, ipoints_inliers, cameraMatrix,
|
||||
distCoeffs, rvec, tvec, useExtrinsicGuess,
|
||||
(flags == SOLVEPNP_P3P || flags == SOLVEPNP_AP3P) ? SOLVEPNP_EPNP : flags) ? 1 : -1;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ private:
|
||||
static double det3x3(const cv::Matx<double, 9, 1>& e);
|
||||
|
||||
/*
|
||||
* @brief Tests the cheirality for a given solution.
|
||||
* @brief Tests the chirality for a given solution.
|
||||
* @param solution The solution to evaluate.
|
||||
*/
|
||||
inline bool positiveDepth(const SQPSolution& solution) const;
|
||||
|
||||
@@ -101,6 +101,15 @@ TEST_F(fisheyeTest, projectPoints)
|
||||
EXPECT_MAT_NEAR(distorted0, distorted2, 1e-10);
|
||||
}
|
||||
|
||||
// we use it to reduce patch size for images in testdata
|
||||
static void throwAwayHalf(Mat img)
|
||||
{
|
||||
int whalf = img.cols / 2, hhalf = img.rows / 2;
|
||||
Rect tl(0, 0, whalf, hhalf), br(whalf, hhalf, whalf, hhalf);
|
||||
img(tl) = 0;
|
||||
img(br) = 0;
|
||||
};
|
||||
|
||||
TEST_F(fisheyeTest, undistortImage)
|
||||
{
|
||||
cv::Matx33d theK = this->K;
|
||||
@@ -112,32 +121,41 @@ TEST_F(fisheyeTest, undistortImage)
|
||||
newK(0, 0) = 100;
|
||||
newK(1, 1) = 100;
|
||||
cv::fisheye::undistortImage(distorted, undistorted, theK, theD, newK);
|
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, "new_f_100.png"));
|
||||
if (correct.empty())
|
||||
CV_Assert(cv::imwrite(combine(datasets_repository_path, "new_f_100.png"), undistorted));
|
||||
else
|
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
|
||||
std::string imageFilename = combine(datasets_repository_path, "new_f_100.png");
|
||||
cv::Mat correct = cv::imread(imageFilename);
|
||||
ASSERT_FALSE(correct.empty()) << "Correct image " << imageFilename.c_str() << " can not be read" << std::endl;
|
||||
|
||||
throwAwayHalf(correct);
|
||||
throwAwayHalf(undistorted);
|
||||
|
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
|
||||
}
|
||||
{
|
||||
double balance = 1.0;
|
||||
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(theK, theD, distorted.size(), cv::noArray(), newK, balance);
|
||||
cv::fisheye::undistortImage(distorted, undistorted, theK, theD, newK);
|
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, "balance_1.0.png"));
|
||||
if (correct.empty())
|
||||
CV_Assert(cv::imwrite(combine(datasets_repository_path, "balance_1.0.png"), undistorted));
|
||||
else
|
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
|
||||
std::string imageFilename = combine(datasets_repository_path, "balance_1.0.png");
|
||||
cv::Mat correct = cv::imread(imageFilename);
|
||||
ASSERT_FALSE(correct.empty()) << "Correct image " << imageFilename.c_str() << " can not be read" << std::endl;
|
||||
|
||||
throwAwayHalf(correct);
|
||||
throwAwayHalf(undistorted);
|
||||
|
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
|
||||
}
|
||||
|
||||
{
|
||||
double balance = 0.0;
|
||||
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(theK, theD, distorted.size(), cv::noArray(), newK, balance);
|
||||
cv::fisheye::undistortImage(distorted, undistorted, theK, theD, newK);
|
||||
cv::Mat correct = cv::imread(combine(datasets_repository_path, "balance_0.0.png"));
|
||||
if (correct.empty())
|
||||
CV_Assert(cv::imwrite(combine(datasets_repository_path, "balance_0.0.png"), undistorted));
|
||||
else
|
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
|
||||
std::string imageFilename = combine(datasets_repository_path, "balance_0.0.png");
|
||||
cv::Mat correct = cv::imread(imageFilename);
|
||||
ASSERT_FALSE(correct.empty()) << "Correct image " << imageFilename.c_str() << " can not be read" << std::endl;
|
||||
|
||||
throwAwayHalf(correct);
|
||||
throwAwayHalf(undistorted);
|
||||
|
||||
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,19 +440,19 @@ TEST_F(fisheyeTest, stereoRectify)
|
||||
0.002076471801477729, 0.006463478587068991, 0.9999769555891836
|
||||
);
|
||||
cv::Matx34d P1_ref(
|
||||
420.8551870450913, 0, 586.501617798451, 0,
|
||||
0, 420.8551870450913, 374.7667511986098, 0,
|
||||
420.9684016542647, 0, 586.3059567784627, 0,
|
||||
0, 420.9684016542647, 374.8571836462291, 0,
|
||||
0, 0, 1, 0
|
||||
);
|
||||
cv::Matx34d P2_ref(
|
||||
420.8551870450913, 0, 586.501617798451, -41.77758076597302,
|
||||
0, 420.8551870450913, 374.7667511986098, 0,
|
||||
420.9684016542647, 0, 586.3059567784627, -41.78881938824554,
|
||||
0, 420.9684016542647, 374.8571836462291, 0,
|
||||
0, 0, 1, 0
|
||||
);
|
||||
cv::Matx44d Q_ref(
|
||||
1, 0, 0, -586.501617798451,
|
||||
0, 1, 0, -374.7667511986098,
|
||||
0, 0, 0, 420.8551870450913,
|
||||
1, 0, 0, -586.3059567784627,
|
||||
0, 1, 0, -374.8571836462291,
|
||||
0, 0, 0, 420.9684016542647,
|
||||
0, 0, 10.07370889670733, -0
|
||||
);
|
||||
|
||||
@@ -489,7 +507,9 @@ TEST_F(fisheyeTest, stereoRectify)
|
||||
cv::Mat rectification;
|
||||
merge4(l, r, lundist, rundist, rectification);
|
||||
|
||||
cv::imwrite(cv::format("fisheye_rectification_AB_%03d.png", i), rectification);
|
||||
// Add the "--test_debug" to arguments for file output
|
||||
if (cvtest::debugLevel > 0)
|
||||
cv::imwrite(cv::format("fisheye_rectification_AB_%03d.png", i), rectification);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,13 +703,13 @@ TEST_F(fisheyeTest, estimateNewCameraMatrixForUndistortRectify)
|
||||
|
||||
cv::Mat K_new_truth(3, 3, cv::DataType<double>::type);
|
||||
|
||||
K_new_truth.at<double>(0, 0) = 387.4809086880343;
|
||||
K_new_truth.at<double>(0, 0) = 387.5118215642316;
|
||||
K_new_truth.at<double>(0, 1) = 0.0;
|
||||
K_new_truth.at<double>(0, 2) = 1036.669802754649;
|
||||
K_new_truth.at<double>(0, 2) = 1033.936556777084;
|
||||
|
||||
K_new_truth.at<double>(1, 0) = 0.0;
|
||||
K_new_truth.at<double>(1, 1) = 373.6375700303157;
|
||||
K_new_truth.at<double>(1, 2) = 538.8373261247601;
|
||||
K_new_truth.at<double>(1, 1) = 373.6673784974842;
|
||||
K_new_truth.at<double>(1, 2) = 538.794152656429;
|
||||
|
||||
K_new_truth.at<double>(2, 0) = 0.0;
|
||||
K_new_truth.at<double>(2, 1) = 0.0;
|
||||
|
||||
@@ -6,7 +6,7 @@ ocv_add_dispatched_file(arithm SSE2 SSE4_1 AVX2 VSX3)
|
||||
ocv_add_dispatched_file(convert SSE2 AVX2 VSX3)
|
||||
ocv_add_dispatched_file(convert_scale SSE2 AVX2)
|
||||
ocv_add_dispatched_file(count_non_zero SSE2 AVX2)
|
||||
ocv_add_dispatched_file(matmul SSE2 SSE4_1 AVX2 AVX512_SKX)
|
||||
ocv_add_dispatched_file(matmul SSE2 SSE4_1 AVX2 AVX512_SKX NEON_DOTPROD)
|
||||
ocv_add_dispatched_file(mean SSE2 AVX2)
|
||||
ocv_add_dispatched_file(merge SSE2 AVX2)
|
||||
ocv_add_dispatched_file(split SSE2 AVX2)
|
||||
|
||||
@@ -71,7 +71,7 @@ data sharing. A destructor decrements the reference counter associated with the
|
||||
The buffer is deallocated if and only if the reference counter reaches zero, that is, when no other
|
||||
structures refer to the same buffer. Similarly, when a Mat instance is copied, no actual data is
|
||||
really copied. Instead, the reference counter is incremented to memorize that there is another owner
|
||||
of the same data. There is also the Mat::clone method that creates a full copy of the matrix data.
|
||||
of the same data. There is also the cv::Mat::clone method that creates a full copy of the matrix data.
|
||||
See the example below:
|
||||
```.cpp
|
||||
// create a big 8Mb matrix
|
||||
@@ -159,11 +159,11 @@ grayscale conversion. Note that frame and edges are allocated only once during t
|
||||
of the loop body since all the next video frames have the same resolution. If you somehow change the
|
||||
video resolution, the arrays are automatically reallocated.
|
||||
|
||||
The key component of this technology is the Mat::create method. It takes the desired array size and
|
||||
type. If the array already has the specified size and type, the method does nothing. Otherwise, it
|
||||
releases the previously allocated data, if any (this part involves decrementing the reference
|
||||
The key component of this technology is the cv::Mat::create method. It takes the desired array size
|
||||
and type. If the array already has the specified size and type, the method does nothing. Otherwise,
|
||||
it releases the previously allocated data, if any (this part involves decrementing the reference
|
||||
counter and comparing it with zero), and then allocates a new buffer of the required size. Most
|
||||
functions call the Mat::create method for each output array, and so the automatic output data
|
||||
functions call the cv::Mat::create method for each output array, and so the automatic output data
|
||||
allocation is implemented.
|
||||
|
||||
Some notable exceptions from this scheme are cv::mixChannels, cv::RNG::fill, and a few other
|
||||
@@ -247,9 +247,9 @@ Examples:
|
||||
// matrix (10-element complex vector)
|
||||
Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image
|
||||
// of 1920 columns and 1080 rows.
|
||||
Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of
|
||||
// the same size and same
|
||||
// channel type as img
|
||||
Mat grayscale(img.size(), CV_MAKETYPE(img.depth(), 1)); // make a 1-channel image of
|
||||
// the same size and same
|
||||
// channel type as img
|
||||
```
|
||||
Arrays with more complex elements cannot be constructed or processed using OpenCV. Furthermore, each
|
||||
function or method can handle only a subset of all possible array types. Usually, the more complex
|
||||
@@ -269,14 +269,14 @@ extended in future based on user requests.
|
||||
### InputArray and OutputArray
|
||||
|
||||
Many OpenCV functions process dense 2-dimensional or multi-dimensional numerical arrays. Usually,
|
||||
such functions take cppMat as parameters, but in some cases it's more convenient to use
|
||||
such functions take `cv::Mat` as parameters, but in some cases it's more convenient to use
|
||||
`std::vector<>` (for a point set, for example) or `cv::Matx<>` (for 3x3 homography matrix and such). To
|
||||
avoid many duplicates in the API, special "proxy" classes have been introduced. The base "proxy"
|
||||
class is cv::InputArray. It is used for passing read-only arrays on a function input. The derived from
|
||||
InputArray class cv::OutputArray is used to specify an output array for a function. Normally, you should
|
||||
not care of those intermediate types (and you should not declare variables of those types
|
||||
explicitly) - it will all just work automatically. You can assume that instead of
|
||||
InputArray/OutputArray you can always use `Mat`, `std::vector<>`, `cv::Matx<>`, `cv::Vec<>` or `cv::Scalar`. When a
|
||||
InputArray/OutputArray you can always use `cv::Mat`, `std::vector<>`, `cv::Matx<>`, `cv::Vec<>` or `cv::Scalar`. When a
|
||||
function has an optional input or output array, and you do not have or do not want one, pass
|
||||
cv::noArray().
|
||||
|
||||
@@ -288,7 +288,7 @@ the optimization algorithm did not converge), it returns a special error code (t
|
||||
boolean variable).
|
||||
|
||||
The exceptions can be instances of the cv::Exception class or its derivatives. In its turn,
|
||||
cv::Exception is a derivative of std::exception. So it can be gracefully handled in the code using
|
||||
cv::Exception is a derivative of `std::exception`. So it can be gracefully handled in the code using
|
||||
other standard C++ library components.
|
||||
|
||||
The exception is typically thrown either using the `#CV_Error(errcode, description)` macro, or its
|
||||
@@ -297,7 +297,7 @@ printf-like `#CV_Error_(errcode, (printf-spec, printf-args))` variant, or using
|
||||
satisfied. For performance-critical code, there is #CV_DbgAssert(condition) that is only retained in
|
||||
the Debug configuration. Due to the automatic memory management, all the intermediate buffers are
|
||||
automatically deallocated in case of a sudden error. You only need to add a try statement to catch
|
||||
exceptions, if needed: :
|
||||
exceptions, if needed:
|
||||
```.cpp
|
||||
try
|
||||
{
|
||||
|
||||
@@ -3095,12 +3095,16 @@ public:
|
||||
|
||||
/** @brief Stores algorithm parameters in a file storage
|
||||
*/
|
||||
virtual void write(FileStorage& fs) const { CV_UNUSED(fs); }
|
||||
CV_WRAP virtual void write(FileStorage& fs) const { CV_UNUSED(fs); }
|
||||
|
||||
/** @brief simplified API for language bindings
|
||||
/**
|
||||
* @overload
|
||||
*/
|
||||
CV_WRAP void write(const Ptr<FileStorage>& fs, const String& name = String()) const;
|
||||
CV_WRAP void write(FileStorage& fs, const String& name) const;
|
||||
#if CV_VERSION_MAJOR < 5
|
||||
/** @deprecated */
|
||||
void write(const Ptr<FileStorage>& fs, const String& name = String()) const;
|
||||
#endif
|
||||
|
||||
/** @brief Reads algorithm parameters from a file storage
|
||||
*/
|
||||
|
||||
@@ -213,6 +213,17 @@ AsyncArray testAsyncException()
|
||||
return p.getArrayResult();
|
||||
}
|
||||
|
||||
struct CV_EXPORTS_W_SIMPLE ClassWithKeywordProperties {
|
||||
CV_PROP_RW int lambda;
|
||||
CV_PROP int except;
|
||||
|
||||
CV_WRAP explicit ClassWithKeywordProperties(int lambda_arg = 24, int except_arg = 42)
|
||||
{
|
||||
lambda = lambda_arg;
|
||||
except = except_arg;
|
||||
}
|
||||
};
|
||||
|
||||
namespace nested {
|
||||
CV_WRAP static inline bool testEchoBooleanFunction(bool flag) {
|
||||
return flag;
|
||||
|
||||
@@ -65,6 +65,7 @@ struct CheckContext {
|
||||
static const cv::detail::CheckContext CV__CHECK_LOCATION_VARNAME(id) = \
|
||||
{ CV__CHECK_FUNCTION, CV__CHECK_FILENAME, __LINE__, testOp, "" message, "" p1_str, "" p2_str }
|
||||
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const bool v1, const bool v2, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v1, const size_t v2, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const float v1, const float v2, const CheckContext& ctx);
|
||||
@@ -74,6 +75,9 @@ CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, co
|
||||
CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v1, const int v2, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx);
|
||||
|
||||
CV_EXPORTS void CV_NORETURN check_failed_true(const bool v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_false(const bool v, const CheckContext& ctx);
|
||||
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const float v, const CheckContext& ctx);
|
||||
@@ -134,6 +138,12 @@ CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckCon
|
||||
/// Example: v == A || v == B
|
||||
#define CV_Check(v, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg)
|
||||
|
||||
/// Example: v == true
|
||||
#define CV_CheckTrue(v, msg) CV__CHECK_CUSTOM_TEST(_, true, v, v, #v, "", msg)
|
||||
|
||||
/// Example: v == false
|
||||
#define CV_CheckFalse(v, msg) CV__CHECK_CUSTOM_TEST(_, false, v, (!(v)), #v, "", msg)
|
||||
|
||||
/// Some complex conditions: CV_Check(src2, src2.empty() || (src2.type() == src1.type() && src2.size() == src1.size()), "src2 should have same size/type as src1")
|
||||
// TODO define pretty-printers
|
||||
|
||||
|
||||
@@ -488,8 +488,16 @@ public:
|
||||
//! Allocates a new GpuMat of given size and type.
|
||||
GpuMat getBuffer(int rows, int cols, int type);
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
//! Allocates a new GpuMat of given size and type.
|
||||
GpuMat getBuffer(Size size, int type) { return getBuffer(size.height, size.width, type); }
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//! Returns the allocator associated with the stream.
|
||||
Ptr<GpuMat::Allocator> getAllocator() const { return allocator_; }
|
||||
|
||||
@@ -75,6 +75,11 @@ GpuMat::GpuMat(Size size_, int type_, Allocator* allocator_)
|
||||
create(size_.height, size_.width, type_);
|
||||
}
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
inline
|
||||
GpuMat::GpuMat(int rows_, int cols_, int type_, Scalar s_, Allocator* allocator_)
|
||||
: flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_)
|
||||
@@ -96,6 +101,9 @@ GpuMat::GpuMat(Size size_, int type_, Scalar s_, Allocator* allocator_)
|
||||
setTo(s_);
|
||||
}
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
inline
|
||||
GpuMat::GpuMat(const GpuMat& m)
|
||||
@@ -158,11 +166,19 @@ GpuMat GpuMat::clone() const
|
||||
return m;
|
||||
}
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
inline
|
||||
void GpuMat::copyTo(OutputArray dst, InputArray mask) const
|
||||
{
|
||||
copyTo(dst, mask, Stream::Null());
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
inline
|
||||
GpuMat& GpuMat::setTo(Scalar s)
|
||||
@@ -176,6 +192,11 @@ GpuMat& GpuMat::setTo(Scalar s, InputArray mask)
|
||||
return setTo(s, mask, Stream::Null());
|
||||
}
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
inline
|
||||
void GpuMat::convertTo(OutputArray dst, int rtype) const
|
||||
{
|
||||
@@ -187,6 +208,9 @@ void GpuMat::convertTo(OutputArray dst, int rtype, double alpha, double beta) co
|
||||
{
|
||||
convertTo(dst, rtype, alpha, beta, Stream::Null());
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
inline
|
||||
void GpuMat::convertTo(OutputArray dst, int rtype, double alpha, Stream& stream) const
|
||||
@@ -554,6 +578,11 @@ Event::Event(const Ptr<Impl>& impl)
|
||||
// Initialization & Info
|
||||
//===================================================================================
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
inline
|
||||
bool TargetArchs::has(int major, int minor)
|
||||
{
|
||||
@@ -571,6 +600,9 @@ DeviceInfo::DeviceInfo()
|
||||
{
|
||||
device_id_ = getDevice();
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
inline
|
||||
DeviceInfo::DeviceInfo(int device_id)
|
||||
@@ -579,6 +611,11 @@ DeviceInfo::DeviceInfo(int device_id)
|
||||
device_id_ = device_id;
|
||||
}
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
inline
|
||||
int DeviceInfo::deviceID() const
|
||||
{
|
||||
@@ -607,6 +644,9 @@ bool DeviceInfo::supports(FeatureSet feature_set) const
|
||||
int version = majorVersion() * 10 + minorVersion();
|
||||
return version >= feature_set;
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace cv { namespace cuda {
|
||||
|
||||
@@ -79,6 +79,10 @@
|
||||
# endif
|
||||
# define CV_FP16 1
|
||||
#endif
|
||||
#ifdef CV_CPU_COMPILE_NEON_DOTPROD
|
||||
# include <arm_neon.h>
|
||||
# define CV_NEON_DOT 1
|
||||
#endif
|
||||
#ifdef CV_CPU_COMPILE_AVX2
|
||||
# include <immintrin.h>
|
||||
# define CV_AVX2 1
|
||||
|
||||
@@ -420,6 +420,27 @@
|
||||
#endif
|
||||
#define __CV_CPU_DISPATCH_CHAIN_NEON(fn, args, mode, ...) CV_CPU_CALL_NEON(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
|
||||
|
||||
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_NEON_DOTPROD
|
||||
# define CV_TRY_NEON_DOTPROD 1
|
||||
# define CV_CPU_FORCE_NEON_DOTPROD 1
|
||||
# define CV_CPU_HAS_SUPPORT_NEON_DOTPROD 1
|
||||
# define CV_CPU_CALL_NEON_DOTPROD(fn, args) return (cpu_baseline::fn args)
|
||||
# define CV_CPU_CALL_NEON_DOTPROD_(fn, args) return (opt_NEON_DOTPROD::fn args)
|
||||
#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_NEON_DOTPROD
|
||||
# define CV_TRY_NEON_DOTPROD 1
|
||||
# define CV_CPU_FORCE_NEON_DOTPROD 0
|
||||
# define CV_CPU_HAS_SUPPORT_NEON_DOTPROD (cv::checkHardwareSupport(CV_CPU_NEON_DOTPROD))
|
||||
# define CV_CPU_CALL_NEON_DOTPROD(fn, args) if (CV_CPU_HAS_SUPPORT_NEON_DOTPROD) return (opt_NEON_DOTPROD::fn args)
|
||||
# define CV_CPU_CALL_NEON_DOTPROD_(fn, args) if (CV_CPU_HAS_SUPPORT_NEON_DOTPROD) return (opt_NEON_DOTPROD::fn args)
|
||||
#else
|
||||
# define CV_TRY_NEON_DOTPROD 0
|
||||
# define CV_CPU_FORCE_NEON_DOTPROD 0
|
||||
# define CV_CPU_HAS_SUPPORT_NEON_DOTPROD 0
|
||||
# define CV_CPU_CALL_NEON_DOTPROD(fn, args)
|
||||
# define CV_CPU_CALL_NEON_DOTPROD_(fn, args)
|
||||
#endif
|
||||
#define __CV_CPU_DISPATCH_CHAIN_NEON_DOTPROD(fn, args, mode, ...) CV_CPU_CALL_NEON_DOTPROD(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
|
||||
|
||||
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_MSA
|
||||
# define CV_TRY_MSA 1
|
||||
# define CV_CPU_FORCE_MSA 1
|
||||
|
||||
@@ -282,6 +282,7 @@ namespace cv {
|
||||
#define CV_CPU_AVX_5124FMAPS 27
|
||||
|
||||
#define CV_CPU_NEON 100
|
||||
#define CV_CPU_NEON_DOTPROD 101
|
||||
|
||||
#define CV_CPU_MSA 150
|
||||
|
||||
@@ -334,6 +335,7 @@ enum CpuFeatures {
|
||||
CPU_AVX_5124FMAPS = 27,
|
||||
|
||||
CPU_NEON = 100,
|
||||
CPU_NEON_DOTPROD = 101,
|
||||
|
||||
CPU_MSA = 150,
|
||||
|
||||
@@ -721,7 +723,7 @@ Cv64suf;
|
||||
|
||||
|
||||
|
||||
// Integer types portatibility
|
||||
// Integer types portability
|
||||
#ifdef OPENCV_STDINT_HEADER
|
||||
#include OPENCV_STDINT_HEADER
|
||||
#elif defined(__cplusplus)
|
||||
|
||||
@@ -50,6 +50,12 @@
|
||||
#include <stdlib.h>
|
||||
#include "opencv2/core/cvdef.h"
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 12
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
#define OPENCV_HAL_ADD(a, b) ((a) + (b))
|
||||
#define OPENCV_HAL_AND(a, b) ((a) & (b))
|
||||
#define OPENCV_HAL_NOP(a) (a)
|
||||
@@ -695,4 +701,8 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
|
||||
|
||||
//! @endcond
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 12
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,8 +78,6 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
|
||||
#define CV_NEON_AARCH64 0
|
||||
#endif
|
||||
|
||||
// TODO
|
||||
#define CV_NEON_DOT 0
|
||||
|
||||
//////////// Utils ////////////
|
||||
|
||||
@@ -667,11 +665,22 @@ inline v_int64x2 v_dotprod(const v_int32x4& a, const v_int32x4& b, const v_int64
|
||||
}
|
||||
|
||||
// 8 >> 32
|
||||
#ifdef CV_NEON_DOT
|
||||
#define OPENCV_HAL_IMPL_NEON_DOT_PRODUCT_OP(_Tpvec1, _Tpvec2, suffix) \
|
||||
inline _Tpvec1 v_dotprod_expand(const _Tpvec2& a, const _Tpvec2& b) \
|
||||
{ \
|
||||
return _Tpvec1(vdotq_##suffix(vdupq_n_##suffix(0), a.val, b.val));\
|
||||
} \
|
||||
inline _Tpvec1 v_dotprod_expand(const _Tpvec2& a, const _Tpvec2& b, const _Tpvec1& c) \
|
||||
{ \
|
||||
return _Tpvec1(vdotq_##suffix(c.val, a.val, b.val)); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_DOT_PRODUCT_OP(v_uint32x4, v_uint8x16, u32)
|
||||
OPENCV_HAL_IMPL_NEON_DOT_PRODUCT_OP(v_int32x4, v_int8x16, s32)
|
||||
#else
|
||||
inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_uint32x4(vdotq_u32(vdupq_n_u32(0), a.val, b.val));
|
||||
#else
|
||||
const uint8x16_t zero = vreinterpretq_u8_u32(vdupq_n_u32(0));
|
||||
const uint8x16_t mask = vreinterpretq_u8_u32(vdupq_n_u32(0x00FF00FF));
|
||||
const uint16x8_t zero32 = vreinterpretq_u16_u32(vdupq_n_u32(0));
|
||||
@@ -687,23 +696,15 @@ inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b)
|
||||
uint32x4_t s1 = vaddq_u32(vshrq_n_u32(vreinterpretq_u32_u16(even), 16),
|
||||
vshrq_n_u32(vreinterpretq_u32_u16(odd), 16));
|
||||
return v_uint32x4(vaddq_u32(s0, s1));
|
||||
#endif
|
||||
}
|
||||
inline v_uint32x4 v_dotprod_expand(const v_uint8x16& a, const v_uint8x16& b,
|
||||
const v_uint32x4& c)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_uint32x4(vdotq_u32(c.val, a.val, b.val));
|
||||
#else
|
||||
return v_dotprod_expand(a, b) + c;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_int32x4(vdotq_s32(vdupq_n_s32(0), a.val, b.val));
|
||||
#else
|
||||
int16x8_t p0 = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val));
|
||||
int16x8_t p1 = vmull_s8(vget_high_s8(a.val), vget_high_s8(b.val));
|
||||
int16x8_t uzp1, uzp2;
|
||||
@@ -712,18 +713,13 @@ inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b)
|
||||
int16x4_t uzpl1, uzpl2;
|
||||
_v128_unzip(vget_low_s16(sum), vget_high_s16(sum), uzpl1, uzpl2);
|
||||
return v_int32x4(vaddl_s16(uzpl1, uzpl2));
|
||||
#endif
|
||||
}
|
||||
inline v_int32x4 v_dotprod_expand(const v_int8x16& a, const v_int8x16& b,
|
||||
const v_int32x4& c)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_int32x4(vdotq_s32(c.val, a.val, b.val));
|
||||
#else
|
||||
return v_dotprod_expand(a, b) + c;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
// 16 >> 64
|
||||
inline v_uint64x2 v_dotprod_expand(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
@@ -832,45 +828,44 @@ inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b, const v_
|
||||
}
|
||||
|
||||
// 8 >> 32
|
||||
#ifdef CV_NEON_DOT
|
||||
#define OPENCV_HAL_IMPL_NEON_DOT_PRODUCT_FAST_OP(_Tpvec1, _Tpvec2, suffix) \
|
||||
inline _Tpvec1 v_dotprod_expand_fast(const _Tpvec2& a, const _Tpvec2& b) \
|
||||
{ \
|
||||
return v_dotprod_expand(a, b); \
|
||||
} \
|
||||
inline _Tpvec1 v_dotprod_expand_fast(const _Tpvec2& a, const _Tpvec2& b, const _Tpvec1& c) \
|
||||
{ \
|
||||
return v_dotprod_expand(a, b, c); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_DOT_PRODUCT_FAST_OP(v_uint32x4, v_uint8x16, u32)
|
||||
OPENCV_HAL_IMPL_NEON_DOT_PRODUCT_FAST_OP(v_int32x4, v_int8x16, s32)
|
||||
#else
|
||||
inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_uint32x4(vdotq_u32(vdupq_n_u32(0), a.val, b.val));
|
||||
#else
|
||||
uint16x8_t p0 = vmull_u8(vget_low_u8(a.val), vget_low_u8(b.val));
|
||||
uint16x8_t p1 = vmull_u8(vget_high_u8(a.val), vget_high_u8(b.val));
|
||||
uint32x4_t s0 = vaddl_u16(vget_low_u16(p0), vget_low_u16(p1));
|
||||
uint32x4_t s1 = vaddl_u16(vget_high_u16(p0), vget_high_u16(p1));
|
||||
return v_uint32x4(vaddq_u32(s0, s1));
|
||||
#endif
|
||||
}
|
||||
inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b, const v_uint32x4& c)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_uint32x4(vdotq_u32(c.val, a.val, b.val));
|
||||
#else
|
||||
return v_dotprod_expand_fast(a, b) + c;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_int32x4(vdotq_s32(vdupq_n_s32(0), a.val, b.val));
|
||||
#else
|
||||
int16x8_t prod = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val));
|
||||
prod = vmlal_s8(prod, vget_high_s8(a.val), vget_high_s8(b.val));
|
||||
return v_int32x4(vaddl_s16(vget_low_s16(prod), vget_high_s16(prod)));
|
||||
#endif
|
||||
}
|
||||
inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b, const v_int32x4& c)
|
||||
{
|
||||
#if CV_NEON_DOT
|
||||
return v_int32x4(vdotq_s32(c.val, a.val, b.val));
|
||||
#else
|
||||
return v_dotprod_expand_fast(a, b) + c;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// 16 >> 64
|
||||
inline v_uint64x2 v_dotprod_expand_fast(const v_uint16x8& a, const v_uint16x8& b)
|
||||
|
||||
@@ -681,11 +681,19 @@ Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp
|
||||
for(int i = 16; i < channels; i++) val[i] = _Tp(0);
|
||||
}
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(const _Tp* values)
|
||||
{
|
||||
for( int i = 0; i < channels; i++ ) val[i] = values[i];
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef CV_CXX11
|
||||
template<typename _Tp, int m, int n> inline
|
||||
|
||||
@@ -703,10 +703,18 @@ cv::ogl::Texture2D::Format cv::ogl::Texture2D::format() const
|
||||
|
||||
///////
|
||||
|
||||
// WARNING: unreachable code using Ninja
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
inline
|
||||
cv::ogl::Arrays::Arrays() : size_(0)
|
||||
{
|
||||
}
|
||||
#if defined _MSC_VER && _MSC_VER >= 1920
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
inline
|
||||
int cv::ogl::Arrays::size() const
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace cv { namespace utils { namespace fs {
|
||||
* Provides interprocess synchronization mechanism.
|
||||
* Platform dependent.
|
||||
*
|
||||
* Supports multiple readers / single writer access pattern (RW / readers–writer / shared-exclusive lock).
|
||||
* Supports multiple readers / single writer access pattern (RW / readers-writer / shared-exclusive lock).
|
||||
*
|
||||
* File must exist.
|
||||
* File can't be re-used (for example, I/O operations via std::fstream is not safe)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#define CV_VERSION_MAJOR 3
|
||||
#define CV_VERSION_MINOR 4
|
||||
#define CV_VERSION_REVISION 18
|
||||
#define CV_VERSION_STATUS "-pre"
|
||||
#define CV_VERSION_REVISION 19
|
||||
#define CV_VERSION_STATUS ""
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -55,19 +55,27 @@ Algorithm::~Algorithm()
|
||||
CV_TRACE_FUNCTION();
|
||||
}
|
||||
|
||||
void Algorithm::write(const Ptr<FileStorage>& fs, const String& name) const
|
||||
void Algorithm::write(FileStorage& fs, const String& name) const
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
if(name.empty())
|
||||
{
|
||||
write(*fs);
|
||||
write(fs);
|
||||
return;
|
||||
}
|
||||
*fs << name << "{";
|
||||
write(*fs);
|
||||
*fs << "}";
|
||||
fs << name << "{";
|
||||
write(fs);
|
||||
fs << "}";
|
||||
}
|
||||
|
||||
#if CV_VERSION_MAJOR < 5
|
||||
void Algorithm::write(const Ptr<FileStorage>& fs, const String& name) const
|
||||
{
|
||||
CV_Assert(fs);
|
||||
write(*fs, name);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Algorithm::save(const String& filename) const
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
@@ -29,8 +29,7 @@ public:
|
||||
}
|
||||
void cleanup() const
|
||||
{
|
||||
CV_Assert(ptr && *ptr);
|
||||
*ptr = 0;
|
||||
CV_DbgAssert(ptr);
|
||||
if (raw_mem)
|
||||
fastFree(raw_mem);
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@ void check_failed_MatChannels(const int v1, const int v2, const CheckContext& ct
|
||||
{
|
||||
check_failed_auto_<int>(v1, v2, ctx);
|
||||
}
|
||||
void check_failed_auto(const bool v1, const bool v2, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_<bool>(v1, v2, ctx);
|
||||
}
|
||||
void check_failed_auto(const int v1, const int v2, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_<int>(v1, v2, ctx);
|
||||
@@ -151,6 +155,22 @@ void check_failed_MatChannels(const int v, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_<int>(v, ctx);
|
||||
}
|
||||
void check_failed_true(const bool v, const CheckContext& ctx)
|
||||
{
|
||||
CV_UNUSED(v);
|
||||
std::stringstream ss;
|
||||
ss << ctx.message << ":" << std::endl
|
||||
<< " '" << ctx.p1_str << "' must be 'true'";
|
||||
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
|
||||
}
|
||||
void check_failed_false(const bool v, const CheckContext& ctx)
|
||||
{
|
||||
CV_UNUSED(v);
|
||||
std::stringstream ss;
|
||||
ss << ctx.message << ":" << std::endl
|
||||
<< " '" << ctx.p1_str << "' must be 'false'";
|
||||
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
|
||||
}
|
||||
void check_failed_auto(const int v, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_<int>(v, ctx);
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
#if defined(__clang__) && defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#define CV_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
|
||||
__msan_unpoison(adresse, size)
|
||||
__msan_unpoison(address, size)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef CV_ANNOTATE_MEMORY_IS_INITIALIZED
|
||||
@@ -244,6 +244,11 @@ lapack_SVD(fptype* a, size_t a_step, fptype *w, fptype* u, size_t u_step, fptype
|
||||
lwork = (int)round(work1); //optimal buffer size
|
||||
fptype* buffer = new fptype[lwork + 1];
|
||||
|
||||
// Make sure MSAN sees the memory as having been written.
|
||||
// MSAN does not think it has been written because a different language is called.
|
||||
// Note: we do this here because if dgesdd is C++, MSAN errors can be reported within it.
|
||||
CV_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, sizeof(fptype) * (lwork + 1));
|
||||
|
||||
if(typeid(fptype) == typeid(float))
|
||||
OCV_LAPACK_FUNC(sgesdd)(mode, &m, &n, (float*)a, &lda, (float*)w, (float*)u, &ldu, (float*)vt, &ldv, (float*)buffer, &lwork, iworkBuf, info);
|
||||
else if(typeid(fptype) == typeid(double))
|
||||
@@ -252,7 +257,6 @@ lapack_SVD(fptype* a, size_t a_step, fptype *w, fptype* u, size_t u_step, fptype
|
||||
// Make sure MSAN sees the memory as having been written.
|
||||
// MSAN does not think it has been written because a different language was called.
|
||||
CV_ANNOTATE_MEMORY_IS_INITIALIZED(a, a_step * n);
|
||||
CV_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, sizeof(fptype) * (lwork + 1));
|
||||
if (u)
|
||||
CV_ANNOTATE_MEMORY_IS_INITIALIZED(u, u_step * m);
|
||||
if (vt)
|
||||
|
||||
@@ -973,6 +973,12 @@ bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* minLoc
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (dev.deviceVersionMajor() == 1 && dev.deviceVersionMinor() < 2)
|
||||
{
|
||||
// 'static' storage class specifier used by "minmaxloc" is available from OpenCL 1.2+ only
|
||||
return false;
|
||||
}
|
||||
|
||||
bool doubleSupport = dev.doubleFPConfig() > 0, haveMask = !_mask.empty(),
|
||||
haveSrc2 = _src2.kind() != _InputArray::NONE;
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type),
|
||||
|
||||
@@ -52,11 +52,13 @@ DECLARE_CV_PAUSE
|
||||
#endif
|
||||
#ifndef CV_PAUSE
|
||||
# if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
|
||||
# include <x86intrin.h> /* for __rdtsc */
|
||||
# if !defined(__SSE2__)
|
||||
static inline void cv_non_sse_mm_pause() { __asm__ __volatile__ ("rep; nop"); }
|
||||
# define _mm_pause cv_non_sse_mm_pause
|
||||
# endif
|
||||
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { _mm_pause(); } } while (0)
|
||||
// With Skylake CPUs and above, _mm_pause takes 140 cycles so no need for a loop.
|
||||
# define CV_PAUSE(v) do { (void)v; _mm_pause(); } while (0)
|
||||
# elif defined __GNUC__ && defined __aarch64__
|
||||
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("yield" ::: "memory"); } } while (0)
|
||||
# elif defined __GNUC__ && defined __arm__
|
||||
|
||||
@@ -301,6 +301,9 @@ DECLARE_CV_CPUID_X86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined CV_CXX11
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -411,6 +414,7 @@ struct HWFeatures
|
||||
g_hwFeatureNames[CPU_AVX_5124FMAPS] = "AVX5124FMAPS";
|
||||
|
||||
g_hwFeatureNames[CPU_NEON] = "NEON";
|
||||
g_hwFeatureNames[CPU_NEON_DOTPROD] = "NEON_DOTPROD";
|
||||
|
||||
g_hwFeatureNames[CPU_VSX] = "VSX";
|
||||
g_hwFeatureNames[CPU_VSX3] = "VSX3";
|
||||
@@ -555,6 +559,24 @@ struct HWFeatures
|
||||
#ifdef __aarch64__
|
||||
have[CV_CPU_NEON] = true;
|
||||
have[CV_CPU_FP16] = true;
|
||||
int cpufile = open("/proc/self/auxv", O_RDONLY);
|
||||
|
||||
if (cpufile >= 0)
|
||||
{
|
||||
Elf64_auxv_t auxv;
|
||||
const size_t size_auxv_t = sizeof(auxv);
|
||||
|
||||
while ((size_t)read(cpufile, &auxv, size_auxv_t) == size_auxv_t)
|
||||
{
|
||||
if (auxv.a_type == AT_HWCAP)
|
||||
{
|
||||
have[CV_CPU_NEON_DOTPROD] = (auxv.a_un.a_val & (1 << 20)) != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(cpufile);
|
||||
}
|
||||
#elif defined __arm__ && defined __ANDROID__
|
||||
#if defined HAVE_CPUFEATURES
|
||||
CV_LOG_INFO(NULL, "calling android_getCpuFeatures() ...");
|
||||
@@ -598,13 +620,20 @@ struct HWFeatures
|
||||
close(cpufile);
|
||||
}
|
||||
#endif
|
||||
#elif (defined __clang__ || defined __APPLE__)
|
||||
#elif (defined __APPLE__)
|
||||
#if (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
|
||||
have[CV_CPU_NEON] = true;
|
||||
#endif
|
||||
#if (defined __ARM_FP && (((__ARM_FP & 0x2) != 0) && defined __ARM_NEON__))
|
||||
have[CV_CPU_FP16] = true;
|
||||
#endif
|
||||
#elif (defined __clang__)
|
||||
#if (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
|
||||
have[CV_CPU_NEON] = true;
|
||||
#if (defined __ARM_FP && ((__ARM_FP & 0x2) != 0))
|
||||
have[CV_CPU_FP16] = true;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined _ARM_ && (defined(_WIN32_WCE) && _WIN32_WCE >= 0x800)
|
||||
have[CV_CPU_NEON] = true;
|
||||
@@ -833,7 +862,10 @@ bool useOptimized(void)
|
||||
|
||||
int64 getTickCount(void)
|
||||
{
|
||||
#if defined _WIN32 || defined WINCE
|
||||
#if defined CV_CXX11
|
||||
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
return (int64)now.time_since_epoch().count();
|
||||
#elif defined _WIN32 || defined WINCE
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter( &counter );
|
||||
return (int64)counter.QuadPart;
|
||||
@@ -852,7 +884,11 @@ int64 getTickCount(void)
|
||||
|
||||
double getTickFrequency(void)
|
||||
{
|
||||
#if defined _WIN32 || defined WINCE
|
||||
#if defined CV_CXX11
|
||||
using clock_period_t = std::chrono::steady_clock::duration::period;
|
||||
double clock_freq = clock_period_t::den / clock_period_t::num;
|
||||
return clock_freq;
|
||||
#elif defined _WIN32 || defined WINCE
|
||||
LARGE_INTEGER freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
return (double)freq.QuadPart;
|
||||
|
||||
@@ -403,9 +403,6 @@ TEST_P(BufferArea, basic)
|
||||
EXPECT_EQ((double)0, dbl_ptr[i]);
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(int_ptr == NULL);
|
||||
EXPECT_TRUE(uchar_ptr == NULL);
|
||||
EXPECT_TRUE(dbl_ptr == NULL);
|
||||
}
|
||||
|
||||
TEST_P(BufferArea, align)
|
||||
@@ -442,10 +439,6 @@ TEST_P(BufferArea, align)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < CNT; ++i)
|
||||
{
|
||||
EXPECT_TRUE(buffers[i] == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(BufferArea, default_align)
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
#include "opencv2/core/async.hpp"
|
||||
|
||||
#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_EXPERIMENTAL_NS
|
||||
#define CV__DNN_EXPERIMENTAL_NS_BEGIN namespace experimental_dnn_34_v25 {
|
||||
#define CV__DNN_EXPERIMENTAL_NS_BEGIN namespace experimental_dnn_34_v26 {
|
||||
#define CV__DNN_EXPERIMENTAL_NS_END }
|
||||
namespace cv { namespace dnn { namespace experimental_dnn_34_v25 { } using namespace experimental_dnn_34_v25; }}
|
||||
namespace cv { namespace dnn { namespace experimental_dnn_34_v26 { } using namespace experimental_dnn_34_v26; }}
|
||||
#else
|
||||
#define CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
#define CV__DNN_EXPERIMENTAL_NS_END
|
||||
|
||||
@@ -160,22 +160,49 @@ static inline MatShape shape(int a0, int a1=-1, int a2=-1, int a3=-1)
|
||||
|
||||
static inline int total(const MatShape& shape, int start = -1, int end = -1)
|
||||
{
|
||||
if (start == -1) start = 0;
|
||||
if (end == -1) end = (int)shape.size();
|
||||
|
||||
if (shape.empty())
|
||||
return 0;
|
||||
|
||||
int dims = (int)shape.size();
|
||||
|
||||
if (start == -1) start = 0;
|
||||
if (end == -1) end = dims;
|
||||
|
||||
CV_CheckLE(0, start, "");
|
||||
CV_CheckLE(start, end, "");
|
||||
CV_CheckLE(end, dims, "");
|
||||
|
||||
int elems = 1;
|
||||
CV_Assert(start <= (int)shape.size() && end <= (int)shape.size() &&
|
||||
start <= end);
|
||||
for(int i = start; i < end; i++)
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
elems *= shape[i];
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
// TODO: rename to countDimsElements()
|
||||
static inline int total(const Mat& mat, int start = -1, int end = -1)
|
||||
{
|
||||
if (mat.empty())
|
||||
return 0;
|
||||
|
||||
int dims = mat.dims;
|
||||
|
||||
if (start == -1) start = 0;
|
||||
if (end == -1) end = dims;
|
||||
|
||||
CV_CheckLE(0, start, "");
|
||||
CV_CheckLE(start, end, "");
|
||||
CV_CheckLE(end, dims, "");
|
||||
|
||||
int elems = 1;
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
elems *= mat.size[i];
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
static inline MatShape concat(const MatShape& a, const MatShape& b)
|
||||
{
|
||||
MatShape c = a;
|
||||
|
||||
@@ -204,14 +204,13 @@ public:
|
||||
std::vector<InferenceEngine::DataConfig> outDataConfig;
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2020_2)
|
||||
InferenceEngine::SizeVector order;
|
||||
size_t offset = std::numeric_limits<size_t>::max();
|
||||
for (int i = 0; i < node->get_input_size(); ++i)
|
||||
{
|
||||
InferenceEngine::DataConfig conf;
|
||||
auto shape = node->input_value(i).get_shape();
|
||||
order.resize(shape.size());
|
||||
std::iota(order.begin(), order.end(), 0);
|
||||
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order, offset});
|
||||
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order});
|
||||
inDataConfig.push_back(conf);
|
||||
}
|
||||
|
||||
@@ -221,7 +220,7 @@ public:
|
||||
auto shape = node->output(i).get_shape();
|
||||
order.resize(shape.size());
|
||||
std::iota(order.begin(), order.end(), 0);
|
||||
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order, offset});
|
||||
conf.desc = InferenceEngine::TensorDesc(InferenceEngine::Precision::FP32, shape, {shape, order});
|
||||
outDataConfig.push_back(conf);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -208,8 +208,8 @@ public:
|
||||
const float* inpData = inp0.ptr<float>();
|
||||
float* outData = outputs[0].ptr<float>();
|
||||
|
||||
size_t num = total(shape(inp0.size), 0, startAxis);
|
||||
size_t numPlanes = total(shape(inp0.size), startAxis, endAxis + 1);
|
||||
size_t num = total(inp0, 0, startAxis);
|
||||
size_t numPlanes = total(inp0, startAxis, endAxis + 1);
|
||||
CV_Assert(num * numPlanes != 0);
|
||||
size_t planeSize = inp0.total() / (num * numPlanes);
|
||||
for (size_t n = 0; n < num; ++n)
|
||||
|
||||
@@ -91,6 +91,16 @@ public:
|
||||
if (hasWeights && hasBias)
|
||||
CV_CheckEQ(weights.total(), bias.total(), "Incompatible weights/bias blobs");
|
||||
|
||||
if (weights.total() == 1)
|
||||
{
|
||||
// The total() of bias should be same as weights.
|
||||
if (hasBias)
|
||||
inpBlob.convertTo(outBlob, CV_32F, weights.at<float>(0), bias.at<float>(0));
|
||||
else
|
||||
inpBlob.convertTo(outBlob, CV_32F, weights.at<float>(0));
|
||||
return;
|
||||
}
|
||||
|
||||
int endAxis;
|
||||
for (endAxis = axis + 1; endAxis <= inpBlob.dims; ++endAxis)
|
||||
{
|
||||
|
||||
@@ -1759,15 +1759,15 @@ void ONNXImporter::parseBatchNormalization(LayerParams& layerParams, const openc
|
||||
addLayer(layerParams, node_proto);
|
||||
}
|
||||
|
||||
// A * B + C = Y, we require that the dimension of A is [m, k], and the dimension of B is [n, k].
|
||||
// And the dim of output Y is [m, n]
|
||||
void ONNXImporter::parseGemm(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
|
||||
{
|
||||
CV_Assert(node_proto.input_size() >= 2);
|
||||
layerParams.type = "InnerProduct";
|
||||
Mat weights = getBlob(node_proto, 1);
|
||||
int ind_num_out = 0;
|
||||
if (layerParams.has("transB") && !layerParams.get<int>("transB")) {
|
||||
if (!layerParams.get<int>("transB", 0)) {
|
||||
transpose(weights, weights);
|
||||
ind_num_out = 1;
|
||||
}
|
||||
layerParams.blobs.push_back(weights);
|
||||
|
||||
@@ -1789,7 +1789,7 @@ void ONNXImporter::parseGemm(LayerParams& layerParams, const opencv_onnx::NodePr
|
||||
addLayer(constParams, proto);
|
||||
}
|
||||
|
||||
layerParams.set("num_output", layerParams.blobs[0].size[ind_num_out]);
|
||||
layerParams.set("num_output", layerParams.blobs[0].size[0]);
|
||||
layerParams.set("bias_term", node_proto.input_size() == 3);
|
||||
addLayer(layerParams, node_proto);
|
||||
}
|
||||
@@ -1818,6 +1818,8 @@ void ONNXImporter::parseMatMul(LayerParams& layerParams, const opencv_onnx::Node
|
||||
|
||||
void findBroadAxis(const MatShape& broadShape, const MatShape& outShape, size_t& axis, int& broadAxis)
|
||||
{
|
||||
// Currently, this function can only complete 1-dimensional expansion of broadShape.
|
||||
// If there are two dimensions in broadShape that need to be expended, it will fail.
|
||||
const size_t diff = outShape.size() - broadShape.size();
|
||||
|
||||
// find the first non-one element of the broadcasting shape
|
||||
@@ -1982,25 +1984,30 @@ void ONNXImporter::parseMul(LayerParams& layerParams, const opencv_onnx::NodePro
|
||||
const MatShape& outShape = outShapes[node_proto.input(0)];
|
||||
|
||||
size_t axis = 0;
|
||||
int broadAxis = -1;
|
||||
findBroadAxis(broadShape, outShape, axis, broadAxis);
|
||||
|
||||
// if there is a one dimension in the middle that should be broadcasted, broadcast it
|
||||
if (broadAxis != -1)
|
||||
if (total(broadShape) != 1)
|
||||
{
|
||||
opencv_onnx::NodeProto concat_node_proto = node_proto;
|
||||
const std::string& input1 = concat_node_proto.input(1);
|
||||
// If broadShape is a scalar, we set axis as 0.
|
||||
// Other-wise, we check broadcast is available.
|
||||
int broadAxis = -1;
|
||||
findBroadAxis(broadShape, outShape, axis, broadAxis);
|
||||
|
||||
expandMid(layerParams.name, concat_node_proto, input1, outShape[broadAxis]);
|
||||
// if there is a one dimension in the middle that should be broadcasted, broadcast it
|
||||
if (broadAxis != -1)
|
||||
{
|
||||
opencv_onnx::NodeProto concat_node_proto = node_proto;
|
||||
const std::string& input1 = concat_node_proto.input(1);
|
||||
|
||||
LayerParams concatLP;
|
||||
concatLP.name = layerParams.name + "/concat";
|
||||
concatLP.set("axis", broadAxis);
|
||||
concatLP.type = "Concat";
|
||||
concat_node_proto.set_output(0, concatLP.name);
|
||||
expandMid(layerParams.name, concat_node_proto, input1, outShape[broadAxis]);
|
||||
|
||||
addLayer(concatLP, concat_node_proto);
|
||||
node_proto.set_input(1, concatLP.name);
|
||||
LayerParams concatLP;
|
||||
concatLP.name = layerParams.name + "/concat";
|
||||
concatLP.set("axis", broadAxis);
|
||||
concatLP.type = "Concat";
|
||||
concat_node_proto.set_output(0, concatLP.name);
|
||||
|
||||
addLayer(concatLP, concat_node_proto);
|
||||
node_proto.set_input(1, concatLP.name);
|
||||
}
|
||||
}
|
||||
|
||||
CV_Assert(axis != outShape.size());
|
||||
|
||||
@@ -829,12 +829,19 @@ void RemoveIdentityOps(tensorflow::GraphDef& net)
|
||||
IdentityOpsMap::iterator it = identity_ops.find(input_op_name);
|
||||
|
||||
if (it != identity_ops.end()) {
|
||||
std::set<String> loopCheckSet;
|
||||
// In case of Identity after Identity
|
||||
while (true)
|
||||
{
|
||||
IdentityOpsMap::iterator nextIt = identity_ops.find(it->second);
|
||||
if (nextIt != identity_ops.end())
|
||||
{
|
||||
// Loop check
|
||||
if (loopCheckSet.find(it->second) != loopCheckSet.end())
|
||||
CV_Error(Error::StsError, "Found a loop in your input Tensorflow model, which is illegal!");
|
||||
loopCheckSet.insert(it->second);
|
||||
it = nextIt;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -207,12 +207,6 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// May hang on some configurations
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
|
||||
@@ -699,10 +699,6 @@ TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
|
||||
// Check 'backward_compatible_check || in_out_elements_equal' failed at core/src/op/reshape.cpp:427:
|
||||
// While validating node 'v1::Reshape bbox_pred_reshape (bbox_pred[0]:f32{1,84}, Constant_265242[0]:i64{4}) -> (f32{?,?,?,?})' with friendly_name 'bbox_pred_reshape':
|
||||
// Requested output shape {1,6300,4,1} is incompatible with input shape {1, 84}
|
||||
@@ -734,12 +730,6 @@ TEST_P(Test_Caffe_nets, FasterRCNN_zf)
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
|
||||
|
||||
@@ -916,20 +916,10 @@ TEST_P(Test_Darknet_layers, shortcut_leaky)
|
||||
}
|
||||
TEST_P(Test_Darknet_layers, shortcut_unequal)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
testDarknetLayer("shortcut_unequal");
|
||||
}
|
||||
TEST_P(Test_Darknet_layers, shortcut_unequal_2)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
testDarknetLayer("shortcut_unequal_2");
|
||||
}
|
||||
|
||||
|
||||
@@ -637,12 +637,6 @@ TEST_P(NoParamActivation, Accuracy)
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
std::string layer_type = get<0>(GetParam());
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && targetId == DNN_TARGET_CPU && layer_type == "BNLL")
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
LayerParams lp;
|
||||
lp.type = layer_type;
|
||||
lp.name = "testLayer";
|
||||
|
||||
@@ -1431,12 +1431,6 @@ static void test_dldt_fused_output(Backend backend, Target target)
|
||||
|
||||
TEST_P(Test_DLDT_layers, fused_output)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Unsupported, UnsupportedLayer);
|
||||
try
|
||||
{
|
||||
@@ -1596,16 +1590,7 @@ TEST_P(Test_Caffe_layers, Interp)
|
||||
TEST_P(Test_Caffe_layers, DISABLED_Interp) // requires patched protobuf (available in OpenCV source tree only)
|
||||
#endif
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
|
||||
#endif
|
||||
|
||||
@@ -103,12 +103,6 @@ TEST_P(Test_ONNX_layers, MaxPooling)
|
||||
}
|
||||
TEST_P(Test_ONNX_layers, MaxPooling_2)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
testONNXModels("two_maxpooling", npy, 0, 0, false, false);
|
||||
}
|
||||
|
||||
@@ -725,6 +719,8 @@ TEST_P(Test_ONNX_layers, Div)
|
||||
|
||||
normAssert(ref, out, "", default_l1, default_lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
|
||||
testONNXModels("div_test_1x1",npy, 0, 0, false, true, 2);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, DynamicReshape)
|
||||
@@ -791,17 +787,6 @@ TEST_P(Test_ONNX_layers, Slice_Steps_2DInput)
|
||||
|
||||
TEST_P(Test_ONNX_layers, Slice_Steps_3DInput)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#endif
|
||||
|
||||
testONNXModels("slice_opset_11_steps_3d");
|
||||
}
|
||||
|
||||
@@ -812,20 +797,6 @@ TEST_P(Test_ONNX_layers, Slice_Steps_4DInput)
|
||||
|
||||
TEST_P(Test_ONNX_layers, Slice_Steps_5DInput)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// IE exception: Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
|
||||
testONNXModels("slice_opset_11_steps_5d");
|
||||
}
|
||||
|
||||
@@ -848,9 +819,6 @@ TEST_P(Test_ONNX_layers, Split_EltwiseMax)
|
||||
TEST_P(Test_ONNX_layers, LSTM_Activations)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// IE exception: Node Block1326/lstm/reshape_0/permute was not assigned on any pointed device
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
@@ -887,9 +855,6 @@ TEST_P(Test_ONNX_layers, LSTM_hidden)
|
||||
TEST_P(Test_ONNX_layers, LSTM_hidden_bidirectional)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// IE exception: Node Transpose_45 was not assigned on any pointed device.
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
@@ -917,11 +882,7 @@ TEST_P(Test_ONNX_layers, LSTM_cell_forward)
|
||||
}
|
||||
TEST_P(Test_ONNX_layers, LSTM_cell_bidirectional)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021040000)
|
||||
// Ngraph operation Reshape with name LSTM_16/lstm_y/reshape has dynamic output shape on 0 port, but CPU plug-in supports only static shape
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -1283,16 +1244,7 @@ TEST_P(Test_ONNX_layers, MaxPoolSigmoid1d)
|
||||
|
||||
TEST_P(Test_ONNX_layers, MaxPool1d_Twise)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
@@ -1307,11 +1259,7 @@ TEST_P(Test_ONNX_layers, MaxPool1d_Twise)
|
||||
|
||||
TEST_P(Test_ONNX_layers, AvePool1d)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
@@ -1326,19 +1274,7 @@ TEST_P(Test_ONNX_layers, AvePool1d)
|
||||
|
||||
TEST_P(Test_ONNX_layers, PoolConv1d)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#elif defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
@@ -1389,6 +1325,12 @@ TEST_P(Test_ONNX_layers, DivConst)
|
||||
testONNXModels("div_const");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, Gemm)
|
||||
{
|
||||
testONNXModels("gemm_no_transB");
|
||||
testONNXModels("gemm_transB_0");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, OutputRegistration)
|
||||
{
|
||||
testONNXModels("output_registration", npy, 0, 0, false, true, 2);
|
||||
|
||||
@@ -207,9 +207,6 @@ TEST_P(Test_TensorFlow_layers, conv_keras_atrous_conv2d_same)
|
||||
TEST_P(Test_TensorFlow_layers, conv_pool_nchw)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -476,9 +473,6 @@ TEST_P(Test_TensorFlow_layers, slim_batch_norm)
|
||||
TEST_P(Test_TensorFlow_layers, pooling_max_pool_even)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -491,9 +485,6 @@ TEST_P(Test_TensorFlow_layers, pooling_max_pool_even)
|
||||
TEST_P(Test_TensorFlow_layers, pooling_max_pool_odd_valid)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -506,9 +497,6 @@ TEST_P(Test_TensorFlow_layers, pooling_max_pool_odd_valid)
|
||||
TEST_P(Test_TensorFlow_layers, pooling_max_pool_odd_same)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -789,14 +777,6 @@ TEST_P(Test_TensorFlow_layers, BiasAdd)
|
||||
TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
// accuracy
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -999,9 +979,6 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN_resnet50_coco_2018_01_28)
|
||||
);
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: subgraphTopoSortsStep < subgraphs.size()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -1210,9 +1187,6 @@ TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_single_conv)
|
||||
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_max_pool_odd_same)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -1241,9 +1215,6 @@ TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_padding_valid)
|
||||
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_max_pool_even)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -1268,9 +1239,6 @@ TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_deconvolution)
|
||||
TEST_P(Test_TensorFlow_layers, fp16_weights_fp16_max_pool_odd_valid)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// [ GENERAL_ERROR ] AssertionFailed: !expired()
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
@@ -1355,16 +1323,6 @@ TEST_P(Test_TensorFlow_layers, split_equals)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION
|
||||
);
|
||||
#endif
|
||||
runTensorFlowNet("resize_nearest_neighbor");
|
||||
}
|
||||
TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor_keras_upsampling2d)
|
||||
@@ -1434,14 +1392,7 @@ TEST_P(Test_TensorFlow_layers, relu6)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, subpixel)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_CPU, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
// Cannot get memory!
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#elif defined(INF_ENGINE_RELEASE)
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
|
||||