mirror of
https://github.com/opencv/opencv.git
synced 2026-07-25 21:33:04 +04:00
Compare commits
227 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a2b3c8d4c | |||
| edacd91a27 | |||
| 5dd46b54c1 | |||
| ea502b6e84 | |||
| 24ced3d657 | |||
| c5a5d7eb51 | |||
| ab2c16b2e5 | |||
| 113793fee7 | |||
| 954536073d | |||
| b54a70a538 | |||
| cc45c10f3d | |||
| 6d2cfac303 | |||
| 13aa23f706 | |||
| f8a27d2603 | |||
| f185640eda | |||
| 78b51fb574 | |||
| 72eccb7694 | |||
| 803f86b9ca | |||
| 7bac615d8f | |||
| dc3406eed9 | |||
| f0ddc2a53c | |||
| 1cc3f7abbb | |||
| 70177143a7 | |||
| 43d9256096 | |||
| 803ff64b14 | |||
| 824241ad5c | |||
| d5d059690f | |||
| fd832bb57d | |||
| 09cb329d73 | |||
| 4a9291fd89 | |||
| 5677a683a5 | |||
| c813ad5533 | |||
| 0b77600718 | |||
| 5115e5decb | |||
| 429a643f42 | |||
| d2a66d3c99 | |||
| 0f41daeba5 | |||
| 1be75437b7 | |||
| 978ad4981e | |||
| 8c4f886f5f | |||
| 0d63c4c28e | |||
| 6843d368b2 | |||
| 24af70c7e0 | |||
| 1ed9ff17e1 | |||
| 9dc1d388af | |||
| 28cb714a09 | |||
| 91c6d36ff8 | |||
| be76b451cb | |||
| 53785b6ac6 | |||
| 2332fb852d | |||
| f1fdfa1a51 | |||
| 0f3fe957f5 | |||
| 41398987c3 | |||
| de8024ce4a | |||
| 7b9b876726 | |||
| 944710de4e | |||
| 2b3c7490d5 | |||
| 8965f3ae06 | |||
| 5771fd693d | |||
| 1ff11c84ab | |||
| 5faaa28870 | |||
| fc4679d4cf | |||
| 761c269e47 | |||
| 131d199ae3 | |||
| 35c53204cb | |||
| f731515628 | |||
| 4e62900009 | |||
| 7813eef92b | |||
| 59bf2a34fa | |||
| abbb73e894 | |||
| cc10e6b344 | |||
| 11e2a216c5 | |||
| 404893810c | |||
| 53ec8f286b | |||
| 70f2ee917e | |||
| ad93ed720d | |||
| cc3ec5d453 | |||
| 288251e672 | |||
| dada5a422d | |||
| 421fdc0e94 | |||
| c4d434fd6f | |||
| 8bb3d363a4 | |||
| b8aa0cddab | |||
| 50811e04f2 | |||
| 449826288b | |||
| 1522722fab | |||
| 68fe37b008 | |||
| 26ba4f3c1d | |||
| e19b422854 | |||
| 913c4151bf | |||
| 78a802baae | |||
| 9d602f2752 | |||
| 7649e537b7 | |||
| 2faa4cd933 | |||
| 0492301e76 | |||
| 18bf91a08b | |||
| 09ef4c9cff | |||
| 634dd656d5 | |||
| 9d02d42afe | |||
| c716e374c1 | |||
| aeec6e43eb | |||
| 8f1f4273a2 | |||
| 630a94b8b7 | |||
| ceca139f7f | |||
| da5e0ef461 | |||
| 4fa6734320 | |||
| a9c8a526cf | |||
| 0926a84a45 | |||
| 0101fa789c | |||
| 12b3d157a5 | |||
| 60c26f8f1e | |||
| 7294ae0f17 | |||
| 0ffc186680 | |||
| 699db77293 | |||
| 50beef605b | |||
| 068ebe8b4d | |||
| ffaf58349c | |||
| eec468fa13 | |||
| 81c94357e8 | |||
| 042c486b68 | |||
| 6921f967a1 | |||
| 83a0c12144 | |||
| fa8684b5c8 | |||
| 690fb0544c | |||
| 283348afc3 | |||
| ee0c985491 | |||
| b41f38ecc7 | |||
| 682180e0cd | |||
| 1385db48f5 | |||
| 94201b7cf9 | |||
| 15632c6305 | |||
| 6b84990620 | |||
| c9b6b2cf04 | |||
| 617fe2545c | |||
| 93663dc57a | |||
| 28e55dc5f3 | |||
| ae4c72a153 | |||
| 9253e8bda2 | |||
| 0f031b6680 | |||
| 255b20f6de | |||
| ac9ec55b37 | |||
| df4139d373 | |||
| 1059735bfb | |||
| 8f2eb60719 | |||
| a1ffc00ba8 | |||
| 1a81a97e9f | |||
| e6ef9221cb | |||
| ee84ae0551 | |||
| bd04568baf | |||
| ea92c2b1a6 | |||
| 8ecdd215b6 | |||
| 5a3bca8d5c | |||
| 9b9f38afc8 | |||
| 9ac7aea930 | |||
| 5f17cc1abd | |||
| 8f6695acc7 | |||
| 9524abcd28 | |||
| 4fea6179a0 | |||
| 055f177a6a | |||
| 83efde6243 | |||
| 8eb987e393 | |||
| 2c6ab65476 | |||
| 66fdddc339 | |||
| 3c5a6be835 | |||
| 5575171652 | |||
| a8b0db4e5d | |||
| 4b895a4d1f | |||
| e9f99063c7 | |||
| e104fcc000 | |||
| 9f0ff03da5 | |||
| 9ba659af84 | |||
| be989b3b60 | |||
| 0706bd72b8 | |||
| f6dc396a0f | |||
| 48e8e76a34 | |||
| e4f71994c2 | |||
| fae329a0ca | |||
| 29e88e50ff | |||
| 52f52f6786 | |||
| 852f061b26 | |||
| fe56bdeeb9 | |||
| b34d86ca24 | |||
| 24ab751547 | |||
| c8f3579f93 | |||
| f0d277e452 | |||
| 962dc21f2b | |||
| 2e8483bd1c | |||
| 3eec8fd0eb | |||
| 43e66e7ff9 | |||
| ad5898224d | |||
| f8398d80bc | |||
| d8d025c33b | |||
| 8811dabbac | |||
| 9faacfbc0d | |||
| a610be6335 | |||
| 6a5266df79 | |||
| 238a3806b0 | |||
| a07a4cefe1 | |||
| a0211a1c2f | |||
| 47bb09bc4b | |||
| efca746d36 | |||
| 93b0b03447 | |||
| e0f524d3b7 | |||
| d1c842cf29 | |||
| 4d23a5d92d | |||
| 0739d1c2eb | |||
| 475c775b25 | |||
| b7e8ce4523 | |||
| 0a23c1bf11 | |||
| e8fcd721b8 | |||
| ecef7f7930 | |||
| 5db13fe2a7 | |||
| 9932612373 | |||
| 6203c95d31 | |||
| d5d19a9f67 | |||
| ef5579dc86 | |||
| 84ae8097b1 | |||
| f33f236ab6 | |||
| 95b1fe0776 | |||
| 35bee663eb | |||
| 98f6ea0785 | |||
| 295b988657 | |||
| e0a5824028 | |||
| d3eed2cf23 | |||
| 51f7eb3a3c | |||
| b35fbff675 | |||
| 30597e5c98 |
Vendored
+22
-36
@@ -151,6 +151,10 @@ void div(const Size2D &size,
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
|
||||
#if defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
|
||||
static_assert(std::numeric_limits<T>::is_integer, "template implementation is for integer types only");
|
||||
#endif
|
||||
|
||||
if (scale == 0.0f ||
|
||||
(std::numeric_limits<T>::is_integer &&
|
||||
(scale * std::numeric_limits<T>::max()) < 1.0f &&
|
||||
@@ -311,6 +315,10 @@ void recip(const Size2D &size,
|
||||
typedef typename internal::VecTraits<T>::vec128 vec128;
|
||||
typedef typename internal::VecTraits<T>::vec64 vec64;
|
||||
|
||||
#if defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
|
||||
static_assert(std::numeric_limits<T>::is_integer, "template implementation is for integer types only");
|
||||
#endif
|
||||
|
||||
if (scale == 0.0f ||
|
||||
(std::numeric_limits<T>::is_integer &&
|
||||
scale < 1.0f &&
|
||||
@@ -463,8 +471,6 @@ void div(const Size2D &size,
|
||||
return;
|
||||
}
|
||||
|
||||
float32x4_t v_zero = vdupq_n_f32(0.0f);
|
||||
|
||||
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
|
||||
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
|
||||
|
||||
@@ -485,9 +491,7 @@ void div(const Size2D &size,
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_f32(v_src0, internal::vrecpq_f32(v_src1))), v_mask)));
|
||||
vst1q_f32(dst + j, vmulq_f32(v_src0, internal::vrecpq_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
@@ -495,14 +499,12 @@ void div(const Size2D &size,
|
||||
float32x2_t v_src0 = vld1_f32(src0 + j);
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_f32(v_src0, internal::vrecp_f32(v_src1))), v_mask)));
|
||||
vst1_f32(dst + j, vmul_f32(v_src0, internal::vrecp_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? src0[j] / src1[j] : 0.0f;
|
||||
dst[j] = src0[j] / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,10 +525,8 @@ void div(const Size2D &size,
|
||||
float32x4_t v_src0 = vld1q_f32(src0 + j);
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_f32(vmulq_n_f32(v_src0, scale),
|
||||
internal::vrecpq_f32(v_src1))), v_mask)));
|
||||
vst1q_f32(dst + j, vmulq_f32(vmulq_n_f32(v_src0, scale),
|
||||
internal::vrecpq_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
@@ -534,15 +534,13 @@ void div(const Size2D &size,
|
||||
float32x2_t v_src0 = vld1_f32(src0 + j);
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_f32(vmul_n_f32(v_src0, scale),
|
||||
internal::vrecp_f32(v_src1))), v_mask)));
|
||||
vst1_f32(dst + j, vmul_f32(vmul_n_f32(v_src0, scale),
|
||||
internal::vrecp_f32(v_src1)));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? src0[j] * scale / src1[j] : 0.0f;
|
||||
dst[j] = src0[j] * scale / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -620,8 +618,6 @@ void reciprocal(const Size2D &size,
|
||||
return;
|
||||
}
|
||||
|
||||
float32x4_t v_zero = vdupq_n_f32(0.0f);
|
||||
|
||||
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
|
||||
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
|
||||
|
||||
@@ -639,23 +635,19 @@ void reciprocal(const Size2D &size,
|
||||
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(internal::vrecpq_f32(v_src1)), v_mask)));
|
||||
vst1q_f32(dst + j, internal::vrecpq_f32(v_src1));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(internal::vrecp_f32(v_src1)), v_mask)));
|
||||
vst1_f32(dst + j, internal::vrecp_f32(v_src1));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? 1.0f / src1[j] : 0;
|
||||
dst[j] = 1.0f / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,25 +665,19 @@ void reciprocal(const Size2D &size,
|
||||
|
||||
float32x4_t v_src1 = vld1q_f32(src1 + j);
|
||||
|
||||
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
|
||||
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
|
||||
vreinterpretq_u32_f32(vmulq_n_f32(internal::vrecpq_f32(v_src1),
|
||||
scale)),v_mask)));
|
||||
vst1q_f32(dst + j, vmulq_n_f32(internal::vrecpq_f32(v_src1), scale));
|
||||
}
|
||||
|
||||
for (; j < roiw64; j += 2)
|
||||
{
|
||||
float32x2_t v_src1 = vld1_f32(src1 + j);
|
||||
|
||||
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
|
||||
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
|
||||
vreinterpret_u32_f32(vmul_n_f32(internal::vrecp_f32(v_src1),
|
||||
scale)), v_mask)));
|
||||
vst1_f32(dst + j, vmul_n_f32(internal::vrecp_f32(v_src1), scale));
|
||||
}
|
||||
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
dst[j] = src1[j] ? scale / src1[j] : 0;
|
||||
dst[j] = scale / src1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ $output = "$PSScriptRoot\@OPENCV_BIN_INSTALL_PATH@\opencv_ffmpeg@OPENCV_DLLVERSI
|
||||
|
||||
Write-Output ("=" * 120)
|
||||
try {
|
||||
Get-content -Path "$PSScriptRoot\etc\licenses\ffmpeg-readme.txt" -ErrorAction 'Stop'
|
||||
Get-content -Path "$PSScriptRoot\@OPENCV_LICENSES_INSTALL_PATH@\ffmpeg-readme.txt" -ErrorAction 'Stop'
|
||||
} catch {
|
||||
Write-Output "Refer to OpenCV FFmpeg wrapper readme notes about library usage / licensing details."
|
||||
}
|
||||
|
||||
Vendored
+2
@@ -40,3 +40,5 @@ if(OPENCV_INSTALL_FFMPEG_DOWNLOAD_SCRIPT)
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/ffmpeg-download.ps1.in" "${CMAKE_BINARY_DIR}/win-install/ffmpeg-download.ps1" @ONLY)
|
||||
install(FILES "${CMAKE_BINARY_DIR}/win-install/ffmpeg-download.ps1" DESTINATION "." COMPONENT libs)
|
||||
endif()
|
||||
|
||||
ocv_install_3rdparty_licenses(ffmpeg license.txt readme.txt)
|
||||
|
||||
@@ -146,6 +146,14 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
|
||||
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
|
||||
Atomic64 old_value,
|
||||
Atomic64 new_value) {
|
||||
__atomic_compare_exchange_n(ptr, &old_value, new_value, false,
|
||||
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
#endif // defined(__LP64__)
|
||||
|
||||
} // namespace internal
|
||||
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
project(quirc)
|
||||
|
||||
set(CURR_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
|
||||
|
||||
set_property(GLOBAL PROPERTY QUIRC_INCLUDE_DIR ${CURR_INCLUDE_DIR})
|
||||
ocv_include_directories(${CURR_INCLUDE_DIR})
|
||||
|
||||
file(GLOB_RECURSE quirc_headers RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "include/*.h")
|
||||
file(GLOB_RECURSE quirc_sources RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "src/*.c")
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${quirc_headers} ${quirc_sources})
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-variable -Wshadow)
|
||||
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES OUTPUT_NAME ${PROJECT_NAME}
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
COMPILE_PDB_NAME ${PROJECT_NAME}
|
||||
COMPILE_PDB_NAME_DEBUG "${PROJECT_NAME}${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
|
||||
)
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "3rdparty")
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
ocv_install_target(${PROJECT_NAME} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
|
||||
ocv_install_3rdparty_licenses(${PROJECT_NAME} LICENSE)
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
quirc -- QR-code recognition library
|
||||
Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
above copyright notice and this permission notice appear in all
|
||||
copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
Vendored
+173
@@ -0,0 +1,173 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_H_
|
||||
#define QUIRC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct quirc;
|
||||
|
||||
/* Obtain the library version string. */
|
||||
const char *quirc_version(void);
|
||||
|
||||
/* Construct a new QR-code recognizer. This function will return NULL
|
||||
* if sufficient memory could not be allocated.
|
||||
*/
|
||||
struct quirc *quirc_new(void);
|
||||
|
||||
/* Destroy a QR-code recognizer. */
|
||||
void quirc_destroy(struct quirc *q);
|
||||
|
||||
/* Resize the QR-code recognizer. The size of an image must be
|
||||
* specified before codes can be analyzed.
|
||||
*
|
||||
* This function returns 0 on success, or -1 if sufficient memory could
|
||||
* not be allocated.
|
||||
*/
|
||||
int quirc_resize(struct quirc *q, int w, int h);
|
||||
|
||||
/* These functions are used to process images for QR-code recognition.
|
||||
* quirc_begin() must first be called to obtain access to a buffer into
|
||||
* which the input image should be placed. Optionally, the current
|
||||
* width and height may be returned.
|
||||
*
|
||||
* After filling the buffer, quirc_end() should be called to process
|
||||
* the image for QR-code recognition. The locations and content of each
|
||||
* code may be obtained using accessor functions described below.
|
||||
*/
|
||||
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
|
||||
void quirc_end(struct quirc *q);
|
||||
|
||||
/* This structure describes a location in the input image buffer. */
|
||||
struct quirc_point {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
/* This enum describes the various decoder errors which may occur. */
|
||||
typedef enum {
|
||||
QUIRC_SUCCESS = 0,
|
||||
QUIRC_ERROR_INVALID_GRID_SIZE,
|
||||
QUIRC_ERROR_INVALID_VERSION,
|
||||
QUIRC_ERROR_FORMAT_ECC,
|
||||
QUIRC_ERROR_DATA_ECC,
|
||||
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
|
||||
QUIRC_ERROR_DATA_OVERFLOW,
|
||||
QUIRC_ERROR_DATA_UNDERFLOW
|
||||
} quirc_decode_error_t;
|
||||
|
||||
/* Return a string error message for an error code. */
|
||||
const char *quirc_strerror(quirc_decode_error_t err);
|
||||
|
||||
/* Limits on the maximum size of QR-codes and their content. */
|
||||
#define QUIRC_MAX_BITMAP 3917
|
||||
#define QUIRC_MAX_PAYLOAD 8896
|
||||
|
||||
/* QR-code ECC types. */
|
||||
#define QUIRC_ECC_LEVEL_M 0
|
||||
#define QUIRC_ECC_LEVEL_L 1
|
||||
#define QUIRC_ECC_LEVEL_H 2
|
||||
#define QUIRC_ECC_LEVEL_Q 3
|
||||
|
||||
/* QR-code data types. */
|
||||
#define QUIRC_DATA_TYPE_NUMERIC 1
|
||||
#define QUIRC_DATA_TYPE_ALPHA 2
|
||||
#define QUIRC_DATA_TYPE_BYTE 4
|
||||
#define QUIRC_DATA_TYPE_KANJI 8
|
||||
|
||||
/* Common character encodings */
|
||||
#define QUIRC_ECI_ISO_8859_1 1
|
||||
#define QUIRC_ECI_IBM437 2
|
||||
#define QUIRC_ECI_ISO_8859_2 4
|
||||
#define QUIRC_ECI_ISO_8859_3 5
|
||||
#define QUIRC_ECI_ISO_8859_4 6
|
||||
#define QUIRC_ECI_ISO_8859_5 7
|
||||
#define QUIRC_ECI_ISO_8859_6 8
|
||||
#define QUIRC_ECI_ISO_8859_7 9
|
||||
#define QUIRC_ECI_ISO_8859_8 10
|
||||
#define QUIRC_ECI_ISO_8859_9 11
|
||||
#define QUIRC_ECI_WINDOWS_874 13
|
||||
#define QUIRC_ECI_ISO_8859_13 15
|
||||
#define QUIRC_ECI_ISO_8859_15 17
|
||||
#define QUIRC_ECI_SHIFT_JIS 20
|
||||
#define QUIRC_ECI_UTF_8 26
|
||||
|
||||
/* This structure is used to return information about detected QR codes
|
||||
* in the input image.
|
||||
*/
|
||||
struct quirc_code {
|
||||
/* The four corners of the QR-code, from top left, clockwise */
|
||||
struct quirc_point corners[4];
|
||||
|
||||
/* The number of cells across in the QR-code. The cell bitmap
|
||||
* is a bitmask giving the actual values of cells. If the cell
|
||||
* at (x, y) is black, then the following bit is set:
|
||||
*
|
||||
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
||||
*
|
||||
* where i = (y * size) + x.
|
||||
*/
|
||||
int size;
|
||||
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
|
||||
};
|
||||
|
||||
/* This structure holds the decoded QR-code data */
|
||||
struct quirc_data {
|
||||
/* Various parameters of the QR-code. These can mostly be
|
||||
* ignored if you only care about the data.
|
||||
*/
|
||||
int version;
|
||||
int ecc_level;
|
||||
int mask;
|
||||
|
||||
/* This field is the highest-valued data type found in the QR
|
||||
* code.
|
||||
*/
|
||||
int data_type;
|
||||
|
||||
/* Data payload. For the Kanji datatype, payload is encoded as
|
||||
* Shift-JIS. For all other datatypes, payload is ASCII text.
|
||||
*/
|
||||
uint8_t payload[QUIRC_MAX_PAYLOAD];
|
||||
int payload_len;
|
||||
|
||||
/* ECI assignment number */
|
||||
uint32_t eci;
|
||||
};
|
||||
|
||||
/* Return the number of QR-codes identified in the last processed
|
||||
* image.
|
||||
*/
|
||||
int quirc_count(const struct quirc *q);
|
||||
|
||||
/* Extract the QR-code specified by the given index. */
|
||||
void quirc_extract(const struct quirc *q, int index,
|
||||
struct quirc_code *code);
|
||||
|
||||
/* Decode a QR-code, returning the payload data. */
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUIRC_INTERNAL_H_
|
||||
#define QUIRC_INTERNAL_H_
|
||||
|
||||
#include <quirc.h>
|
||||
|
||||
#define QUIRC_PIXEL_WHITE 0
|
||||
#define QUIRC_PIXEL_BLACK 1
|
||||
#define QUIRC_PIXEL_REGION 2
|
||||
|
||||
#ifndef QUIRC_MAX_REGIONS
|
||||
#define QUIRC_MAX_REGIONS 254
|
||||
#endif
|
||||
#define QUIRC_MAX_CAPSTONES 32
|
||||
#define QUIRC_MAX_GRIDS 8
|
||||
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
#endif
|
||||
|
||||
struct quirc_region {
|
||||
struct quirc_point seed;
|
||||
int count;
|
||||
int capstone;
|
||||
};
|
||||
|
||||
struct quirc_capstone {
|
||||
int ring;
|
||||
int stone;
|
||||
|
||||
struct quirc_point corners[4];
|
||||
struct quirc_point center;
|
||||
double c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
|
||||
int qr_grid;
|
||||
};
|
||||
|
||||
struct quirc_grid {
|
||||
/* Capstone indices */
|
||||
int caps[3];
|
||||
|
||||
/* Alignment pattern region and corner */
|
||||
int align_region;
|
||||
struct quirc_point align;
|
||||
|
||||
/* Timing pattern endpoints */
|
||||
struct quirc_point tpep[3];
|
||||
int hscan;
|
||||
int vscan;
|
||||
|
||||
/* Grid size and perspective transform */
|
||||
int grid_size;
|
||||
double c[QUIRC_PERSPECTIVE_PARAMS];
|
||||
};
|
||||
|
||||
struct quirc {
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int *row_average; /* used by threshold() */
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int num_regions;
|
||||
struct quirc_region regions[QUIRC_MAX_REGIONS];
|
||||
|
||||
int num_capstones;
|
||||
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
|
||||
|
||||
int num_grids;
|
||||
struct quirc_grid grids[QUIRC_MAX_GRIDS];
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* QR-code version information database
|
||||
*/
|
||||
|
||||
#define QUIRC_MAX_VERSION 40
|
||||
#define QUIRC_MAX_ALIGNMENT 7
|
||||
|
||||
struct quirc_rs_params {
|
||||
int bs; /* Small block size */
|
||||
int dw; /* Small data words */
|
||||
int ns; /* Number of small blocks */
|
||||
};
|
||||
|
||||
struct quirc_version_info {
|
||||
int data_bytes;
|
||||
int apat[QUIRC_MAX_ALIGNMENT];
|
||||
struct quirc_rs_params ecc[4];
|
||||
};
|
||||
|
||||
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
|
||||
|
||||
#endif
|
||||
Vendored
+919
@@ -0,0 +1,919 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <quirc_internal.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_POLY 64
|
||||
|
||||
/************************************************************************
|
||||
* Galois fields
|
||||
*/
|
||||
|
||||
struct galois_field {
|
||||
int p;
|
||||
const uint8_t *log;
|
||||
const uint8_t *exp;
|
||||
};
|
||||
|
||||
static const uint8_t gf16_exp[16] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
|
||||
0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01
|
||||
};
|
||||
|
||||
static const uint8_t gf16_log[16] = {
|
||||
0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
|
||||
0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c
|
||||
};
|
||||
|
||||
static const struct galois_field gf16 = {
|
||||
.p = 15,
|
||||
.log = gf16_log,
|
||||
.exp = gf16_exp
|
||||
};
|
||||
|
||||
static const uint8_t gf256_exp[256] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
|
||||
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
|
||||
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
|
||||
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
|
||||
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
|
||||
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
|
||||
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
|
||||
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
|
||||
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
|
||||
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
|
||||
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
|
||||
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
|
||||
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
|
||||
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
|
||||
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
|
||||
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
|
||||
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
|
||||
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
|
||||
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
|
||||
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
|
||||
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
|
||||
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
|
||||
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
|
||||
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
|
||||
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
|
||||
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
|
||||
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
|
||||
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
|
||||
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
|
||||
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
|
||||
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
|
||||
};
|
||||
|
||||
static const uint8_t gf256_log[256] = {
|
||||
0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
|
||||
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
|
||||
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
|
||||
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
|
||||
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
|
||||
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
|
||||
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
|
||||
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
|
||||
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
|
||||
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
|
||||
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
|
||||
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
|
||||
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
|
||||
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
|
||||
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
|
||||
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
|
||||
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
|
||||
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
|
||||
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
|
||||
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
|
||||
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
|
||||
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
|
||||
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
|
||||
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
|
||||
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
|
||||
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
|
||||
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
|
||||
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
|
||||
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
|
||||
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
|
||||
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
|
||||
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
|
||||
};
|
||||
|
||||
static const struct galois_field gf256 = {
|
||||
.p = 255,
|
||||
.log = gf256_log,
|
||||
.exp = gf256_exp
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* Polynomial operations
|
||||
*/
|
||||
|
||||
static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
|
||||
int shift, const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
int log_c = gf->log[c];
|
||||
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++) {
|
||||
int p = i + shift;
|
||||
uint8_t v = src[i];
|
||||
|
||||
if (p < 0 || p >= MAX_POLY)
|
||||
continue;
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t poly_eval(const uint8_t *s, uint8_t x,
|
||||
const struct galois_field *gf)
|
||||
{
|
||||
int i;
|
||||
uint8_t sum = 0;
|
||||
uint8_t log_x = gf->log[x];
|
||||
|
||||
if (!x)
|
||||
return s[0];
|
||||
|
||||
for (i = 0; i < MAX_POLY; i++) {
|
||||
uint8_t c = s[i];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Berlekamp-Massey algorithm for finding error locator polynomials.
|
||||
*/
|
||||
|
||||
static void berlekamp_massey(const uint8_t *s, int N,
|
||||
const struct galois_field *gf,
|
||||
uint8_t *sigma)
|
||||
{
|
||||
uint8_t C[MAX_POLY];
|
||||
uint8_t B[MAX_POLY];
|
||||
int L = 0;
|
||||
int m = 1;
|
||||
uint8_t b = 1;
|
||||
int n;
|
||||
|
||||
memset(B, 0, sizeof(B));
|
||||
memset(C, 0, sizeof(C));
|
||||
B[0] = 1;
|
||||
C[0] = 1;
|
||||
|
||||
for (n = 0; n < N; n++) {
|
||||
uint8_t d = s[n];
|
||||
uint8_t mult;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= L; i++) {
|
||||
if (!(C[i] && s[n - i]))
|
||||
continue;
|
||||
|
||||
d ^= gf->exp[(gf->log[C[i]] +
|
||||
gf->log[s[n - i]]) %
|
||||
gf->p];
|
||||
}
|
||||
|
||||
mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
|
||||
|
||||
if (!d) {
|
||||
m++;
|
||||
} else if (L * 2 <= n) {
|
||||
uint8_t T[MAX_POLY];
|
||||
|
||||
memcpy(T, C, sizeof(T));
|
||||
poly_add(C, B, mult, m, gf);
|
||||
memcpy(B, T, sizeof(B));
|
||||
L = n + 1 - L;
|
||||
b = d;
|
||||
m = 1;
|
||||
} else {
|
||||
poly_add(C, B, mult, m, gf);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(sigma, C, MAX_POLY);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Code stream error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
|
||||
*/
|
||||
|
||||
static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
|
||||
{
|
||||
int nonzero = 0;
|
||||
int i;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < bs; j++) {
|
||||
uint8_t c = data[bs - j - 1];
|
||||
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
s[i] ^= gf256_exp[((int)gf256_log[c] +
|
||||
i * j) % 255];
|
||||
}
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static void eloc_poly(uint8_t *omega,
|
||||
const uint8_t *s, const uint8_t *sigma,
|
||||
int npar)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(omega, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < npar; i++) {
|
||||
const uint8_t a = sigma[i];
|
||||
const uint8_t log_a = gf256_log[a];
|
||||
int j;
|
||||
|
||||
if (!a)
|
||||
continue;
|
||||
|
||||
for (j = 0; j + 1 < MAX_POLY; j++) {
|
||||
const uint8_t b = s[j + 1];
|
||||
|
||||
if (i + j >= npar)
|
||||
break;
|
||||
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
omega[i + j] ^=
|
||||
gf256_exp[(log_a + gf256_log[b]) % 255];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_block(uint8_t *data,
|
||||
const struct quirc_rs_params *ecc)
|
||||
{
|
||||
int npar = ecc->bs - ecc->dw;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
uint8_t sigma_deriv[MAX_POLY];
|
||||
uint8_t omega[MAX_POLY];
|
||||
int i;
|
||||
|
||||
/* Compute syndrome vector */
|
||||
if (!block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, npar, &gf256, sigma);
|
||||
|
||||
/* Compute derivative of sigma */
|
||||
memset(sigma_deriv, 0, MAX_POLY);
|
||||
for (i = 0; i + 1 < MAX_POLY; i += 2)
|
||||
sigma_deriv[i] = sigma[i + 1];
|
||||
|
||||
/* Compute error evaluator polynomial */
|
||||
eloc_poly(omega, s, sigma, npar - 1);
|
||||
|
||||
/* Find error locations and magnitudes */
|
||||
for (i = 0; i < ecc->bs; i++) {
|
||||
uint8_t xinv = gf256_exp[255 - i];
|
||||
|
||||
if (!poly_eval(sigma, xinv, &gf256)) {
|
||||
uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
|
||||
uint8_t omega_x = poly_eval(omega, xinv, &gf256);
|
||||
uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
|
||||
gf256_log[omega_x]) % 255];
|
||||
|
||||
data[ecc->bs - i - 1] ^= error;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_syndromes(data, ecc->bs, npar, s))
|
||||
return QUIRC_ERROR_DATA_ECC;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Format value error correction
|
||||
*
|
||||
* Generator polynomial for GF(2^4) is x^4 + x + 1
|
||||
*/
|
||||
|
||||
#define FORMAT_MAX_ERROR 3
|
||||
#define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
|
||||
#define FORMAT_BITS 15
|
||||
|
||||
static int format_syndromes(uint16_t u, uint8_t *s)
|
||||
{
|
||||
int i;
|
||||
int nonzero = 0;
|
||||
|
||||
memset(s, 0, MAX_POLY);
|
||||
|
||||
for (i = 0; i < FORMAT_SYNDROMES; i++) {
|
||||
int j;
|
||||
|
||||
s[i] = 0;
|
||||
for (j = 0; j < FORMAT_BITS; j++)
|
||||
if (u & (1 << j))
|
||||
s[i] ^= gf16_exp[((i + 1) * j) % 15];
|
||||
|
||||
if (s[i])
|
||||
nonzero = 1;
|
||||
}
|
||||
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t correct_format(uint16_t *f_ret)
|
||||
{
|
||||
uint16_t u = *f_ret;
|
||||
int i;
|
||||
uint8_t s[MAX_POLY];
|
||||
uint8_t sigma[MAX_POLY];
|
||||
|
||||
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
|
||||
* to get S_1 .. S_6 (but we index them from 0).
|
||||
*/
|
||||
if (!format_syndromes(u, s))
|
||||
return QUIRC_SUCCESS;
|
||||
|
||||
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
|
||||
|
||||
/* Now, find the roots of the polynomial */
|
||||
for (i = 0; i < 15; i++)
|
||||
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
|
||||
u ^= (1 << i);
|
||||
|
||||
if (format_syndromes(u, s))
|
||||
return QUIRC_ERROR_FORMAT_ECC;
|
||||
|
||||
*f_ret = u;
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Decoder algorithm
|
||||
*/
|
||||
|
||||
struct datastream {
|
||||
uint8_t raw[QUIRC_MAX_PAYLOAD];
|
||||
int data_bits;
|
||||
int ptr;
|
||||
|
||||
uint8_t data[QUIRC_MAX_PAYLOAD];
|
||||
};
|
||||
|
||||
static inline int grid_bit(const struct quirc_code *code, int x, int y)
|
||||
{
|
||||
int p = y * code->size + x;
|
||||
|
||||
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t read_format(const struct quirc_code *code,
|
||||
struct quirc_data *data, int which)
|
||||
{
|
||||
int i;
|
||||
uint16_t format = 0;
|
||||
uint16_t fdata;
|
||||
quirc_decode_error_t err;
|
||||
|
||||
if (which) {
|
||||
for (i = 0; i < 7; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, 8, code->size - 1 - i);
|
||||
for (i = 0; i < 8; i++)
|
||||
format = (format << 1) |
|
||||
grid_bit(code, code->size - 8 + i, 8);
|
||||
} else {
|
||||
static const int xs[15] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0
|
||||
};
|
||||
static const int ys[15] = {
|
||||
0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8
|
||||
};
|
||||
|
||||
for (i = 14; i >= 0; i--)
|
||||
format = (format << 1) | grid_bit(code, xs[i], ys[i]);
|
||||
}
|
||||
|
||||
format ^= 0x5412;
|
||||
|
||||
err = correct_format(&format);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
fdata = format >> 10;
|
||||
data->ecc_level = fdata >> 3;
|
||||
data->mask = fdata & 7;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int mask_bit(int mask, int i, int j)
|
||||
{
|
||||
switch (mask) {
|
||||
case 0: return !((i + j) % 2);
|
||||
case 1: return !(i % 2);
|
||||
case 2: return !(j % 3);
|
||||
case 3: return !((i + j) % 3);
|
||||
case 4: return !(((i / 2) + (j / 3)) % 2);
|
||||
case 5: return !((i * j) % 2 + (i * j) % 3);
|
||||
case 6: return !(((i * j) % 2 + (i * j) % 3) % 2);
|
||||
case 7: return !(((i * j) % 3 + (i + j) % 2) % 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reserved_cell(int version, int i, int j)
|
||||
{
|
||||
const struct quirc_version_info *ver = &quirc_version_db[version];
|
||||
int size = version * 4 + 17;
|
||||
int ai = -1, aj = -1, a;
|
||||
|
||||
/* Finder + format: top left */
|
||||
if (i < 9 && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: bottom left */
|
||||
if (i + 8 >= size && j < 9)
|
||||
return 1;
|
||||
|
||||
/* Finder + format: top right */
|
||||
if (i < 9 && j + 8 >= size)
|
||||
return 1;
|
||||
|
||||
/* Exclude timing patterns */
|
||||
if (i == 6 || j == 6)
|
||||
return 1;
|
||||
|
||||
/* Exclude version info, if it exists. Version info sits adjacent to
|
||||
* the top-right and bottom-left finders in three rows, bounded by
|
||||
* the timing pattern.
|
||||
*/
|
||||
if (version >= 7) {
|
||||
if (i < 6 && j + 11 >= size)
|
||||
return 1;
|
||||
if (i + 11 >= size && j < 6)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exclude alignment patterns */
|
||||
for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++) {
|
||||
int p = ver->apat[a];
|
||||
|
||||
if (abs(p - i) < 3)
|
||||
ai = a;
|
||||
if (abs(p - j) < 3)
|
||||
aj = a;
|
||||
}
|
||||
|
||||
if (ai >= 0 && aj >= 0) {
|
||||
a--;
|
||||
if (ai > 0 && ai < a)
|
||||
return 1;
|
||||
if (aj > 0 && aj < a)
|
||||
return 1;
|
||||
if (aj == a && ai == a)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_bit(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds, int i, int j)
|
||||
{
|
||||
int bitpos = ds->data_bits & 7;
|
||||
int bytepos = ds->data_bits >> 3;
|
||||
int v = grid_bit(code, j, i);
|
||||
|
||||
if (mask_bit(data->mask, i, j))
|
||||
v ^= 1;
|
||||
|
||||
if (v)
|
||||
ds->raw[bytepos] |= (0x80 >> bitpos);
|
||||
|
||||
ds->data_bits++;
|
||||
}
|
||||
|
||||
static void read_data(const struct quirc_code *code,
|
||||
struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int y = code->size - 1;
|
||||
int x = code->size - 1;
|
||||
int dir = -1;
|
||||
|
||||
while (x > 0) {
|
||||
if (x == 6)
|
||||
x--;
|
||||
|
||||
if (!reserved_cell(data->version, y, x))
|
||||
read_bit(code, data, ds, y, x);
|
||||
|
||||
if (!reserved_cell(data->version, y, x - 1))
|
||||
read_bit(code, data, ds, y, x - 1);
|
||||
|
||||
y += dir;
|
||||
if (y < 0 || y >= code->size) {
|
||||
dir = -dir;
|
||||
x -= 2;
|
||||
y += dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
const struct quirc_version_info *ver =
|
||||
&quirc_version_db[data->version];
|
||||
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
|
||||
struct quirc_rs_params lb_ecc;
|
||||
const int lb_count =
|
||||
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
|
||||
const int bc = lb_count + sb_ecc->ns;
|
||||
const int ecc_offset = sb_ecc->dw * bc + lb_count;
|
||||
int dst_offset = 0;
|
||||
int i;
|
||||
|
||||
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
|
||||
lb_ecc.dw++;
|
||||
lb_ecc.bs++;
|
||||
|
||||
for (i = 0; i < bc; i++) {
|
||||
uint8_t *dst = ds->data + dst_offset;
|
||||
const struct quirc_rs_params *ecc =
|
||||
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
|
||||
const int num_ec = ecc->bs - ecc->dw;
|
||||
quirc_decode_error_t err;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ecc->dw; j++)
|
||||
dst[j] = ds->raw[j * bc + i];
|
||||
for (j = 0; j < num_ec; j++)
|
||||
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
|
||||
|
||||
err = correct_block(dst, ecc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_offset += ecc->dw;
|
||||
}
|
||||
|
||||
ds->data_bits = dst_offset * 8;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int bits_remaining(const struct datastream *ds)
|
||||
{
|
||||
return ds->data_bits - ds->ptr;
|
||||
}
|
||||
|
||||
static int take_bits(struct datastream *ds, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (len && (ds->ptr < ds->data_bits)) {
|
||||
uint8_t b = ds->data[ds->ptr >> 3];
|
||||
int bitpos = ds->ptr & 7;
|
||||
|
||||
ret <<= 1;
|
||||
if ((b << bitpos) & 0x80)
|
||||
ret |= 1;
|
||||
|
||||
ds->ptr++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int numeric_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = digits - 1; i >= 0; i--) {
|
||||
data->payload[data->payload_len + i] = tuple % 10 + '0';
|
||||
tuple /= 10;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_numeric(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 14;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 10;
|
||||
else if (data->version < 27)
|
||||
bits = 12;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 3) {
|
||||
if (numeric_tuple(data, ds, 10, 3) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 3;
|
||||
}
|
||||
|
||||
if (count >= 2) {
|
||||
if (numeric_tuple(data, ds, 7, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count) {
|
||||
if (numeric_tuple(data, ds, 4, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static int alpha_tuple(struct quirc_data *data,
|
||||
struct datastream *ds,
|
||||
int bits, int digits)
|
||||
{
|
||||
int tuple;
|
||||
int i;
|
||||
|
||||
if (bits_remaining(ds) < bits)
|
||||
return -1;
|
||||
|
||||
tuple = take_bits(ds, bits);
|
||||
|
||||
for (i = 0; i < digits; i++) {
|
||||
static const char *alpha_map =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
||||
|
||||
data->payload[data->payload_len + digits - i - 1] =
|
||||
alpha_map[tuple % 45];
|
||||
tuple /= 45;
|
||||
}
|
||||
|
||||
data->payload_len += digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_alpha(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 13;
|
||||
int count;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 9;
|
||||
else if (data->version < 27)
|
||||
bits = 11;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
|
||||
while (count >= 2) {
|
||||
if (alpha_tuple(data, ds, 11, 2) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (count) {
|
||||
if (alpha_tuple(data, ds, 6, 1) < 0)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_byte(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 16;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
data->payload[data->payload_len++] = take_bits(ds, 8);
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
int bits = 12;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (data->version < 10)
|
||||
bits = 8;
|
||||
else if (data->version < 27)
|
||||
bits = 10;
|
||||
|
||||
count = take_bits(ds, bits);
|
||||
if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
|
||||
return QUIRC_ERROR_DATA_OVERFLOW;
|
||||
if (bits_remaining(ds) < count * 13)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int d = take_bits(ds, 13);
|
||||
int msB = d / 0xc0;
|
||||
int lsB = d % 0xc0;
|
||||
int intermediate = (msB << 8) | lsB;
|
||||
uint16_t sjw;
|
||||
|
||||
if (intermediate + 0x8140 <= 0x9ffc) {
|
||||
/* bytes are in the range 0x8140 to 0x9FFC */
|
||||
sjw = intermediate + 0x8140;
|
||||
} else {
|
||||
/* bytes are in the range 0xE040 to 0xEBBF */
|
||||
sjw = intermediate + 0xc140;
|
||||
}
|
||||
|
||||
data->payload[data->payload_len++] = sjw >> 8;
|
||||
data->payload[data->payload_len++] = sjw & 0xff;
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_eci(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = take_bits(ds, 8);
|
||||
|
||||
if ((data->eci & 0xc0) == 0x80) {
|
||||
if (bits_remaining(ds) < 8)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 8) | take_bits(ds, 8);
|
||||
} else if ((data->eci & 0xe0) == 0xc0) {
|
||||
if (bits_remaining(ds) < 16)
|
||||
return QUIRC_ERROR_DATA_UNDERFLOW;
|
||||
|
||||
data->eci = (data->eci << 16) | take_bits(ds, 16);
|
||||
}
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
struct datastream *ds)
|
||||
{
|
||||
while (bits_remaining(ds) >= 4) {
|
||||
quirc_decode_error_t err = QUIRC_SUCCESS;
|
||||
int type = take_bits(ds, 4);
|
||||
|
||||
switch (type) {
|
||||
case QUIRC_DATA_TYPE_NUMERIC:
|
||||
err = decode_numeric(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_ALPHA:
|
||||
err = decode_alpha(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_BYTE:
|
||||
err = decode_byte(data, ds);
|
||||
break;
|
||||
|
||||
case QUIRC_DATA_TYPE_KANJI:
|
||||
err = decode_kanji(data, ds);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
err = decode_eci(data, ds);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(type & (type - 1)) && (type > data->data_type))
|
||||
data->data_type = type;
|
||||
}
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if ((unsigned)data->payload_len >= sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
|
||||
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
||||
struct quirc_data *data)
|
||||
{
|
||||
quirc_decode_error_t err;
|
||||
struct datastream ds;
|
||||
|
||||
if ((code->size - 17) % 4)
|
||||
return QUIRC_ERROR_INVALID_GRID_SIZE;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
memset(&ds, 0, sizeof(ds));
|
||||
|
||||
data->version = (code->size - 17) / 4;
|
||||
|
||||
if (data->version < 1 ||
|
||||
data->version > QUIRC_MAX_VERSION)
|
||||
return QUIRC_ERROR_INVALID_VERSION;
|
||||
|
||||
/* Read format information -- try both locations */
|
||||
err = read_format(code, data, 0);
|
||||
if (err)
|
||||
err = read_format(code, data, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
read_data(code, data, &ds);
|
||||
err = codestream_ecc(data, &ds);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = decode_payload(data, &ds);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return QUIRC_SUCCESS;
|
||||
}
|
||||
Vendored
+138
@@ -0,0 +1,138 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <quirc_internal.h>
|
||||
|
||||
const char *quirc_version(void)
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = malloc(sizeof(*q));
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
void quirc_destroy(struct quirc *q)
|
||||
{
|
||||
free(q->image);
|
||||
/* q->pixels may alias q->image when their type representation is of the
|
||||
same size, so we need to be careful here to avoid a double free */
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
free(q->pixels);
|
||||
free(q->row_average);
|
||||
free(q);
|
||||
}
|
||||
|
||||
int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
uint8_t *image = NULL;
|
||||
quirc_pixel_t *pixels = NULL;
|
||||
int *row_average = NULL;
|
||||
|
||||
/*
|
||||
* XXX: w and h should be size_t (or at least unsigned) as negatives
|
||||
* values would not make much sense. The downside is that it would break
|
||||
* both the API and ABI. Thus, at the moment, let's just do a sanity
|
||||
* check.
|
||||
*/
|
||||
if (w < 0 || h < 0)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* alloc a new buffer for q->image. We avoid realloc(3) because we want
|
||||
* on failure to be leave `q` in a consistant, unmodified state.
|
||||
*/
|
||||
image = calloc(w, h);
|
||||
if (!image)
|
||||
goto fail;
|
||||
|
||||
/* compute the "old" (i.e. currently allocated) and the "new"
|
||||
(i.e. requested) image dimensions */
|
||||
size_t olddim = q->w * q->h;
|
||||
size_t newdim = w * h;
|
||||
size_t min = (olddim < newdim ? olddim : newdim);
|
||||
|
||||
/*
|
||||
* copy the data into the new buffer, avoiding (a) to read beyond the
|
||||
* old buffer when the new size is greater and (b) to write beyond the
|
||||
* new buffer when the new size is smaller, hence the min computation.
|
||||
*/
|
||||
(void)memcpy(image, q->image, min);
|
||||
|
||||
/* alloc a new buffer for q->pixels if needed */
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels)) {
|
||||
pixels = calloc(newdim, sizeof(quirc_pixel_t));
|
||||
if (!pixels)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* alloc a new buffer for q->row_average */
|
||||
row_average = calloc(w, sizeof(int));
|
||||
if (!row_average)
|
||||
goto fail;
|
||||
|
||||
/* alloc succeeded, update `q` with the new size and buffers */
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
free(q->image);
|
||||
q->image = image;
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels)) {
|
||||
free(q->pixels);
|
||||
q->pixels = pixels;
|
||||
}
|
||||
free(q->row_average);
|
||||
q->row_average = row_average;
|
||||
|
||||
return 0;
|
||||
/* NOTREACHED */
|
||||
fail:
|
||||
free(image);
|
||||
free(pixels);
|
||||
free(row_average);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int quirc_count(const struct quirc *q)
|
||||
{
|
||||
return q->num_grids;
|
||||
}
|
||||
|
||||
static const char *const error_table[] = {
|
||||
[QUIRC_SUCCESS] = "Success",
|
||||
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
|
||||
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
|
||||
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
|
||||
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
|
||||
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
|
||||
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
|
||||
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"
|
||||
};
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if ((int)err < 8) { return error_table[err]; }
|
||||
else { return "Unknown error"; }
|
||||
}
|
||||
Vendored
+430
@@ -0,0 +1,430 @@
|
||||
/* quirc -- QR-code recognition library
|
||||
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <quirc_internal.h>
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{ /* 0 */
|
||||
.data_bytes = 0,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 0, .dw = 0, .ns = 0},
|
||||
{.bs = 0, .dw = 0, .ns = 0},
|
||||
{.bs = 0, .dw = 0, .ns = 0},
|
||||
{.bs = 0, .dw = 0, .ns = 0}
|
||||
}
|
||||
},
|
||||
{ /* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 26, .dw = 16, .ns = 1},
|
||||
{.bs = 26, .dw = 19, .ns = 1},
|
||||
{.bs = 26, .dw = 9, .ns = 1},
|
||||
{.bs = 26, .dw = 13, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 2 */
|
||||
.data_bytes = 44,
|
||||
.apat = {6, 18, 0},
|
||||
.ecc = {
|
||||
{.bs = 44, .dw = 28, .ns = 1},
|
||||
{.bs = 44, .dw = 34, .ns = 1},
|
||||
{.bs = 44, .dw = 16, .ns = 1},
|
||||
{.bs = 44, .dw = 22, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 3 */
|
||||
.data_bytes = 70,
|
||||
.apat = {6, 22, 0},
|
||||
.ecc = {
|
||||
{.bs = 70, .dw = 44, .ns = 1},
|
||||
{.bs = 70, .dw = 55, .ns = 1},
|
||||
{.bs = 35, .dw = 13, .ns = 2},
|
||||
{.bs = 35, .dw = 17, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 4 */
|
||||
.data_bytes = 100,
|
||||
.apat = {6, 26, 0},
|
||||
.ecc = {
|
||||
{.bs = 50, .dw = 32, .ns = 2},
|
||||
{.bs = 100, .dw = 80, .ns = 1},
|
||||
{.bs = 25, .dw = 9, .ns = 4},
|
||||
{.bs = 50, .dw = 24, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 5 */
|
||||
.data_bytes = 134,
|
||||
.apat = {6, 30, 0},
|
||||
.ecc = {
|
||||
{.bs = 67, .dw = 43, .ns = 2},
|
||||
{.bs = 134, .dw = 108, .ns = 1},
|
||||
{.bs = 33, .dw = 11, .ns = 2},
|
||||
{.bs = 33, .dw = 15, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 6 */
|
||||
.data_bytes = 172,
|
||||
.apat = {6, 34, 0},
|
||||
.ecc = {
|
||||
{.bs = 43, .dw = 27, .ns = 4},
|
||||
{.bs = 86, .dw = 68, .ns = 2},
|
||||
{.bs = 43, .dw = 15, .ns = 4},
|
||||
{.bs = 43, .dw = 19, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 7 */
|
||||
.data_bytes = 196,
|
||||
.apat = {6, 22, 38, 0},
|
||||
.ecc = {
|
||||
{.bs = 49, .dw = 31, .ns = 4},
|
||||
{.bs = 98, .dw = 78, .ns = 2},
|
||||
{.bs = 39, .dw = 13, .ns = 4},
|
||||
{.bs = 32, .dw = 14, .ns = 2}
|
||||
}
|
||||
},
|
||||
{ /* Version 8 */
|
||||
.data_bytes = 242,
|
||||
.apat = {6, 24, 42, 0},
|
||||
.ecc = {
|
||||
{.bs = 60, .dw = 38, .ns = 2},
|
||||
{.bs = 121, .dw = 97, .ns = 2},
|
||||
{.bs = 40, .dw = 14, .ns = 4},
|
||||
{.bs = 40, .dw = 18, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 9 */
|
||||
.data_bytes = 292,
|
||||
.apat = {6, 26, 46, 0},
|
||||
.ecc = {
|
||||
{.bs = 58, .dw = 36, .ns = 3},
|
||||
{.bs = 146, .dw = 116, .ns = 2},
|
||||
{.bs = 36, .dw = 12, .ns = 4},
|
||||
{.bs = 36, .dw = 16, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 10 */
|
||||
.data_bytes = 346,
|
||||
.apat = {6, 28, 50, 0},
|
||||
.ecc = {
|
||||
{.bs = 69, .dw = 43, .ns = 4},
|
||||
{.bs = 86, .dw = 68, .ns = 2},
|
||||
{.bs = 43, .dw = 15, .ns = 6},
|
||||
{.bs = 43, .dw = 19, .ns = 6}
|
||||
}
|
||||
},
|
||||
{ /* Version 11 */
|
||||
.data_bytes = 404,
|
||||
.apat = {6, 30, 54, 0},
|
||||
.ecc = {
|
||||
{.bs = 80, .dw = 50, .ns = 1},
|
||||
{.bs = 101, .dw = 81, .ns = 4},
|
||||
{.bs = 36, .dw = 12, .ns = 3},
|
||||
{.bs = 50, .dw = 22, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 12 */
|
||||
.data_bytes = 466,
|
||||
.apat = {6, 32, 58, 0},
|
||||
.ecc = {
|
||||
{.bs = 58, .dw = 36, .ns = 6},
|
||||
{.bs = 116, .dw = 92, .ns = 2},
|
||||
{.bs = 42, .dw = 14, .ns = 7},
|
||||
{.bs = 46, .dw = 20, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 13 */
|
||||
.data_bytes = 532,
|
||||
.apat = {6, 34, 62, 0},
|
||||
.ecc = {
|
||||
{.bs = 59, .dw = 37, .ns = 8},
|
||||
{.bs = 133, .dw = 107, .ns = 4},
|
||||
{.bs = 33, .dw = 11, .ns = 12},
|
||||
{.bs = 44, .dw = 20, .ns = 8}
|
||||
}
|
||||
},
|
||||
{ /* Version 14 */
|
||||
.data_bytes = 581,
|
||||
.apat = {6, 26, 46, 66, 0},
|
||||
.ecc = {
|
||||
{.bs = 64, .dw = 40, .ns = 4},
|
||||
{.bs = 145, .dw = 115, .ns = 3},
|
||||
{.bs = 36, .dw = 12, .ns = 11},
|
||||
{.bs = 36, .dw = 16, .ns = 11}
|
||||
}
|
||||
},
|
||||
{ /* Version 15 */
|
||||
.data_bytes = 655,
|
||||
.apat = {6, 26, 48, 70, 0},
|
||||
.ecc = {
|
||||
{.bs = 65, .dw = 41, .ns = 5},
|
||||
{.bs = 109, .dw = 87, .ns = 5},
|
||||
{.bs = 36, .dw = 12, .ns = 11},
|
||||
{.bs = 54, .dw = 24, .ns = 5}
|
||||
}
|
||||
},
|
||||
{ /* Version 16 */
|
||||
.data_bytes = 733,
|
||||
.apat = {6, 26, 50, 74, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ns = 7},
|
||||
{.bs = 122, .dw = 98, .ns = 5},
|
||||
{.bs = 45, .dw = 15, .ns = 3},
|
||||
{.bs = 43, .dw = 19, .ns = 15}
|
||||
}
|
||||
},
|
||||
{ /* Version 17 */
|
||||
.data_bytes = 815,
|
||||
.apat = {6, 30, 54, 78, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 10},
|
||||
{.bs = 135, .dw = 107, .ns = 1},
|
||||
{.bs = 42, .dw = 14, .ns = 2},
|
||||
{.bs = 50, .dw = 22, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 18 */
|
||||
.data_bytes = 901,
|
||||
.apat = {6, 30, 56, 82, 0},
|
||||
.ecc = {
|
||||
{.bs = 69, .dw = 43, .ns = 9},
|
||||
{.bs = 150, .dw = 120, .ns = 5},
|
||||
{.bs = 42, .dw = 14, .ns = 2},
|
||||
{.bs = 50, .dw = 22, .ns = 17}
|
||||
}
|
||||
},
|
||||
{ /* Version 19 */
|
||||
.data_bytes = 991,
|
||||
.apat = {6, 30, 58, 86, 0},
|
||||
.ecc = {
|
||||
{.bs = 70, .dw = 44, .ns = 3},
|
||||
{.bs = 141, .dw = 113, .ns = 3},
|
||||
{.bs = 39, .dw = 13, .ns = 9},
|
||||
{.bs = 47, .dw = 21, .ns = 17}
|
||||
}
|
||||
},
|
||||
{ /* Version 20 */
|
||||
.data_bytes = 1085,
|
||||
.apat = {6, 34, 62, 90, 0},
|
||||
.ecc = {
|
||||
{.bs = 67, .dw = 41, .ns = 3},
|
||||
{.bs = 135, .dw = 107, .ns = 3},
|
||||
{.bs = 43, .dw = 15, .ns = 15},
|
||||
{.bs = 54, .dw = 24, .ns = 15}
|
||||
}
|
||||
},
|
||||
{ /* Version 21 */
|
||||
.data_bytes = 1156,
|
||||
.apat = {6, 28, 50, 72, 92, 0},
|
||||
.ecc = {
|
||||
{.bs = 68, .dw = 42, .ns = 17},
|
||||
{.bs = 144, .dw = 116, .ns = 4},
|
||||
{.bs = 46, .dw = 16, .ns = 19},
|
||||
{.bs = 50, .dw = 22, .ns = 17}
|
||||
}
|
||||
},
|
||||
{ /* Version 22 */
|
||||
.data_bytes = 1258,
|
||||
.apat = {6, 26, 50, 74, 98, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 17},
|
||||
{.bs = 139, .dw = 111, .ns = 2},
|
||||
{.bs = 37, .dw = 13, .ns = 34},
|
||||
{.bs = 54, .dw = 24, .ns = 7}
|
||||
}
|
||||
},
|
||||
{ /* Version 23 */
|
||||
.data_bytes = 1364,
|
||||
.apat = {6, 30, 54, 78, 102, 0},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 4},
|
||||
{.bs = 151, .dw = 121, .ns = 4},
|
||||
{.bs = 45, .dw = 15, .ns = 16},
|
||||
{.bs = 54, .dw = 24, .ns = 11}
|
||||
}
|
||||
},
|
||||
{ /* Version 24 */
|
||||
.data_bytes = 1474,
|
||||
.apat = {6, 28, 54, 80, 106, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ns = 6},
|
||||
{.bs = 147, .dw = 117, .ns = 6},
|
||||
{.bs = 46, .dw = 16, .ns = 30},
|
||||
{.bs = 54, .dw = 24, .ns = 11}
|
||||
}
|
||||
},
|
||||
{ /* Version 25 */
|
||||
.data_bytes = 1588,
|
||||
.apat = {6, 32, 58, 84, 110, 0},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 8},
|
||||
{.bs = 132, .dw = 106, .ns = 8},
|
||||
{.bs = 45, .dw = 15, .ns = 22},
|
||||
{.bs = 54, .dw = 24, .ns = 7}
|
||||
}
|
||||
},
|
||||
{ /* Version 26 */
|
||||
.data_bytes = 1706,
|
||||
.apat = {6, 30, 58, 86, 114, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 19},
|
||||
{.bs = 142, .dw = 114, .ns = 10},
|
||||
{.bs = 46, .dw = 16, .ns = 33},
|
||||
{.bs = 50, .dw = 22, .ns = 28}
|
||||
}
|
||||
},
|
||||
{ /* Version 27 */
|
||||
.data_bytes = 1828,
|
||||
.apat = {6, 34, 62, 90, 118, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ns = 22},
|
||||
{.bs = 152, .dw = 122, .ns = 8},
|
||||
{.bs = 45, .dw = 15, .ns = 12},
|
||||
{.bs = 53, .dw = 23, .ns = 8}
|
||||
}
|
||||
},
|
||||
{ /* Version 28 */
|
||||
.data_bytes = 1921,
|
||||
.apat = {6, 26, 50, 74, 98, 122, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ns = 3},
|
||||
{.bs = 147, .dw = 117, .ns = 3},
|
||||
{.bs = 45, .dw = 15, .ns = 11},
|
||||
{.bs = 54, .dw = 24, .ns = 4}
|
||||
}
|
||||
},
|
||||
{ /* Version 29 */
|
||||
.data_bytes = 2051,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 0},
|
||||
.ecc = {
|
||||
{.bs = 73, .dw = 45, .ns = 21},
|
||||
{.bs = 146, .dw = 116, .ns = 7},
|
||||
{.bs = 45, .dw = 15, .ns = 19},
|
||||
{.bs = 53, .dw = 23, .ns = 1}
|
||||
}
|
||||
},
|
||||
{ /* Version 30 */
|
||||
.data_bytes = 2185,
|
||||
.apat = {6, 26, 52, 78, 104, 130, 0},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 19},
|
||||
{.bs = 145, .dw = 115, .ns = 5},
|
||||
{.bs = 45, .dw = 15, .ns = 23},
|
||||
{.bs = 54, .dw = 24, .ns = 15}
|
||||
}
|
||||
},
|
||||
{ /* Version 31 */
|
||||
.data_bytes = 2323,
|
||||
.apat = {6, 30, 56, 82, 108, 134, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 2},
|
||||
{.bs = 145, .dw = 115, .ns = 13},
|
||||
{.bs = 45, .dw = 15, .ns = 23},
|
||||
{.bs = 54, .dw = 24, .ns = 42}
|
||||
}
|
||||
},
|
||||
{ /* Version 32 */
|
||||
.data_bytes = 2465,
|
||||
.apat = {6, 34, 60, 86, 112, 138, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 10},
|
||||
{.bs = 145, .dw = 115, .ns = 17},
|
||||
{.bs = 45, .dw = 15, .ns = 19},
|
||||
{.bs = 54, .dw = 24, .ns = 10}
|
||||
}
|
||||
},
|
||||
{ /* Version 33 */
|
||||
.data_bytes = 2611,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 14},
|
||||
{.bs = 145, .dw = 115, .ns = 17},
|
||||
{.bs = 45, .dw = 15, .ns = 11},
|
||||
{.bs = 54, .dw = 24, .ns = 29}
|
||||
}
|
||||
},
|
||||
{ /* Version 34 */
|
||||
.data_bytes = 2761,
|
||||
.apat = {6, 34, 62, 90, 118, 146, 0},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 14},
|
||||
{.bs = 145, .dw = 115, .ns = 13},
|
||||
{.bs = 46, .dw = 16, .ns = 59},
|
||||
{.bs = 54, .dw = 24, .ns = 44}
|
||||
}
|
||||
},
|
||||
{ /* Version 35 */
|
||||
.data_bytes = 2876,
|
||||
.apat = {6, 30, 54, 78, 102, 126, 150},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 12},
|
||||
{.bs = 151, .dw = 121, .ns = 12},
|
||||
{.bs = 45, .dw = 15, .ns = 22},
|
||||
{.bs = 54, .dw = 24, .ns = 39}
|
||||
}
|
||||
},
|
||||
{ /* Version 36 */
|
||||
.data_bytes = 3034,
|
||||
.apat = {6, 24, 50, 76, 102, 128, 154},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 6},
|
||||
{.bs = 151, .dw = 121, .ns = 6},
|
||||
{.bs = 45, .dw = 15, .ns = 2},
|
||||
{.bs = 54, .dw = 24, .ns = 46}
|
||||
}
|
||||
},
|
||||
{ /* Version 37 */
|
||||
.data_bytes = 3196,
|
||||
.apat = {6, 28, 54, 80, 106, 132, 158},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 29},
|
||||
{.bs = 152, .dw = 122, .ns = 17},
|
||||
{.bs = 45, .dw = 15, .ns = 24},
|
||||
{.bs = 54, .dw = 24, .ns = 49}
|
||||
}
|
||||
},
|
||||
{ /* Version 38 */
|
||||
.data_bytes = 3362,
|
||||
.apat = {6, 32, 58, 84, 110, 136, 162},
|
||||
.ecc = {
|
||||
{.bs = 74, .dw = 46, .ns = 13},
|
||||
{.bs = 152, .dw = 122, .ns = 4},
|
||||
{.bs = 45, .dw = 15, .ns = 42},
|
||||
{.bs = 54, .dw = 24, .ns = 48}
|
||||
}
|
||||
},
|
||||
{ /* Version 39 */
|
||||
.data_bytes = 3532,
|
||||
.apat = {6, 26, 54, 82, 110, 138, 166},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 40},
|
||||
{.bs = 147, .dw = 117, .ns = 20},
|
||||
{.bs = 45, .dw = 15, .ns = 10},
|
||||
{.bs = 54, .dw = 24, .ns = 43}
|
||||
}
|
||||
},
|
||||
{ /* Version 40 */
|
||||
.data_bytes = 3706,
|
||||
.apat = {6, 30, 58, 86, 114, 142, 170},
|
||||
.ecc = {
|
||||
{.bs = 75, .dw = 47, .ns = 18},
|
||||
{.bs = 148, .dw = 118, .ns = 19},
|
||||
{.bs = 45, .dw = 15, .ns = 20},
|
||||
{.bs = 54, .dw = 24, .ns = 34}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -283,6 +283,7 @@ OCV_OPTION(WITH_IMGCODEC_HDR "Include HDR support" ON)
|
||||
OCV_OPTION(WITH_IMGCODEC_SUNRASTER "Include SUNRASTER support" ON)
|
||||
OCV_OPTION(WITH_IMGCODEC_PXM "Include PNM (PBM,PGM,PPM) and PAM formats support" ON)
|
||||
OCV_OPTION(WITH_IMGCODEC_PFM "Include PFM formats support" ON)
|
||||
OCV_OPTION(WITH_QUIRC "Include library QR-code decoding" ON)
|
||||
|
||||
# OpenCV build components
|
||||
# ===================================================
|
||||
@@ -696,6 +697,10 @@ if(WITH_OPENVX)
|
||||
include(cmake/FindOpenVX.cmake)
|
||||
endif()
|
||||
|
||||
if(WITH_QUIRC)
|
||||
add_subdirectory(3rdparty/quirc)
|
||||
set(HAVE_QUIRC TRUE)
|
||||
endif()
|
||||
# ----------------------------------------------------------------------------
|
||||
# OpenCV HAL
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
@@ -210,7 +210,7 @@ void calib::calibDataController::filterFrames()
|
||||
worstElemIndex = i;
|
||||
}
|
||||
}
|
||||
showOverlayMessage(cv::format("Frame %d is worst", worstElemIndex + 1));
|
||||
showOverlayMessage(cv::format("Frame %zu is worst", worstElemIndex + 1));
|
||||
|
||||
if(mCalibData->imagePoints.size()) {
|
||||
mCalibData->imagePoints.erase(mCalibData->imagePoints.begin() + worstElemIndex);
|
||||
|
||||
@@ -318,7 +318,7 @@ cv::Mat CalibProcessor::processFrame(const cv::Mat &frame)
|
||||
saveFrameData();
|
||||
bool isFrameBad = checkLastFrame();
|
||||
if (!isFrameBad) {
|
||||
std::string displayMessage = cv::format("Frame # %d captured", std::max(mCalibData->imagePoints.size(),
|
||||
std::string displayMessage = cv::format("Frame # %zu captured", std::max(mCalibData->imagePoints.size(),
|
||||
mCalibData->allCharucoCorners.size()));
|
||||
if(!showOverlayMessage(displayMessage))
|
||||
showCaptureMessage(frame, displayMessage);
|
||||
|
||||
@@ -86,7 +86,11 @@ endif()
|
||||
if(CV_GCC OR CV_CLANG)
|
||||
# High level of warnings.
|
||||
add_extra_compiler_option(-W)
|
||||
add_extra_compiler_option(-Wall)
|
||||
if (NOT MSVC)
|
||||
# clang-cl interprets -Wall as MSVC would: -Weverything, which is more than
|
||||
# we want.
|
||||
add_extra_compiler_option(-Wall)
|
||||
endif()
|
||||
add_extra_compiler_option(-Werror=return-type)
|
||||
add_extra_compiler_option(-Werror=non-virtual-dtor)
|
||||
add_extra_compiler_option(-Werror=address)
|
||||
@@ -173,7 +177,7 @@ if(CV_GCC OR CV_CLANG)
|
||||
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
|
||||
string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
elseif(NOT ((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS))
|
||||
elseif(NOT ((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS) AND NOT MSVC)
|
||||
# Remove unreferenced functions: function level linking
|
||||
add_extra_compiler_option(-ffunction-sections)
|
||||
add_extra_compiler_option(-fdata-sections)
|
||||
@@ -266,6 +270,7 @@ endif()
|
||||
|
||||
# set default visibility to hidden
|
||||
if((CV_GCC OR CV_CLANG)
|
||||
AND NOT MSVC
|
||||
AND NOT OPENCV_SKIP_VISIBILITY_HIDDEN
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " -fvisibility")
|
||||
add_extra_compiler_option(-fvisibility=hidden)
|
||||
|
||||
@@ -38,7 +38,7 @@ if(NOT ${found})
|
||||
set(PYTHON_EXECUTABLE "${${executable}}")
|
||||
endif()
|
||||
|
||||
if(WIN32 AND NOT ${executable})
|
||||
if(WIN32 AND NOT ${executable} AND OPENCV_PYTHON_PREFER_WIN32_REGISTRY) # deprecated
|
||||
# search for executable with the same bitness as resulting binaries
|
||||
# standard FindPythonInterp always prefers executable from system path
|
||||
# this is really important because we are using the interpreter for numpy search and for choosing the install location
|
||||
@@ -53,16 +53,53 @@ if(NOT ${found})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "^[0-9]+" _preferred_version_major "${preferred_version}")
|
||||
|
||||
find_host_package(PythonInterp "${preferred_version}")
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
if(preferred_version)
|
||||
set(__python_package_version "${preferred_version} EXACT")
|
||||
find_host_package(PythonInterp "${preferred_version}" EXACT)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
message(STATUS "Python is not found: ${preferred_version} EXACT")
|
||||
endif()
|
||||
elseif(min_version)
|
||||
set(__python_package_version "${min_version}")
|
||||
find_host_package(PythonInterp "${min_version}")
|
||||
else()
|
||||
set(__python_package_version "")
|
||||
find_host_package(PythonInterp)
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "^[0-9]+" _python_version_major "${min_version}")
|
||||
|
||||
if(PYTHONINTERP_FOUND)
|
||||
# Check if python major version is correct
|
||||
if("${_preferred_version_major}" STREQUAL "" OR "${_preferred_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}")
|
||||
if(" ${_python_version_major}" STREQUAL " ")
|
||||
set(_python_version_major "${PYTHON_VERSION_MAJOR}")
|
||||
endif()
|
||||
if(NOT "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}"
|
||||
AND NOT DEFINED ${executable}
|
||||
)
|
||||
if(NOT OPENCV_SKIP_PYTHON_WARNING)
|
||||
message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' founds wrong Python version:\n"
|
||||
"PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n"
|
||||
"PYTHON_VERSION_STRING=${PYTHON_VERSION_STRING}\n"
|
||||
"Consider specify '${executable}' variable via CMake command line or environment variables\n")
|
||||
endif()
|
||||
ocv_clear_vars(PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHON_VERSION_PATCH)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.12")
|
||||
if(_python_version_major STREQUAL "2")
|
||||
set(__PYTHON_PREFIX Python2)
|
||||
else()
|
||||
set(__PYTHON_PREFIX Python3)
|
||||
endif()
|
||||
find_host_package(${__PYTHON_PREFIX} "${preferred_version}" COMPONENTS Interpreter)
|
||||
if(${__PYTHON_PREFIX}_EXECUTABLE)
|
||||
set(PYTHON_EXECUTABLE "${${__PYTHON_PREFIX}_EXECUTABLE}")
|
||||
find_host_package(PythonInterp "${preferred_version}") # Populate other variables
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Consider using CMake 3.12+ for better Python support")
|
||||
endif()
|
||||
endif()
|
||||
if(PYTHONINTERP_FOUND AND "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}")
|
||||
# Copy outputs
|
||||
set(_found ${PYTHONINTERP_FOUND})
|
||||
set(_executable ${PYTHON_EXECUTABLE})
|
||||
@@ -235,7 +272,7 @@ if(OPENCV_PYTHON_SKIP_DETECTION)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
|
||||
find_python("" "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
|
||||
PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING
|
||||
PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND
|
||||
PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY
|
||||
@@ -243,7 +280,8 @@ find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
|
||||
PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH
|
||||
PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION)
|
||||
|
||||
find_python(3.4 "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
|
||||
option(OPENCV_PYTHON3_VERSION "Python3 version" "")
|
||||
find_python("${OPENCV_PYTHON3_VERSION}" "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
|
||||
PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING
|
||||
PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND
|
||||
PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY
|
||||
|
||||
@@ -44,8 +44,10 @@ else()
|
||||
|
||||
if(Protobuf_FOUND)
|
||||
if(TARGET protobuf::libprotobuf)
|
||||
add_library(libprotobuf INTERFACE)
|
||||
target_link_libraries(libprotobuf INTERFACE protobuf::libprotobuf)
|
||||
add_library(libprotobuf INTERFACE IMPORTED)
|
||||
set_target_properties(libprotobuf PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES protobuf::libprotobuf
|
||||
)
|
||||
else()
|
||||
add_library(libprotobuf UNKNOWN IMPORTED)
|
||||
set_target_properties(libprotobuf PROPERTIES
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(MIN_VER_CMAKE 3.5.1)
|
||||
set(MIN_VER_CUDA 6.5)
|
||||
set(MIN_VER_PYTHON2 2.6)
|
||||
set(MIN_VER_PYTHON2 2.7)
|
||||
set(MIN_VER_PYTHON3 3.2)
|
||||
set(MIN_VER_ZLIB 1.2.3)
|
||||
set(MIN_VER_GTK 2.18.0)
|
||||
|
||||
@@ -909,6 +909,13 @@ macro(_ocv_create_module)
|
||||
source_group("Src" FILES "${_VS_VERSION_FILE}")
|
||||
endif()
|
||||
endif()
|
||||
if(WIN32 AND NOT ("${the_module}" STREQUAL "opencv_core" OR "${the_module}" STREQUAL "opencv_world")
|
||||
AND (BUILD_SHARED_LIBS AND NOT "x${OPENCV_MODULE_TYPE}" STREQUAL "xSTATIC")
|
||||
AND NOT OPENCV_SKIP_DLLMAIN_GENERATION
|
||||
)
|
||||
set(_DLLMAIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/${the_module}_main.cpp")
|
||||
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/dllmain.cpp.in" "${_DLLMAIN_FILE}" @ONLY)
|
||||
endif()
|
||||
|
||||
source_group("Include" FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp")
|
||||
source_group("Src" FILES "${${the_module}_pch}")
|
||||
@@ -918,6 +925,7 @@ macro(_ocv_create_module)
|
||||
"${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp"
|
||||
${${the_module}_pch}
|
||||
${_VS_VERSION_FILE}
|
||||
${_DLLMAIN_FILE}
|
||||
)
|
||||
set_target_properties(${the_module} PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL};Module")
|
||||
set_source_files_properties(${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} ${${the_module}_pch}
|
||||
|
||||
+28
-6
@@ -999,6 +999,15 @@ function(ocv_convert_to_lib_name var)
|
||||
set(${var} ${tmp} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(MSVC AND BUILD_SHARED_LIBS) # no defaults for static libs (modern CMake is required)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
|
||||
option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default" ON)
|
||||
option(INSTALL_PDB "Add install PDB rules" ON)
|
||||
elseif(NOT CMAKE_VERSION VERSION_LESS 3.1.0)
|
||||
option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default (not supported)" OFF)
|
||||
option(INSTALL_PDB "Add install PDB rules" OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# add install command
|
||||
function(ocv_install_target)
|
||||
@@ -1030,9 +1039,10 @@ function(ocv_install_target)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(INSTALL_PDB AND (NOT INSTALL_IGNORE_PDB))
|
||||
set(__target "${ARGV0}")
|
||||
|
||||
set(__target "${ARGV0}")
|
||||
if(INSTALL_PDB AND NOT INSTALL_IGNORE_PDB
|
||||
AND NOT OPENCV_${__target}_PDB_SKIP
|
||||
)
|
||||
set(__location_key "ARCHIVE") # static libs
|
||||
get_target_property(__target_type ${__target} TYPE)
|
||||
if("${__target_type}" STREQUAL "SHARED_LIBRARY")
|
||||
@@ -1064,16 +1074,28 @@ function(ocv_install_target)
|
||||
if(DEFINED INSTALL_PDB_COMPONENT AND INSTALL_PDB_COMPONENT)
|
||||
set(__pdb_install_component "${INSTALL_PDB_COMPONENT}")
|
||||
endif()
|
||||
set(__pdb_exclude_from_all "")
|
||||
if(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
|
||||
set(__pdb_exclude_from_all EXCLUDE_FROM_ALL)
|
||||
else()
|
||||
message(WARNING "INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL requires CMake 3.6+")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# message(STATUS "Adding PDB file installation rule: target=${__target} dst=${__dst} component=${__pdb_install_component}")
|
||||
if("${__target_type}" STREQUAL "SHARED_LIBRARY")
|
||||
install(FILES "$<TARGET_PDB_FILE:${__target}>" DESTINATION "${__dst}" COMPONENT ${__pdb_install_component} OPTIONAL)
|
||||
install(FILES "$<TARGET_PDB_FILE:${__target}>" DESTINATION "${__dst}"
|
||||
COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
|
||||
else()
|
||||
# There is no generator expression similar to TARGET_PDB_FILE and TARGET_PDB_FILE can't be used: https://gitlab.kitware.com/cmake/cmake/issues/16932
|
||||
# However we still want .pdb files like: 'lib/Debug/opencv_core341d.pdb' or '3rdparty/lib/zlibd.pdb'
|
||||
install(FILES "$<TARGET_PROPERTY:${__target},ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<IF:$<BOOL:$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_DEBUG>>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_DEBUG>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME>>.pdb"
|
||||
DESTINATION "${__dst}" CONFIGURATIONS Debug COMPONENT ${__pdb_install_component} OPTIONAL)
|
||||
DESTINATION "${__dst}" CONFIGURATIONS Debug
|
||||
COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
|
||||
install(FILES "$<TARGET_PROPERTY:${__target},ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<IF:$<BOOL:$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_RELEASE>>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_RELEASE>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME>>.pdb"
|
||||
DESTINATION "${__dst}" CONFIGURATIONS Release COMPONENT ${__pdb_install_component} OPTIONAL)
|
||||
DESTINATION "${__dst}" CONFIGURATIONS Release
|
||||
COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "PDB files installation is not supported (need CMake >= 3.1.0)")
|
||||
|
||||
@@ -244,5 +244,7 @@
|
||||
/* OpenCV trace utilities */
|
||||
#cmakedefine OPENCV_TRACE
|
||||
|
||||
/* Library QR-code decoding */
|
||||
#cmakedefine HAVE_QUIRC
|
||||
|
||||
#endif // OPENCV_CVCONFIG_H_INCLUDED
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef _WIN32
|
||||
#error "Build configuration error"
|
||||
#endif
|
||||
#ifndef CVAPI_EXPORTS
|
||||
#error "Build configuration error"
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#define OPENCV_MODULE_S "@the_module@"
|
||||
|
||||
namespace cv {
|
||||
extern __declspec(dllimport) bool __termination; // Details: #12750
|
||||
}
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
|
||||
{
|
||||
if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
if (lpReserved != NULL) // called after ExitProcess() call
|
||||
{
|
||||
//printf("OpenCV: terminating: " OPENCV_MODULE_S "\n");
|
||||
cv::__termination = true;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -14,12 +14,19 @@ if(DOXYGEN_FOUND)
|
||||
add_custom_target(doxygen)
|
||||
|
||||
# not documented modules list
|
||||
set(blacklist "${DOXYGEN_BLACKLIST}")
|
||||
list(APPEND blacklist "ts" "java_bindings_generator" "java" "python_bindings_generator" "python2" "python3" "js" "world")
|
||||
unset(CMAKE_DOXYGEN_TUTORIAL_CONTRIB_ROOT)
|
||||
unset(CMAKE_DOXYGEN_TUTORIAL_JS_ROOT)
|
||||
|
||||
set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation")
|
||||
|
||||
set(OPENCV_DOCS_EXCLUDE_CUDA ON)
|
||||
if(";${OPENCV_MODULES_EXTRA};" MATCHES ";cudev;")
|
||||
set(OPENCV_DOCS_EXCLUDE_CUDA OFF)
|
||||
list(APPEND CMAKE_DOXYGEN_ENABLED_SECTIONS "CUDA_MODULES")
|
||||
endif()
|
||||
|
||||
# gathering headers
|
||||
set(paths_include)
|
||||
set(paths_doc)
|
||||
@@ -38,6 +45,15 @@ if(DOXYGEN_FOUND)
|
||||
if(EXISTS "${header_dir}")
|
||||
list(APPEND paths_include "${header_dir}")
|
||||
list(APPEND deps ${header_dir})
|
||||
if(OPENCV_DOCS_EXCLUDE_CUDA)
|
||||
if(EXISTS "${OPENCV_MODULE_opencv_${m}_LOCATION}/include/opencv2/${m}/cuda")
|
||||
list(APPEND CMAKE_DOXYGEN_EXCLUDE_LIST "${OPENCV_MODULE_opencv_${m}_LOCATION}/include/opencv2/${m}/cuda")
|
||||
endif()
|
||||
file(GLOB list_cuda_files "${OPENCV_MODULE_opencv_${m}_LOCATION}/include/opencv2/${m}/*cuda*.hpp")
|
||||
if(list_cuda_files)
|
||||
list(APPEND CMAKE_DOXYGEN_EXCLUDE_LIST ${list_cuda_files})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
# doc folder
|
||||
set(docs_dir "${OPENCV_MODULE_opencv_${m}_LOCATION}/doc")
|
||||
@@ -124,6 +140,8 @@ if(DOXYGEN_FOUND)
|
||||
# set export variables
|
||||
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_INPUT_LIST "${rootfile} ; ${faqfile} ; ${paths_include} ; ${paths_hal_interface} ; ${paths_doc} ; ${tutorial_path} ; ${tutorial_py_path} ; ${tutorial_js_path} ; ${paths_tutorial} ; ${tutorial_contrib_root}")
|
||||
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_IMAGE_PATH "${paths_doc} ; ${tutorial_path} ; ${tutorial_py_path} ; ${tutorial_js_path} ; ${paths_tutorial}")
|
||||
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXCLUDE_LIST "${CMAKE_DOXYGEN_EXCLUDE_LIST}")
|
||||
string(REPLACE ";" " " CMAKE_DOXYGEN_ENABLED_SECTIONS "${CMAKE_DOXYGEN_ENABLED_SECTIONS}")
|
||||
# TODO: remove paths_doc from EXAMPLE_PATH after face module tutorials/samples moved to separate folders
|
||||
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXAMPLE_PATH "${example_path} ; ${paths_doc} ; ${paths_sample}")
|
||||
set(CMAKE_DOXYGEN_LAYOUT "${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml")
|
||||
|
||||
+2
-2
@@ -85,7 +85,7 @@ GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
ENABLED_SECTIONS = @CMAKE_DOXYGEN_ENABLED_SECTIONS@
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_FILES = YES
|
||||
@@ -104,7 +104,7 @@ INPUT = @CMAKE_DOXYGEN_INPUT_LIST@
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS =
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE = @CMAKE_DOXYGEN_EXCLUDE_LIST@
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS = *.inl.hpp *.impl.hpp *_detail.hpp */cudev/**/detail/*.hpp *.m */opencl/runtime/*
|
||||
EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__*
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import cv2 as cv
|
||||
|
||||
img = cv.imread('star.jpg',0)
|
||||
ret,thresh = cv.threshold(img,127,255,0)
|
||||
im2,contours,hierarchy = cv.findContours(thresh, 1, 2)
|
||||
contours,hierarchy = cv.findContours(thresh, 1, 2)
|
||||
|
||||
cnt = contours[0]
|
||||
M = cv.moments(cnt)
|
||||
|
||||
+4
-4
@@ -17,7 +17,7 @@ detection and recognition.
|
||||
|
||||
- For better accuracy, use binary images. So before finding contours, apply threshold or canny
|
||||
edge detection.
|
||||
- Since OpenCV 3.2, findContours() no longer modifies the source image but returns a modified image as the first of three return parameters.
|
||||
- Since OpenCV 3.2, findContours() no longer modifies the source image.
|
||||
- In OpenCV, finding contours is like finding white object from black background. So remember,
|
||||
object to be found should be white and background should be black.
|
||||
|
||||
@@ -29,11 +29,11 @@ import cv2 as cv
|
||||
im = cv.imread('test.jpg')
|
||||
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
|
||||
ret, thresh = cv.threshold(imgray, 127, 255, 0)
|
||||
im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
|
||||
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
|
||||
@endcode
|
||||
See, there are three arguments in **cv.findContours()** function, first one is source image, second
|
||||
is contour retrieval mode, third is contour approximation method. And it outputs a modified image, the contours and
|
||||
hierarchy. contours is a Python list of all the contours in the image. Each individual contour is a
|
||||
is contour retrieval mode, third is contour approximation method. And it outputs the contours and hierarchy.
|
||||
Contours is a Python list of all the contours in the image. Each individual contour is a
|
||||
Numpy array of (x,y) coordinates of boundary points of the object.
|
||||
|
||||
@note We will discuss second and third arguments and about hierarchy in details later. Until then,
|
||||
|
||||
+3
-3
@@ -39,7 +39,7 @@ import numpy as np
|
||||
img = cv.imread('star.jpg')
|
||||
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
|
||||
ret,thresh = cv.threshold(img_gray, 127, 255,0)
|
||||
im2,contours,hierarchy = cv.findContours(thresh,2,1)
|
||||
contours,hierarchy = cv.findContours(thresh,2,1)
|
||||
cnt = contours[0]
|
||||
|
||||
hull = cv.convexHull(cnt,returnPoints = False)
|
||||
@@ -93,9 +93,9 @@ img2 = cv.imread('star2.jpg',0)
|
||||
|
||||
ret, thresh = cv.threshold(img1, 127, 255,0)
|
||||
ret, thresh2 = cv.threshold(img2, 127, 255,0)
|
||||
im2,contours,hierarchy = cv.findContours(thresh,2,1)
|
||||
contours,hierarchy = cv.findContours(thresh,2,1)
|
||||
cnt1 = contours[0]
|
||||
im2,contours,hierarchy = cv.findContours(thresh2,2,1)
|
||||
contours,hierarchy = cv.findContours(thresh2,2,1)
|
||||
cnt2 = contours[0]
|
||||
|
||||
ret = cv.matchShapes(cnt1,cnt2,1,0.0)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@cond CUDA_MODULES
|
||||
Similarity check (PNSR and SSIM) on the GPU {#tutorial_gpu_basics_similarity}
|
||||
===========================================
|
||||
@todo update this tutorial
|
||||
@@ -204,3 +205,4 @@ It may be just the improvement needed for your application to work. You may obse
|
||||
instance of this on the [YouTube here](https://www.youtube.com/watch?v=3_ESXmFlnvY).
|
||||
|
||||
@youtube{3_ESXmFlnvY}
|
||||
@endcond
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@cond CUDA_MODULES
|
||||
Using a cv::cuda::GpuMat with thrust {#tutorial_gpu_thrust_interop}
|
||||
===========================================
|
||||
|
||||
@@ -68,3 +69,4 @@ Next we will determine how many values are greater than 0 by using thrust::count
|
||||
|
||||
We will use those results to create an output buffer for storing the copied values, we will then use copy_if with the same predicate to populate the output buffer.
|
||||
Lastly we will download the values into a CPU mat for viewing.
|
||||
@endcond
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@cond CUDA_MODULES
|
||||
GPU-Accelerated Computer Vision (cuda module) {#tutorial_table_of_content_gpu}
|
||||
=============================================
|
||||
|
||||
@@ -20,3 +21,4 @@ run the OpenCV algorithms.
|
||||
|
||||
This tutorial will show you how to wrap a GpuMat into a thrust iterator in order to be able to
|
||||
use the functions in the thrust library.
|
||||
@endcond
|
||||
|
||||
@@ -56,7 +56,7 @@ Theory
|
||||
entire pyramid.
|
||||
- The procedure above was useful to downsample an image. What if we want to make it bigger?:
|
||||
columns filled with zeros (\f$0 \f$)
|
||||
- First, upsize the image to twice the original in each dimension, wit the new even rows and
|
||||
- First, upsize the image to twice the original in each dimension, with the new even rows and
|
||||
- Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the
|
||||
values of the "missing pixels"
|
||||
- These two procedures (downsampling and upsampling as explained above) are implemented by the
|
||||
|
||||
@@ -236,7 +236,10 @@ for(;;){
|
||||
|
||||
CUDA {#tutorial_transition_hints_cuda}
|
||||
----
|
||||
_cuda_ module has been split into several smaller pieces:
|
||||
|
||||
CUDA modules has been moved into opencv_contrib repository.
|
||||
|
||||
@cond CUDA_MODULES
|
||||
- _cuda_ - @ref cuda
|
||||
- _cudaarithm_ - @ref cudaarithm
|
||||
- _cudabgsegm_ - @ref cudabgsegm
|
||||
@@ -249,10 +252,7 @@ _cuda_ module has been split into several smaller pieces:
|
||||
- _cudastereo_ - @ref cudastereo
|
||||
- _cudawarping_ - @ref cudawarping
|
||||
- _cudev_ - @ref cudev
|
||||
|
||||
`gpu` namespace has been removed, use cv::cuda namespace instead. Many classes has also been renamed, for example:
|
||||
- `gpu::FAST_GPU` -> cv::cuda::FastFeatureDetector
|
||||
- `gpu::createBoxFilter_GPU` -> cv::cuda::createBoxFilter
|
||||
@endcond
|
||||
|
||||
Documentation format {#tutorial_transition_docs}
|
||||
--------------------
|
||||
|
||||
@@ -76,11 +76,13 @@ As always, we would be happy to hear your comments and receive your contribution
|
||||
|
||||
Learn how to create beautiful photo panoramas and more with OpenCV stitching pipeline.
|
||||
|
||||
@cond CUDA_MODULES
|
||||
- @subpage tutorial_table_of_content_gpu
|
||||
|
||||
Squeeze out every
|
||||
little computational power from your system by utilizing the power of your video card to run the
|
||||
OpenCV algorithms.
|
||||
@endcond
|
||||
|
||||
- @subpage tutorial_table_of_content_ios
|
||||
|
||||
|
||||
@@ -244,7 +244,9 @@ enum { SOLVEPNP_ITERATIVE = 0,
|
||||
enum { CALIB_CB_ADAPTIVE_THRESH = 1,
|
||||
CALIB_CB_NORMALIZE_IMAGE = 2,
|
||||
CALIB_CB_FILTER_QUADS = 4,
|
||||
CALIB_CB_FAST_CHECK = 8
|
||||
CALIB_CB_FAST_CHECK = 8,
|
||||
CALIB_CB_EXHAUSTIVE = 16,
|
||||
CALIB_CB_ACCURACY = 32
|
||||
};
|
||||
|
||||
enum { CALIB_CB_SYMMETRIC_GRID = 1,
|
||||
@@ -847,7 +849,11 @@ CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize, Out
|
||||
@param patternSize Number of inner corners per a chessboard row and column
|
||||
( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) ).
|
||||
@param corners Output array of detected corners.
|
||||
@param flags operation flags for future improvements
|
||||
@param flags Various operation flags that can be zero or a combination of the following values:
|
||||
- **CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before detection.
|
||||
- **CALIB_CB_EXHAUSTIVE ** Run an exhaustive search to improve detection rate.
|
||||
- **CALIB_CB_ACCURACY ** Up sample input image to improve sub-pixel accuracy due to aliasing effects.
|
||||
This should be used if an accurate camera calibration is required.
|
||||
|
||||
The function is analog to findchessboardCorners but uses a localized radon
|
||||
transformation approximated by box filters being more robust to all sort of
|
||||
@@ -2216,6 +2222,209 @@ public:
|
||||
int mode = StereoSGBM::MODE_SGBM);
|
||||
};
|
||||
|
||||
|
||||
//! cv::undistort mode
|
||||
enum UndistortTypes
|
||||
{
|
||||
PROJ_SPHERICAL_ORTHO = 0,
|
||||
PROJ_SPHERICAL_EQRECT = 1
|
||||
};
|
||||
|
||||
/** @brief Transforms an image to compensate for lens distortion.
|
||||
|
||||
The function transforms an image to compensate radial and tangential lens distortion.
|
||||
|
||||
The function is simply a combination of #initUndistortRectifyMap (with unity R ) and #remap
|
||||
(with bilinear interpolation). See the former function for details of the transformation being
|
||||
performed.
|
||||
|
||||
Those pixels in the destination image, for which there is no correspondent pixels in the source
|
||||
image, are filled with zeros (black color).
|
||||
|
||||
A particular subset of the source image that will be visible in the corrected image can be regulated
|
||||
by newCameraMatrix. You can use #getOptimalNewCameraMatrix to compute the appropriate
|
||||
newCameraMatrix depending on your requirements.
|
||||
|
||||
The camera matrix and the distortion parameters can be determined using #calibrateCamera. If
|
||||
the resolution of images is different from the resolution used at the calibration stage, \f$f_x,
|
||||
f_y, c_x\f$ and \f$c_y\f$ need to be scaled accordingly, while the distortion coefficients remain
|
||||
the same.
|
||||
|
||||
@param src Input (distorted) image.
|
||||
@param dst Output (corrected) image that has the same size and type as src .
|
||||
@param cameraMatrix Input camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
@param distCoeffs Input vector of distortion coefficients
|
||||
\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
|
||||
of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
|
||||
@param newCameraMatrix Camera matrix of the distorted image. By default, it is the same as
|
||||
cameraMatrix but you may additionally scale and shift the result by using a different matrix.
|
||||
*/
|
||||
CV_EXPORTS_W void undistort( InputArray src, OutputArray dst,
|
||||
InputArray cameraMatrix,
|
||||
InputArray distCoeffs,
|
||||
InputArray newCameraMatrix = noArray() );
|
||||
|
||||
/** @brief Computes the undistortion and rectification transformation map.
|
||||
|
||||
The function computes the joint undistortion and rectification transformation and represents the
|
||||
result in the form of maps for remap. The undistorted image looks like original, as if it is
|
||||
captured with a camera using the camera matrix =newCameraMatrix and zero distortion. In case of a
|
||||
monocular camera, newCameraMatrix is usually equal to cameraMatrix, or it can be computed by
|
||||
#getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera,
|
||||
newCameraMatrix is normally set to P1 or P2 computed by #stereoRectify .
|
||||
|
||||
Also, this new camera is oriented differently in the coordinate space, according to R. That, for
|
||||
example, helps to align two heads of a stereo camera so that the epipolar lines on both images
|
||||
become horizontal and have the same y- coordinate (in case of a horizontally aligned stereo camera).
|
||||
|
||||
The function actually builds the maps for the inverse mapping algorithm that is used by remap. That
|
||||
is, for each pixel \f$(u, v)\f$ in the destination (corrected and rectified) image, the function
|
||||
computes the corresponding coordinates in the source image (that is, in the original image from
|
||||
camera). The following process is applied:
|
||||
\f[
|
||||
\begin{array}{l}
|
||||
x \leftarrow (u - {c'}_x)/{f'}_x \\
|
||||
y \leftarrow (v - {c'}_y)/{f'}_y \\
|
||||
{[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\
|
||||
x' \leftarrow X/W \\
|
||||
y' \leftarrow Y/W \\
|
||||
r^2 \leftarrow x'^2 + y'^2 \\
|
||||
x'' \leftarrow x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}
|
||||
+ 2p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4\\
|
||||
y'' \leftarrow y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}
|
||||
+ p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\
|
||||
s\vecthree{x'''}{y'''}{1} =
|
||||
\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}((\tau_x, \tau_y)}
|
||||
{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)}
|
||||
{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\
|
||||
map_x(u,v) \leftarrow x''' f_x + c_x \\
|
||||
map_y(u,v) \leftarrow y''' f_y + c_y
|
||||
\end{array}
|
||||
\f]
|
||||
where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
|
||||
are the distortion coefficients.
|
||||
|
||||
In case of a stereo camera, this function is called twice: once for each camera head, after
|
||||
stereoRectify, which in its turn is called after #stereoCalibrate. But if the stereo camera
|
||||
was not calibrated, it is still possible to compute the rectification transformations directly from
|
||||
the fundamental matrix using #stereoRectifyUncalibrated. For each camera, the function computes
|
||||
homography H as the rectification transformation in a pixel domain, not a rotation matrix R in 3D
|
||||
space. R can be computed from H as
|
||||
\f[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\f]
|
||||
where cameraMatrix can be chosen arbitrarily.
|
||||
|
||||
@param cameraMatrix Input camera matrix \f$A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
@param distCoeffs Input vector of distortion coefficients
|
||||
\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
|
||||
of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
|
||||
@param R Optional rectification transformation in the object space (3x3 matrix). R1 or R2 ,
|
||||
computed by #stereoRectify can be passed here. If the matrix is empty, the identity transformation
|
||||
is assumed. In cvInitUndistortMap R assumed to be an identity matrix.
|
||||
@param newCameraMatrix New camera matrix \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$.
|
||||
@param size Undistorted image size.
|
||||
@param m1type Type of the first output map that can be CV_32FC1, CV_32FC2 or CV_16SC2, see #convertMaps
|
||||
@param map1 The first output map.
|
||||
@param map2 The second output map.
|
||||
*/
|
||||
CV_EXPORTS_W
|
||||
void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs,
|
||||
InputArray R, InputArray newCameraMatrix,
|
||||
Size size, int m1type, OutputArray map1, OutputArray map2);
|
||||
|
||||
//! initializes maps for #remap for wide-angle
|
||||
CV_EXPORTS
|
||||
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
|
||||
Size imageSize, int destImageWidth,
|
||||
int m1type, OutputArray map1, OutputArray map2,
|
||||
enum UndistortTypes projType = PROJ_SPHERICAL_EQRECT, double alpha = 0);
|
||||
static inline
|
||||
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
|
||||
Size imageSize, int destImageWidth,
|
||||
int m1type, OutputArray map1, OutputArray map2,
|
||||
int projType, double alpha = 0)
|
||||
{
|
||||
return initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize, destImageWidth,
|
||||
m1type, map1, map2, (UndistortTypes)projType, alpha);
|
||||
}
|
||||
|
||||
/** @brief Returns the default new camera matrix.
|
||||
|
||||
The function returns the camera matrix that is either an exact copy of the input cameraMatrix (when
|
||||
centerPrinicipalPoint=false ), or the modified one (when centerPrincipalPoint=true).
|
||||
|
||||
In the latter case, the new camera matrix will be:
|
||||
|
||||
\f[\begin{bmatrix} f_x && 0 && ( \texttt{imgSize.width} -1)*0.5 \\ 0 && f_y && ( \texttt{imgSize.height} -1)*0.5 \\ 0 && 0 && 1 \end{bmatrix} ,\f]
|
||||
|
||||
where \f$f_x\f$ and \f$f_y\f$ are \f$(0,0)\f$ and \f$(1,1)\f$ elements of cameraMatrix, respectively.
|
||||
|
||||
By default, the undistortion functions in OpenCV (see #initUndistortRectifyMap, #undistort) do not
|
||||
move the principal point. However, when you work with stereo, it is important to move the principal
|
||||
points in both views to the same y-coordinate (which is required by most of stereo correspondence
|
||||
algorithms), and may be to the same x-coordinate too. So, you can form the new camera matrix for
|
||||
each view where the principal points are located at the center.
|
||||
|
||||
@param cameraMatrix Input camera matrix.
|
||||
@param imgsize Camera view image size in pixels.
|
||||
@param centerPrincipalPoint Location of the principal point in the new camera matrix. The
|
||||
parameter indicates whether this location should be at the image center or not.
|
||||
*/
|
||||
CV_EXPORTS_W
|
||||
Mat getDefaultNewCameraMatrix(InputArray cameraMatrix, Size imgsize = Size(),
|
||||
bool centerPrincipalPoint = false);
|
||||
|
||||
/** @brief Computes the ideal point coordinates from the observed point coordinates.
|
||||
|
||||
The function is similar to #undistort and #initUndistortRectifyMap but it operates on a
|
||||
sparse set of points instead of a raster image. Also the function performs a reverse transformation
|
||||
to projectPoints. In case of a 3D object, it does not reconstruct its 3D coordinates, but for a
|
||||
planar object, it does, up to a translation vector, if the proper R is specified.
|
||||
|
||||
For each observed point coordinate \f$(u, v)\f$ the function computes:
|
||||
\f[
|
||||
\begin{array}{l}
|
||||
x^{"} \leftarrow (u - c_x)/f_x \\
|
||||
y^{"} \leftarrow (v - c_y)/f_y \\
|
||||
(x',y') = undistort(x^{"},y^{"}, \texttt{distCoeffs}) \\
|
||||
{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\
|
||||
x \leftarrow X/W \\
|
||||
y \leftarrow Y/W \\
|
||||
\text{only performed if P is specified:} \\
|
||||
u' \leftarrow x {f'}_x + {c'}_x \\
|
||||
v' \leftarrow y {f'}_y + {c'}_y
|
||||
\end{array}
|
||||
\f]
|
||||
|
||||
where *undistort* is an approximate iterative algorithm that estimates the normalized original
|
||||
point coordinates out of the normalized distorted point coordinates ("normalized" means that the
|
||||
coordinates do not depend on the camera matrix).
|
||||
|
||||
The function can be used for both a stereo camera head or a monocular camera (when R is empty).
|
||||
|
||||
@param src Observed point coordinates, 1xN or Nx1 2-channel (CV_32FC2 or CV_64FC2).
|
||||
@param dst Output ideal point coordinates after undistortion and reverse perspective
|
||||
transformation. If matrix P is identity or omitted, dst will contain normalized point coordinates.
|
||||
@param cameraMatrix Camera matrix \f$\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
|
||||
@param distCoeffs Input vector of distortion coefficients
|
||||
\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
|
||||
of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
|
||||
@param R Rectification transformation in the object space (3x3 matrix). R1 or R2 computed by
|
||||
#stereoRectify can be passed here. If the matrix is empty, the identity transformation is used.
|
||||
@param P New camera matrix (3x3) or new projection matrix (3x4) \f$\begin{bmatrix} {f'}_x & 0 & {c'}_x & t_x \\ 0 & {f'}_y & {c'}_y & t_y \\ 0 & 0 & 1 & t_z \end{bmatrix}\f$. P1 or P2 computed by
|
||||
#stereoRectify can be passed here. If the matrix is empty, the identity new camera matrix is used.
|
||||
*/
|
||||
CV_EXPORTS_W
|
||||
void undistortPoints(InputArray src, OutputArray dst,
|
||||
InputArray cameraMatrix, InputArray distCoeffs,
|
||||
InputArray R = noArray(), InputArray P = noArray());
|
||||
/** @overload
|
||||
@note Default version of #undistortPoints does 5 iterations to compute undistorted points.
|
||||
*/
|
||||
CV_EXPORTS_AS(undistortPointsIter)
|
||||
void undistortPoints(InputArray src, OutputArray dst,
|
||||
InputArray cameraMatrix, InputArray distCoeffs,
|
||||
InputArray R, InputArray P, TermCriteria criteria);
|
||||
|
||||
//! @} calib3d
|
||||
|
||||
/** @brief The methods in this namespace use a so-called fisheye camera model.
|
||||
|
||||
@@ -379,6 +379,39 @@ CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage,
|
||||
CvArr* _3dImage, const CvMat* Q,
|
||||
int handleMissingValues CV_DEFAULT(0) );
|
||||
|
||||
/** @brief Transforms the input image to compensate lens distortion
|
||||
@see cv::undistort
|
||||
*/
|
||||
CVAPI(void) cvUndistort2( const CvArr* src, CvArr* dst,
|
||||
const CvMat* camera_matrix,
|
||||
const CvMat* distortion_coeffs,
|
||||
const CvMat* new_camera_matrix CV_DEFAULT(0) );
|
||||
|
||||
/** @brief Computes transformation map from intrinsic camera parameters
|
||||
that can used by cvRemap
|
||||
*/
|
||||
CVAPI(void) cvInitUndistortMap( const CvMat* camera_matrix,
|
||||
const CvMat* distortion_coeffs,
|
||||
CvArr* mapx, CvArr* mapy );
|
||||
|
||||
/** @brief Computes undistortion+rectification map for a head of stereo camera
|
||||
@see cv::initUndistortRectifyMap
|
||||
*/
|
||||
CVAPI(void) cvInitUndistortRectifyMap( const CvMat* camera_matrix,
|
||||
const CvMat* dist_coeffs,
|
||||
const CvMat *R, const CvMat* new_camera_matrix,
|
||||
CvArr* mapx, CvArr* mapy );
|
||||
|
||||
/** @brief Computes the original (undistorted) feature coordinates
|
||||
from the observed (distorted) coordinates
|
||||
@see cv::undistortPoints
|
||||
*/
|
||||
CVAPI(void) cvUndistortPoints( const CvMat* src, CvMat* dst,
|
||||
const CvMat* camera_matrix,
|
||||
const CvMat* dist_coeffs,
|
||||
const CvMat* R CV_DEFAULT(0),
|
||||
const CvMat* P CV_DEFAULT(0));
|
||||
|
||||
/** @} calib3d_c */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.opencv.test.calib3d;
|
||||
|
||||
import org.opencv.calib3d.Calib3d;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfDouble;
|
||||
@@ -14,6 +15,15 @@ import org.opencv.imgproc.Imgproc;
|
||||
|
||||
public class Calib3dTest extends OpenCVTestCase {
|
||||
|
||||
Size size;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
size = new Size(3, 3);
|
||||
}
|
||||
|
||||
public void testCalibrateCameraListOfMatListOfMatSizeMatMatListOfMatListOfMat() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
@@ -602,4 +612,131 @@ public class Calib3dTest extends OpenCVTestCase {
|
||||
Calib3d.computeCorrespondEpilines(left, 1, fundamental, lines);
|
||||
assertMatEqual(truth, lines, EPS);
|
||||
}
|
||||
|
||||
public void testGetDefaultNewCameraMatrixMat() {
|
||||
Mat mtx = Calib3d.getDefaultNewCameraMatrix(gray0);
|
||||
|
||||
assertFalse(mtx.empty());
|
||||
assertEquals(0, Core.countNonZero(mtx));
|
||||
}
|
||||
|
||||
public void testGetDefaultNewCameraMatrixMatSizeBoolean() {
|
||||
Mat mtx = Calib3d.getDefaultNewCameraMatrix(gray0, size, true);
|
||||
|
||||
assertFalse(mtx.empty());
|
||||
assertFalse(0 == Core.countNonZero(mtx));
|
||||
// TODO_: write better test
|
||||
}
|
||||
|
||||
public void testInitUndistortRectifyMap() {
|
||||
fail("Not yet implemented");
|
||||
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
|
||||
cameraMatrix.put(0, 0, 1, 0, 1);
|
||||
cameraMatrix.put(1, 0, 0, 1, 1);
|
||||
cameraMatrix.put(2, 0, 0, 0, 1);
|
||||
|
||||
Mat R = new Mat(3, 3, CvType.CV_32F, new Scalar(2));
|
||||
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
|
||||
|
||||
Mat distCoeffs = new Mat();
|
||||
Mat map1 = new Mat();
|
||||
Mat map2 = new Mat();
|
||||
|
||||
// TODO: complete this test
|
||||
Calib3d.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, CvType.CV_32F, map1, map2);
|
||||
}
|
||||
|
||||
public void testInitWideAngleProjMapMatMatSizeIntIntMatMat() {
|
||||
fail("Not yet implemented");
|
||||
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
|
||||
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F);
|
||||
// Size imageSize = new Size(2, 2);
|
||||
|
||||
cameraMatrix.put(0, 0, 1, 0, 1);
|
||||
cameraMatrix.put(1, 0, 0, 1, 2);
|
||||
cameraMatrix.put(2, 0, 0, 0, 1);
|
||||
|
||||
distCoeffs.put(0, 0, 1, 3, 2, 4);
|
||||
truth = new Mat(3, 3, CvType.CV_32F);
|
||||
truth.put(0, 0, 0, 0, 0);
|
||||
truth.put(1, 0, 0, 0, 0);
|
||||
truth.put(2, 0, 0, 3, 0);
|
||||
// TODO: No documentation for this function
|
||||
// Calib3d.initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize,
|
||||
// 5, m1type, truthput1, truthput2);
|
||||
}
|
||||
|
||||
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatInt() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatIntDouble() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
public void testUndistortMatMatMatMat() {
|
||||
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
|
||||
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
|
||||
{
|
||||
put(0, 0, 1, 0, 1);
|
||||
put(1, 0, 0, 1, 2);
|
||||
put(2, 0, 0, 0, 1);
|
||||
}
|
||||
};
|
||||
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
|
||||
{
|
||||
put(0, 0, 1, 3, 2, 4);
|
||||
}
|
||||
};
|
||||
|
||||
Calib3d.undistort(src, dst, cameraMatrix, distCoeffs);
|
||||
|
||||
truth = new Mat(3, 3, CvType.CV_32F) {
|
||||
{
|
||||
put(0, 0, 0, 0, 0);
|
||||
put(1, 0, 0, 0, 0);
|
||||
put(2, 0, 0, 3, 0);
|
||||
}
|
||||
};
|
||||
assertMatEqual(truth, dst, EPS);
|
||||
}
|
||||
|
||||
public void testUndistortMatMatMatMatMat() {
|
||||
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
|
||||
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
|
||||
{
|
||||
put(0, 0, 1, 0, 1);
|
||||
put(1, 0, 0, 1, 2);
|
||||
put(2, 0, 0, 0, 1);
|
||||
}
|
||||
};
|
||||
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
|
||||
{
|
||||
put(0, 0, 2, 1, 4, 5);
|
||||
}
|
||||
};
|
||||
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(1));
|
||||
|
||||
Calib3d.undistort(src, dst, cameraMatrix, distCoeffs, newCameraMatrix);
|
||||
|
||||
truth = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
|
||||
assertMatEqual(truth, dst, EPS);
|
||||
}
|
||||
|
||||
//undistortPoints(List<Point> src, List<Point> dst, Mat cameraMatrix, Mat distCoeffs)
|
||||
public void testUndistortPointsListOfPointListOfPointMatMat() {
|
||||
MatOfPoint2f src = new MatOfPoint2f(new Point(1, 2), new Point(3, 4), new Point(-1, -1));
|
||||
MatOfPoint2f dst = new MatOfPoint2f();
|
||||
Mat cameraMatrix = Mat.eye(3, 3, CvType.CV_64FC1);
|
||||
Mat distCoeffs = new Mat(8, 1, CvType.CV_64FC1, new Scalar(0));
|
||||
|
||||
Calib3d.undistortPoints(src, dst, cameraMatrix, distCoeffs);
|
||||
|
||||
assertEquals(src.size(), dst.size());
|
||||
for(int i=0; i<src.toList().size(); i++) {
|
||||
//Log.d("UndistortPoints", "s="+src.get(i)+", d="+dst.get(i));
|
||||
assertTrue(src.toList().get(i).equals(dst.toList().get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/imgproc/detail/distortion_model.hpp"
|
||||
#include "distortion_model.hpp"
|
||||
#include "opencv2/calib3d/calib3d_c.h"
|
||||
#include <stdio.h>
|
||||
#include <iterator>
|
||||
@@ -3541,6 +3541,9 @@ double cv::stereoCalibrate( InputArrayOfArrays _objectPoints,
|
||||
OutputArray _Emat, OutputArray _Fmat, int flags,
|
||||
TermCriteria criteria)
|
||||
{
|
||||
if (flags & CALIB_USE_EXTRINSIC_GUESS)
|
||||
CV_Error(Error::StsBadFlag, "stereoCalibrate does not support CALIB_USE_EXTRINSIC_GUESS.");
|
||||
|
||||
Mat Rmat, Tmat;
|
||||
double ret = stereoCalibrate(_objectPoints, _imagePoints1, _imagePoints2, _cameraMatrix1, _distCoeffs1,
|
||||
_cameraMatrix2, _distCoeffs2, imageSize, Rmat, Tmat, _Emat, _Fmat,
|
||||
|
||||
+211
-193
@@ -10,7 +10,7 @@
|
||||
//#define CV_DETECTORS_CHESSBOARD_DEBUG
|
||||
#ifdef CV_DETECTORS_CHESSBOARD_DEBUG
|
||||
#include <opencv2/highgui.hpp>
|
||||
cv::Mat debug_image;
|
||||
static cv::Mat debug_image;
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
@@ -21,19 +21,19 @@ namespace details {
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// magic numbers used for chessboard corner detection
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
const float CORNERS_SEARCH = 0.5F; // percentage of the edge length to the next corner used to find new corners
|
||||
const float MAX_ANGLE = float(48.0/180.0*M_PI); // max angle between line segments supposed to be straight
|
||||
const float MIN_COS_ANGLE = float(cos(35.0/180*M_PI)); // min cos angle between board edges
|
||||
const float MIN_RESPONSE_RATIO = 0.3F;
|
||||
const float ELLIPSE_WIDTH = 0.35F; // width of the search ellipse in percentage of its length
|
||||
const float RAD2DEG = float(180.0/M_PI);
|
||||
const int MAX_SYMMETRY_ERRORS = 5; // maximal number of failures during point symmetry test (filtering out lines)
|
||||
static const float CORNERS_SEARCH = 0.5F; // percentage of the edge length to the next corner used to find new corners
|
||||
static const float MAX_ANGLE = float(48.0/180.0*CV_PI); // max angle between line segments supposed to be straight
|
||||
static const float MIN_COS_ANGLE = float(cos(35.0/180*CV_PI)); // min cos angle between board edges
|
||||
static const float MIN_RESPONSE_RATIO = 0.1F;
|
||||
static const float ELLIPSE_WIDTH = 0.35F; // width of the search ellipse in percentage of its length
|
||||
static const float RAD2DEG = float(180.0/CV_PI);
|
||||
static const int MAX_SYMMETRY_ERRORS = 5; // maximal number of failures during point symmetry test (filtering out lines)
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// some helper methods
|
||||
static bool isPointOnLine(cv::Point2f l1,cv::Point2f l2,cv::Point2f pt,float min_angle);
|
||||
static int testPointSymmetry(cv::Mat mat,cv::Point2f pt,float dist,float max_error);
|
||||
static int testPointSymmetry(const cv::Mat& mat,cv::Point2f pt,float dist,float max_error);
|
||||
static float calcSubpixel(const float &x_l,const float &x,const float &x_r);
|
||||
static float calcSubPos(const float &x_l,const float &x,const float &x_r);
|
||||
static void polyfit(const Mat& src_x, const Mat& src_y, Mat& dst, int order);
|
||||
@@ -60,26 +60,23 @@ void normalizePoints1D(cv::InputArray _points,cv::OutputArray _T,cv::OutputArray
|
||||
CV_Error(Error::StsBadArg, "all given points are identical");
|
||||
double scale = 1.0/mean_dist;
|
||||
|
||||
|
||||
// generate transformation
|
||||
_T.create(2,2,CV_64FC1);
|
||||
cv::Mat T = _T.getMat();
|
||||
T.at<double>(0,0) = scale;
|
||||
T.at<double>(0,1) = -scale*centroid;
|
||||
T.at<double>(1,0) = 0;
|
||||
T.at<double>(1,1) = 1;
|
||||
cv::Matx22d Tx(
|
||||
scale, -scale*centroid,
|
||||
0, 1
|
||||
);
|
||||
Mat(Tx, false).copyTo(_T);
|
||||
|
||||
// calc normalized points;
|
||||
cv::Matx22d Tx(T);
|
||||
_new_points.create(points.rows,1,points.type());
|
||||
new_points = _new_points.getMat();
|
||||
cv::Vec2d p;
|
||||
switch(points.type())
|
||||
{
|
||||
case CV_32FC1:
|
||||
for(int i=0;i < points.rows;++i)
|
||||
{
|
||||
p(0) = points.at<float>(i);
|
||||
p(1) = 1.0;
|
||||
cv::Vec2d p(points.at<float>(i), 1.0);
|
||||
p = Tx*p;
|
||||
new_points.at<float>(i) = float(p(0)/p(1));
|
||||
}
|
||||
@@ -87,8 +84,7 @@ void normalizePoints1D(cv::InputArray _points,cv::OutputArray _T,cv::OutputArray
|
||||
case CV_64FC1:
|
||||
for(int i=0;i < points.rows;++i)
|
||||
{
|
||||
p(0) = points.at<double>(i);
|
||||
p(1) = 1.0;
|
||||
cv::Vec2d p(points.at<double>(i), 1.0);
|
||||
p = Tx*p;
|
||||
new_points.at<double>(i) = p(0)/p(1);
|
||||
}
|
||||
@@ -107,8 +103,7 @@ cv::Mat findHomography1D(cv::InputArray _src,cv::InputArray _dst)
|
||||
src = src.reshape(1,src.cols);
|
||||
if(dst.cols > 1 && dst.rows == 1)
|
||||
dst = dst.reshape(1,dst.cols);
|
||||
if(src.rows != dst.rows)
|
||||
CV_Error(Error::StsBadArg, "size mismatch");
|
||||
CV_CheckEQ(src.rows, dst.rows, "size mismatch");
|
||||
CV_CheckChannelsEQ(src.channels(), 1, "data with only one channel are supported");
|
||||
CV_CheckChannelsEQ(dst.channels(), 1, "data with only one channel are supported");
|
||||
CV_CheckTypeEQ(src.type(), dst.type(), "src and dst must have the same type");
|
||||
@@ -163,10 +158,10 @@ cv::Mat findHomography1D(cv::InputArray _src,cv::InputArray _dst)
|
||||
y.at<double>(i) = b_.at<double>(i)/d.at<double>(i);
|
||||
|
||||
cv::Mat x = vt.t()*y;
|
||||
cv::Mat H = (cv::Mat_<double>(2,2) << x.at<double>(0), x.at<double>(1), x.at<double>(2), 1.0);
|
||||
cv::Matx22d H_(x.at<double>(0), x.at<double>(1), x.at<double>(2), 1.0);
|
||||
|
||||
// denormalize
|
||||
H = dst_T.inv()*H*src_T;
|
||||
Mat H = dst_T.inv()*Mat(H_, false)*src_T;
|
||||
|
||||
// enforce frobeniusnorm of one
|
||||
double scale = 1.0/cv::norm(H);
|
||||
@@ -177,8 +172,8 @@ void polyfit(const Mat& src_x, const Mat& src_y, Mat& dst, int order)
|
||||
int npoints = src_x.checkVector(1);
|
||||
int nypoints = src_y.checkVector(1);
|
||||
CV_Assert(npoints == nypoints && npoints >= order+1);
|
||||
Mat srcX = Mat_<double>(src_x), srcY = Mat_<double>(src_y);
|
||||
Mat A = Mat_<double>::ones(npoints,order + 1);
|
||||
Mat_<double> srcX(src_x), srcY(src_y);
|
||||
Mat_<double> A = Mat_<double>::ones(npoints,order + 1);
|
||||
// build A matrix
|
||||
for (int y = 0; y < npoints; ++y)
|
||||
{
|
||||
@@ -187,7 +182,7 @@ void polyfit(const Mat& src_x, const Mat& src_y, Mat& dst, int order)
|
||||
}
|
||||
cv::Mat w;
|
||||
solve(A,srcY,w,DECOMP_SVD);
|
||||
w.convertTo(dst,std::max(std::max(src_x.depth(), src_y.depth()), CV_32F));
|
||||
w.convertTo(dst, ((src_x.depth() == CV_64F || src_y.depth() == CV_64F) ? CV_64F : CV_32F));
|
||||
}
|
||||
|
||||
float calcSignedDistance(const cv::Vec2f &n,const cv::Point2f &a,const cv::Point2f &pt)
|
||||
@@ -207,15 +202,16 @@ bool isPointOnLine(cv::Point2f l1,cv::Point2f l2,cv::Point2f pt,float min_angle)
|
||||
}
|
||||
|
||||
// returns how many tests fails out of 10
|
||||
int testPointSymmetry(cv::Mat mat,cv::Point2f pt,float dist,float max_error)
|
||||
int testPointSymmetry(const cv::Mat& mat,cv::Point2f pt,float dist,float max_error)
|
||||
{
|
||||
cv::Rect image_rect(int(0.5*dist),int(0.5*dist),int(mat.cols-0.5*dist),int(mat.rows-0.5*dist));
|
||||
cv::Size size(int(0.5*dist),int(0.5*dist));
|
||||
int count = 0;
|
||||
cv::Mat patch1,patch2;
|
||||
cv::Point2f center1,center2;
|
||||
for(double angle=0;angle <= M_PI;angle+=M_PI*0.1)
|
||||
for (int angle_i = 0; angle_i < 10; angle_i++)
|
||||
{
|
||||
double angle = angle_i * (CV_PI * 0.1);
|
||||
cv::Point2f n(float(cos(angle)),float(-sin(angle)));
|
||||
center1 = pt+dist*n;
|
||||
if(!image_rect.contains(center1))
|
||||
@@ -284,8 +280,7 @@ void FastX::rotate(float angle,const cv::Mat &img,cv::Size size,cv::Mat &out)con
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Mat m = cv::getRotationMatrix2D(cv::Point2f(float(img.cols*0.5),float(img.rows*0.5)),float(angle/M_PI*180),1);
|
||||
CV_Assert(m.type() == CV_64FC1);
|
||||
cv::Mat_<double> m = cv::getRotationMatrix2D(cv::Point2f(float(img.cols*0.5),float(img.rows*0.5)),float(angle/CV_PI*180),1);
|
||||
m.at<double>(0,2) += 0.5*(size.width-img.cols);
|
||||
m.at<double>(1,2) += 0.5*(size.height-img.rows);
|
||||
cv::warpAffine(img,out,m,size);
|
||||
@@ -390,7 +385,7 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
|
||||
// assuming all elements of the same channel
|
||||
const int channels = rotated_images.front().channels();
|
||||
int channels_1 = channels-1;
|
||||
float resolution = float(M_PI/channels);
|
||||
float resolution = float(CV_PI/channels);
|
||||
|
||||
float angle;
|
||||
float val1,val2,val3,wrap_around;
|
||||
@@ -436,9 +431,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
|
||||
{
|
||||
angle = float((calcSubPos(val1,val2,val3)+i)*resolution);
|
||||
if(angle < 0)
|
||||
angle += float(M_PI);
|
||||
else if(angle > M_PI)
|
||||
angle -= float(M_PI);
|
||||
angle += float(CV_PI);
|
||||
else if(angle > CV_PI)
|
||||
angle -= float(CV_PI);
|
||||
angles_i.push_back(angle);
|
||||
pt_iter->angle = 360.0F-angle*RAD2DEG;
|
||||
}
|
||||
@@ -447,9 +442,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
|
||||
{
|
||||
angle = float((calcSubPos(val1,val2,val3)+i)*resolution);
|
||||
if(angle < 0)
|
||||
angle += float(M_PI);
|
||||
else if(angle > M_PI)
|
||||
angle -= float(M_PI);
|
||||
angle += float(CV_PI);
|
||||
else if(angle > CV_PI)
|
||||
angle -= float(CV_PI);
|
||||
angles_i.push_back(-angle);
|
||||
pt_iter->angle = 360.0F-angle*RAD2DEG;
|
||||
}
|
||||
@@ -463,9 +458,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
|
||||
{
|
||||
angle = float((calcSubPos(val1,val2,wrap_around)+channels-1)*resolution);
|
||||
if(angle < 0)
|
||||
angle += float(M_PI);
|
||||
else if(angle > M_PI)
|
||||
angle -= float(M_PI);
|
||||
angle += float(CV_PI);
|
||||
else if(angle > CV_PI)
|
||||
angle -= float(CV_PI);
|
||||
angles_i.push_back(angle);
|
||||
pt_iter->angle = 360.0F-angle*RAD2DEG;
|
||||
}
|
||||
@@ -474,9 +469,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
|
||||
{
|
||||
angle = float((calcSubPos(val1,val2,wrap_around)+channels-1)*resolution);
|
||||
if(angle < 0)
|
||||
angle += float(M_PI);
|
||||
else if(angle > M_PI)
|
||||
angle -= float(M_PI);
|
||||
angle += float(CV_PI);
|
||||
else if(angle > CV_PI)
|
||||
angle -= float(CV_PI);
|
||||
angles_i.push_back(-angle);
|
||||
pt_iter->angle = 360.0F-angle*RAD2DEG;
|
||||
}
|
||||
@@ -488,10 +483,12 @@ void FastX::findKeyPoints(const std::vector<cv::Mat> &feature_maps, std::vector<
|
||||
{
|
||||
//TODO check that all feature_maps have the same size
|
||||
int num_scales = parameters.max_scale-parameters.min_scale;
|
||||
if(int(feature_maps.size()) < num_scales)
|
||||
CV_Error(Error::StsBadArg,"missing feature maps");
|
||||
if(_mask.data && (_mask.type() != CV_8UC1 || _mask.size() != feature_maps.front().size()))
|
||||
CV_Error(Error::StsBadMask,"wrong mask type or size");
|
||||
CV_CheckGE(int(feature_maps.size()), num_scales, "missing feature maps");
|
||||
if (!_mask.empty())
|
||||
{
|
||||
CV_CheckTypeEQ(_mask.type(), CV_8UC1, "wrong mask type");
|
||||
CV_CheckEQ(_mask.size(), feature_maps.front().size(),"wrong mask type or size");
|
||||
}
|
||||
keypoints.clear();
|
||||
|
||||
cv::Mat mask;
|
||||
@@ -512,10 +509,10 @@ void FastX::findKeyPoints(const std::vector<cv::Mat> &feature_maps, std::vector<
|
||||
cv::Mat src;
|
||||
for(int scale=parameters.max_scale;scale>=parameters.min_scale;--scale)
|
||||
{
|
||||
int window_size = int(pow(2.0,scale+super_res)+1);
|
||||
int window_size = (1 << (scale + super_res)) + 1;
|
||||
float window_size2 = 0.5F*window_size;
|
||||
float window_size4 = 0.25F*window_size;
|
||||
int window_size2i = int(round(window_size2));
|
||||
int window_size2i = cvRound(window_size2);
|
||||
|
||||
const cv::Mat &feature_map = feature_maps[scale-parameters.min_scale];
|
||||
int y = ((feature_map.rows)/window_size)-6;
|
||||
@@ -602,63 +599,67 @@ void FastX::detectAndCompute(cv::InputArray image,cv::InputArray mask,std::vecto
|
||||
return;
|
||||
}
|
||||
|
||||
void FastX::detectImpl(const cv::Mat& gray_image,
|
||||
void FastX::detectImpl(const cv::Mat& _gray_image,
|
||||
std::vector<cv::Mat> &rotated_images,
|
||||
std::vector<cv::Mat> &feature_maps,
|
||||
const cv::Mat &_mask)const
|
||||
{
|
||||
if(!_mask.empty())
|
||||
CV_Error(Error::StsBadSize, "Mask is not supported");
|
||||
CV_CheckTypeEQ(gray_image.type(), CV_8UC1, "Unsupported image type");
|
||||
CV_CheckTypeEQ(_gray_image.type(), CV_8UC1, "Unsupported image type");
|
||||
|
||||
// up-sample if needed
|
||||
cv::Mat gray_image;
|
||||
int super_res = int(parameters.super_resolution);
|
||||
if(super_res)
|
||||
cv::resize(gray_image,gray_image,cv::Size(),2,2);
|
||||
cv::resize(_gray_image,gray_image,cv::Size(),2,2);
|
||||
else
|
||||
gray_image = _gray_image;
|
||||
|
||||
//for each scale
|
||||
int num_scales = parameters.max_scale-parameters.min_scale+1;
|
||||
rotated_images.resize(num_scales);
|
||||
feature_maps.resize(num_scales);
|
||||
for(int scale=parameters.min_scale;scale <= parameters.max_scale;++scale)
|
||||
{
|
||||
// calc images
|
||||
// for each angle step
|
||||
int scale_id = scale-parameters.min_scale;
|
||||
cv::Mat rotated,filtered_h,filtered_v;
|
||||
int diag = int(sqrt(gray_image.rows*gray_image.rows+gray_image.cols*gray_image.cols));
|
||||
cv::Size size(diag,diag);
|
||||
int num = int(0.5001*M_PI/parameters.resolution);
|
||||
std::vector<cv::Mat> images;
|
||||
images.resize(2*num);
|
||||
int scale_size = int(1+pow(2.0,scale+1+super_res));
|
||||
int scale_size2 = int((scale_size/10)*2+1);
|
||||
for(int i=0;i<num;++i)
|
||||
parallel_for_(Range(parameters.min_scale,parameters.max_scale+1),[&](const Range& range){
|
||||
for(int scale=range.start;scale < range.end;++scale)
|
||||
{
|
||||
float angle = parameters.resolution*i;
|
||||
rotate(-angle,gray_image,size,rotated);
|
||||
cv::blur(rotated,filtered_h,cv::Size(scale_size,scale_size2));
|
||||
cv::blur(rotated,filtered_v,cv::Size(scale_size2,scale_size));
|
||||
// calc images
|
||||
// for each angle step
|
||||
int scale_id = scale-parameters.min_scale;
|
||||
cv::Mat rotated,filtered_h,filtered_v;
|
||||
int diag = int(sqrt(gray_image.rows*gray_image.rows+gray_image.cols*gray_image.cols));
|
||||
cv::Size size(diag,diag);
|
||||
int num = int(0.5001*CV_PI/parameters.resolution);
|
||||
std::vector<cv::Mat> images;
|
||||
images.resize(2*num);
|
||||
int scale_size = int(1+pow(2.0,scale+1+super_res));
|
||||
int scale_size2 = int((scale_size/10)*2+1);
|
||||
for(int i=0;i<num;++i)
|
||||
{
|
||||
float angle = parameters.resolution*i;
|
||||
rotate(-angle,gray_image,size,rotated);
|
||||
cv::blur(rotated,filtered_h,cv::Size(scale_size,scale_size2));
|
||||
cv::blur(rotated,filtered_v,cv::Size(scale_size2,scale_size));
|
||||
|
||||
// rotate filtered images back
|
||||
rotate(angle,filtered_h,gray_image.size(),images[i]);
|
||||
rotate(angle,filtered_v,gray_image.size(),images[i+num]);
|
||||
// rotate filtered images back
|
||||
rotate(angle,filtered_h,gray_image.size(),images[i]);
|
||||
rotate(angle,filtered_v,gray_image.size(),images[i+num]);
|
||||
}
|
||||
cv::merge(images,rotated_images[scale_id]);
|
||||
|
||||
// calc feature map
|
||||
calcFeatureMap(rotated_images[scale_id],feature_maps[scale_id]);
|
||||
// filter feature map to improve impulse responses
|
||||
if(parameters.filter)
|
||||
{
|
||||
cv::Mat high,low;
|
||||
cv::blur(feature_maps[scale_id],low,cv::Size(scale_size,scale_size));
|
||||
int scale2 = int((scale_size/6))*2+1;
|
||||
cv::blur(feature_maps[scale_id],high,cv::Size(scale2,scale2));
|
||||
feature_maps[scale_id] = high-0.8*low;
|
||||
}
|
||||
}
|
||||
cv::merge(images,rotated_images[scale_id]);
|
||||
|
||||
// calc feature map
|
||||
calcFeatureMap(rotated_images[scale_id],feature_maps[scale_id]);
|
||||
|
||||
// filter feature map to improve impulse responses
|
||||
if(parameters.filter)
|
||||
{
|
||||
cv::Mat high,low;
|
||||
cv::blur(feature_maps[scale_id],low,cv::Size(scale_size,scale_size));
|
||||
int scale2 = int((scale_size/6))*2+1;
|
||||
cv::blur(feature_maps[scale_id],high,cv::Size(scale2,scale2));
|
||||
feature_maps[scale_id] = high-0.8*low;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FastX::detectImpl(const cv::Mat& image,std::vector<cv::KeyPoint>& keypoints,std::vector<cv::Mat> &feature_maps,const cv::Mat &mask)const
|
||||
@@ -718,7 +719,7 @@ cv::Point2f Ellipse::getCenter()const
|
||||
|
||||
void Ellipse::draw(cv::InputOutputArray img,const cv::Scalar &color)const
|
||||
{
|
||||
cv::ellipse(img,center,axes,360-angle/M_PI*180,0,360,color);
|
||||
cv::ellipse(img,center,axes,360-angle/CV_PI*180,0,360,color);
|
||||
}
|
||||
|
||||
bool Ellipse::contains(const cv::Point2f &pt)const
|
||||
@@ -1078,10 +1079,8 @@ const cv::Point2f* Chessboard::Board::PointIter::operator*()const
|
||||
return cell->bottom_right;
|
||||
case BOTTOM_LEFT:
|
||||
return cell->bottom_left;
|
||||
default:
|
||||
CV_Assert(false);
|
||||
}
|
||||
return NULL;
|
||||
CV_Assert(false);
|
||||
}
|
||||
|
||||
const cv::Point2f* Chessboard::Board::PointIter::operator->()const
|
||||
@@ -1252,10 +1251,8 @@ void Chessboard::Board::draw(cv::InputArray m,cv::OutputArray out,cv::InputArray
|
||||
bool Chessboard::Board::estimatePose(const cv::Size2f &real_size,cv::InputArray _K,cv::OutputArray rvec,cv::OutputArray tvec)const
|
||||
{
|
||||
cv::Mat K = _K.getMat();
|
||||
if(K.type() != CV_64FC1)
|
||||
throw std::runtime_error("wrong K type");
|
||||
if(K.rows != 3|| K.cols != 3)
|
||||
throw std::runtime_error("wrong K size");
|
||||
CV_CheckTypeEQ(K.type(), CV_64FC1, "wrong K type");
|
||||
CV_CheckEQ(K.size(), Size(3, 3), "wrong K size");
|
||||
if(isEmpty())
|
||||
return false;
|
||||
|
||||
@@ -1516,8 +1513,9 @@ void Chessboard::Board::flipVertical()
|
||||
float Chessboard::Board::findMaxPoint(cv::flann::Index &index,const cv::Mat &data,const Ellipse &ellipse,float white_angle,float black_angle,cv::Point2f &point)
|
||||
{
|
||||
// flann data type enriched with angles (third column)
|
||||
if(data.type() != CV_32FC1 || data.cols != 4)
|
||||
CV_Error(Error::StsBadArg,"type of flann data is not supported. Expect CV_32FC1");
|
||||
CV_CheckType(data.type(), CV_32FC1, "type of flann data is not supported");
|
||||
CV_CheckEQ(data.cols, 4, "4-cols flann data is expected");
|
||||
|
||||
std::vector<float> query,dists;
|
||||
std::vector<int> indices;
|
||||
query.resize(2);
|
||||
@@ -1536,15 +1534,15 @@ float Chessboard::Board::findMaxPoint(cv::flann::Index &index,const cv::Mat &dat
|
||||
if(response < best_score)
|
||||
continue;
|
||||
const float &a0 = *(val+2);
|
||||
float a1 = fabs(a0-white_angle);
|
||||
float a2 = fabs(a0-black_angle);
|
||||
if(a1 > M_PI*0.5)
|
||||
a1= float(fabs(a1-M_PI));
|
||||
if(a2> M_PI*0.5)
|
||||
a2= float(fabs(a2-M_PI));
|
||||
float a1 = std::fabs(a0-white_angle);
|
||||
float a2 = std::fabs(a0-black_angle);
|
||||
if(a1 > CV_PI*0.5)
|
||||
a1 = std::fabs(float(a1-CV_PI));
|
||||
if(a2> CV_PI*0.5)
|
||||
a2 = std::fabs(float(a2-CV_PI));
|
||||
if(a1 < MAX_ANGLE || a2 < MAX_ANGLE )
|
||||
{
|
||||
cv::Point2f pt(*val,*(val+1));
|
||||
cv::Point2f pt(val[0], val[1]);
|
||||
if(point.x != point.x) // NaN check
|
||||
point = pt;
|
||||
if(best_score < response && ellipse.contains(pt))
|
||||
@@ -1784,7 +1782,7 @@ bool Chessboard::Board::estimateSearchArea(const cv::Point2f &p1,const cv::Point
|
||||
n = n/norm;
|
||||
float angle = acos(n.x);
|
||||
if(n.y > 0)
|
||||
angle = float(2.0F*M_PI-angle);
|
||||
angle = float(2.0F*CV_PI-angle);
|
||||
n = p4-p3;
|
||||
norm = float(cv::norm(n));
|
||||
double delta = std::max(3.0F,p*norm);
|
||||
@@ -1865,6 +1863,7 @@ cv::Point2f &Chessboard::Board::getCorner(int _row,int _col)
|
||||
}while(_row);
|
||||
}
|
||||
CV_Error(Error::StsInternal,"cannot find corner");
|
||||
// return *top_left->top_left; // never reached
|
||||
}
|
||||
|
||||
bool Chessboard::Board::isCellBlack(int row,int col)const
|
||||
@@ -2790,7 +2789,7 @@ void Chessboard::findKeyPoints(const cv::Mat& image, std::vector<KeyPoint>& keyp
|
||||
|
||||
para.branches = 2; // this is always the case for checssboard corners
|
||||
para.strength = 10; // minimal threshold
|
||||
para.resolution = float(M_PI*0.25); // this gives the best results taking interpolation into account
|
||||
para.resolution = float(CV_PI*0.25); // this gives the best results taking interpolation into account
|
||||
para.filter = 1;
|
||||
para.super_resolution = parameters.super_resolution;
|
||||
para.min_scale = parameters.min_scale;
|
||||
@@ -2841,7 +2840,7 @@ cv::Mat Chessboard::buildData(const std::vector<KeyPoint>& keypoints)const
|
||||
{
|
||||
(*val++) = iter->pt.x;
|
||||
(*val++) = iter->pt.y;
|
||||
(*val++) = float(2.0*M_PI-iter->angle/180.0*M_PI);
|
||||
(*val++) = float(2.0*CV_PI-iter->angle/180.0*CV_PI);
|
||||
(*val++) = iter->response;
|
||||
}
|
||||
return data;
|
||||
@@ -2871,13 +2870,13 @@ std::vector<cv::KeyPoint> Chessboard::getInitialPoints(cv::flann::Index &flann_i
|
||||
continue;
|
||||
const float &angle = data.at<float>(*ids_iter,2);
|
||||
float angle_temp = fabs(angle-white_angle);
|
||||
if(angle_temp > M_PI*0.5)
|
||||
angle_temp = float(fabs(angle_temp-M_PI));
|
||||
if(angle_temp > CV_PI*0.5)
|
||||
angle_temp = float(fabs(angle_temp-CV_PI));
|
||||
if(angle_temp > MAX_ANGLE)
|
||||
{
|
||||
angle_temp = fabs(angle-black_angle);
|
||||
if(angle_temp > M_PI*0.5)
|
||||
angle_temp = float(fabs(angle_temp-M_PI));
|
||||
if(angle_temp > CV_PI*0.5)
|
||||
angle_temp = float(fabs(angle_temp-CV_PI));
|
||||
if(angle_temp >MAX_ANGLE)
|
||||
continue;
|
||||
}
|
||||
@@ -3008,11 +3007,6 @@ Chessboard::Board Chessboard::detectImpl(const Mat& gray,std::vector<cv::Mat> &f
|
||||
#endif
|
||||
CV_CheckTypeEQ(gray.type(),CV_8UC1, "Unsupported image type");
|
||||
|
||||
//TODO is this needed?
|
||||
// double min,max;
|
||||
// cv::minMaxLoc(gray,&min,&max);
|
||||
// gray = (gray-min)*(255.0/(max-min));
|
||||
|
||||
cv::Size chessboard_size2(parameters.chessboard_size.height,parameters.chessboard_size.width);
|
||||
std::vector<KeyPoint> keypoints_seed;
|
||||
std::vector<std::vector<float> > angles;
|
||||
@@ -3025,17 +3019,15 @@ Chessboard::Board Chessboard::detectImpl(const Mat& gray,std::vector<cv::Mat> &f
|
||||
std::vector<KeyPoint>::const_iterator seed_iter = keypoints_seed.begin();
|
||||
int count = 0;
|
||||
int inum = chessboard_size2.width*chessboard_size2.height;
|
||||
for(;seed_iter != keypoints_seed.end();++seed_iter)
|
||||
for(;seed_iter != keypoints_seed.end() && count < inum;++seed_iter,++count)
|
||||
{
|
||||
if(fabs(seed_iter->response) > response)
|
||||
// points are sorted based on response
|
||||
if(fabs(seed_iter->response) < response)
|
||||
{
|
||||
++count;
|
||||
if(count >= inum)
|
||||
break;
|
||||
seed_iter = keypoints_seed.end();
|
||||
return Chessboard::Board();
|
||||
}
|
||||
}
|
||||
if(seed_iter == keypoints_seed.end())
|
||||
return Chessboard::Board();
|
||||
// just add dummy points or flann will fail during knnSearch
|
||||
if(keypoints_seed.size() < 21)
|
||||
keypoints_seed.resize(21, cv::KeyPoint(-99999.0F,-99999.0F,0.0F,0.0F,0.0F));
|
||||
@@ -3070,60 +3062,71 @@ Chessboard::Board Chessboard::detectImpl(const Mat& gray,std::vector<cv::Mat> &f
|
||||
|
||||
std::vector<Board> boards;
|
||||
generateBoards(flann_index, data,*points_iter,white_angle,black_angle,min_response,gray,boards);
|
||||
std::vector<Chessboard::Board>::iterator iter_boards = boards.begin();
|
||||
for(;iter_boards != boards.end();++iter_boards)
|
||||
{
|
||||
cv::Mat h = iter_boards->estimateHomography();
|
||||
int size = iter_boards->validateCorners(data,flann_index,h,min_response);
|
||||
if(size != 9)
|
||||
continue;
|
||||
if(!iter_boards->validateContour())
|
||||
continue;
|
||||
//grow based on kd-tree
|
||||
iter_boards->grow(data,flann_index);
|
||||
if(!iter_boards->checkUnique())
|
||||
continue;
|
||||
|
||||
// check bounding box
|
||||
std::vector<cv::Point2f> contour = iter_boards->getContour();
|
||||
std::vector<cv::Point2f>::const_iterator iter = contour.begin();
|
||||
for(;iter != contour.end();++iter)
|
||||
parallel_for_(Range(0,(int)boards.size()),[&](const Range& range){
|
||||
for(int i=range.start;i <range.end;++i)
|
||||
{
|
||||
if(!bounding_box.contains(*iter))
|
||||
break;
|
||||
}
|
||||
if(iter != contour.end())
|
||||
continue;
|
||||
|
||||
if(iter_boards->getSize() == parameters.chessboard_size ||
|
||||
iter_boards->getSize() == chessboard_size2)
|
||||
{
|
||||
iter_boards->normalizeOrientation(false);
|
||||
if(iter_boards->getSize() != parameters.chessboard_size)
|
||||
auto iter_boards = boards.begin()+i;
|
||||
cv::Mat h = iter_boards->estimateHomography();
|
||||
int size = iter_boards->validateCorners(data,flann_index,h,min_response);
|
||||
if(size != 9 || !iter_boards->validateContour())
|
||||
{
|
||||
if(iter_boards->isCellBlack(0,0) == iter_boards->isCellBlack(0,int(iter_boards->colCount())-1))
|
||||
iter_boards->rotateLeft();
|
||||
else
|
||||
iter_boards->rotateRight();
|
||||
iter_boards->clear();
|
||||
continue;
|
||||
}
|
||||
//grow based on kd-tree
|
||||
iter_boards->grow(data,flann_index);
|
||||
if(!iter_boards->checkUnique())
|
||||
{
|
||||
iter_boards->clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
// check bounding box
|
||||
std::vector<cv::Point2f> contour = iter_boards->getContour();
|
||||
std::vector<cv::Point2f>::const_iterator iter = contour.begin();
|
||||
for(;iter != contour.end();++iter)
|
||||
{
|
||||
if(!bounding_box.contains(*iter))
|
||||
break;
|
||||
}
|
||||
if(iter != contour.end())
|
||||
{
|
||||
iter_boards->clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(iter_boards->getSize() == parameters.chessboard_size ||
|
||||
iter_boards->getSize() == chessboard_size2)
|
||||
{
|
||||
iter_boards->normalizeOrientation(false);
|
||||
if(iter_boards->getSize() != parameters.chessboard_size)
|
||||
{
|
||||
if(iter_boards->isCellBlack(0,0) == iter_boards->isCellBlack(0,int(iter_boards->colCount())-1))
|
||||
iter_boards->rotateLeft();
|
||||
else
|
||||
iter_boards->rotateRight();
|
||||
}
|
||||
#ifdef CV_DETECTORS_CHESSBOARD_DEBUG
|
||||
cv::Mat img;
|
||||
iter_boards->draw(debug_image,img);
|
||||
cv::imshow("chessboard",img);
|
||||
cv::waitKey(-1);
|
||||
cv::Mat img;
|
||||
iter_boards->draw(debug_image,img);
|
||||
cv::imshow("chessboard",img);
|
||||
cv::waitKey(-1);
|
||||
#endif
|
||||
return *iter_boards;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(iter_boards->getSize().width*iter_boards->getSize().height > chessboard_size2.width*chessboard_size2.height)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(parameters.larger)
|
||||
return *iter_boards;
|
||||
else
|
||||
return Chessboard::Board();
|
||||
if(iter_boards->getSize().width*iter_boards->getSize().height < chessboard_size2.width*chessboard_size2.height)
|
||||
iter_boards->clear();
|
||||
else if(!parameters.larger)
|
||||
iter_boards->clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
// check if a good board was found
|
||||
for(const auto &board : boards)
|
||||
{
|
||||
if(!board.isEmpty())
|
||||
return board;
|
||||
}
|
||||
}
|
||||
return Chessboard::Board();
|
||||
@@ -3152,16 +3155,15 @@ void Chessboard::detectImpl(InputArray image, std::vector<KeyPoint>& keypoints,
|
||||
detectImpl(image.getMat(),keypoints,mask.getMat());
|
||||
}
|
||||
|
||||
}} // end namespace details and cv
|
||||
} // end namespace details
|
||||
|
||||
|
||||
// public API
|
||||
bool cv::findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
|
||||
cv::OutputArray corners_, int flags)
|
||||
bool findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
|
||||
cv::OutputArray corners_, int flags)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
int type = image_.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
Mat img = image_.getMat();
|
||||
CV_CheckType(type, depth == CV_8U && (cn == 1 || cn == 3),
|
||||
"Only 8-bit grayscale or color images are supported");
|
||||
if(pattern_size.width <= 2 || pattern_size.height <= 2)
|
||||
@@ -3170,29 +3172,43 @@ bool cv::findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
|
||||
}
|
||||
if (!corners_.needed())
|
||||
CV_Error(Error::StsNullPtr, "Null pointer to corners");
|
||||
if (img.channels() != 1)
|
||||
cvtColor(img, img, COLOR_BGR2GRAY);
|
||||
|
||||
Mat img;
|
||||
if (image_.channels() != 1)
|
||||
cvtColor(image_, img, COLOR_BGR2GRAY);
|
||||
else
|
||||
img = image_.getMat();
|
||||
|
||||
details::Chessboard::Parameters para;
|
||||
para.chessboard_size = pattern_size;
|
||||
para.min_scale = 2;
|
||||
para.max_scale = 4;
|
||||
para.max_tests = 25;
|
||||
para.max_points = std::max(100,pattern_size.width*pattern_size.height*2);
|
||||
para.super_resolution = false;
|
||||
|
||||
switch(flags)
|
||||
// setup search based on flags
|
||||
if(flags & CALIB_CB_NORMALIZE_IMAGE)
|
||||
{
|
||||
case 1: // high accuracy profile
|
||||
para.min_scale = 2;
|
||||
para.max_scale = 4;
|
||||
para.max_tests = 100;
|
||||
para.super_resolution = true;
|
||||
para.max_points = std::max(500,pattern_size.width*pattern_size.height*2);
|
||||
break;
|
||||
default: // default profile
|
||||
para.min_scale = 2;
|
||||
para.max_scale = 3;
|
||||
para.max_tests = 20;
|
||||
para.max_points = pattern_size.width*pattern_size.height*2;
|
||||
para.super_resolution = false;
|
||||
break;
|
||||
Mat tmp;
|
||||
cv::equalizeHist(img, tmp);
|
||||
swap(img, tmp);
|
||||
flags ^= CALIB_CB_NORMALIZE_IMAGE;
|
||||
}
|
||||
if(flags & CALIB_CB_EXHAUSTIVE)
|
||||
{
|
||||
para.max_tests = 100;
|
||||
para.max_points = std::max(500,pattern_size.width*pattern_size.height*2);
|
||||
flags ^= CALIB_CB_EXHAUSTIVE;
|
||||
}
|
||||
if(flags & CALIB_CB_ACCURACY)
|
||||
{
|
||||
para.super_resolution = true;
|
||||
flags ^= CALIB_CB_ACCURACY;
|
||||
}
|
||||
if(flags)
|
||||
CV_Error(Error::StsOutOfRange, cv::format("Invalid remaing flags %d", (int)flags));
|
||||
|
||||
std::vector<cv::KeyPoint> corners;
|
||||
details::Chessboard board(para);
|
||||
board.detect(img,corners);
|
||||
@@ -3206,3 +3222,5 @@ bool cv::findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
|
||||
Mat(points).copyTo(corners_);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cv
|
||||
|
||||
@@ -32,7 +32,7 @@ class FastX : public cv::Feature2D
|
||||
Parameters()
|
||||
{
|
||||
strength = 40;
|
||||
resolution = float(M_PI*0.25);
|
||||
resolution = float(CV_PI*0.25);
|
||||
branches = 2;
|
||||
min_scale = 2;
|
||||
max_scale = 5;
|
||||
|
||||
@@ -534,7 +534,7 @@ void cv::fisheye::undistortImage(InputArray distorted, OutputArray undistorted,
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Size size = new_size.area() != 0 ? new_size : distorted.size();
|
||||
Size size = !new_size.empty() ? new_size : distorted.size();
|
||||
|
||||
cv::Mat map1, map2;
|
||||
fisheye::initUndistortRectifyMap(K, D, cv::Matx33d::eye(), Knew, size, CV_16SC2, map1, map2 );
|
||||
@@ -601,7 +601,7 @@ void cv::fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, Input
|
||||
new_f[1] /= aspect_ratio;
|
||||
new_c[1] /= aspect_ratio;
|
||||
|
||||
if (new_size.area() > 0)
|
||||
if (!new_size.empty())
|
||||
{
|
||||
double rx = new_size.width /(double)image_size.width;
|
||||
double ry = new_size.height/(double)image_size.height;
|
||||
|
||||
@@ -1226,8 +1226,8 @@ public:
|
||||
parallel_for_(Range(0, 2), PrefilterInvoker(left0, right0, left, right, _buf, _buf + bufSize1, ¶ms), 1);
|
||||
|
||||
Rect validDisparityRect(0, 0, width, height), R1 = params.roi1, R2 = params.roi2;
|
||||
validDisparityRect = getValidDisparityROI(R1.area() > 0 ? R1 : validDisparityRect,
|
||||
R2.area() > 0 ? R2 : validDisparityRect,
|
||||
validDisparityRect = getValidDisparityROI(!R1.empty() ? R1 : validDisparityRect,
|
||||
!R2.empty() ? R2 : validDisparityRect,
|
||||
params.minDisparity, params.numDisparities,
|
||||
params.SADWindowSize);
|
||||
|
||||
|
||||
@@ -41,9 +41,11 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/imgproc/detail/distortion_model.hpp"
|
||||
#include "distortion_model.hpp"
|
||||
#include "undistort.hpp"
|
||||
|
||||
#include "opencv2/calib3d/calib3d_c.h"
|
||||
|
||||
cv::Mat cv::getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
|
||||
bool centerPrincipalPoint )
|
||||
{
|
||||
@@ -534,29 +536,31 @@ static void cvUndistortPointsInternal( const CvMat* _src, CvMat* _dst, const CvM
|
||||
}
|
||||
}
|
||||
|
||||
void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
|
||||
const CvMat* _distCoeffs,
|
||||
const CvMat* matR, const CvMat* matP )
|
||||
void cvUndistortPoints(const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
|
||||
const CvMat* _distCoeffs,
|
||||
const CvMat* matR, const CvMat* matP)
|
||||
{
|
||||
cvUndistortPointsInternal(_src, _dst, _cameraMatrix, _distCoeffs, matR, matP,
|
||||
cv::TermCriteria(cv::TermCriteria::COUNT, 5, 0.01));
|
||||
}
|
||||
|
||||
void cv::undistortPoints( InputArray _src, OutputArray _dst,
|
||||
InputArray _cameraMatrix,
|
||||
InputArray _distCoeffs,
|
||||
InputArray _Rmat,
|
||||
InputArray _Pmat )
|
||||
namespace cv {
|
||||
|
||||
void undistortPoints(InputArray _src, OutputArray _dst,
|
||||
InputArray _cameraMatrix,
|
||||
InputArray _distCoeffs,
|
||||
InputArray _Rmat,
|
||||
InputArray _Pmat)
|
||||
{
|
||||
undistortPoints(_src, _dst, _cameraMatrix, _distCoeffs, _Rmat, _Pmat, TermCriteria(TermCriteria::MAX_ITER, 5, 0.01));
|
||||
}
|
||||
|
||||
void cv::undistortPoints( InputArray _src, OutputArray _dst,
|
||||
InputArray _cameraMatrix,
|
||||
InputArray _distCoeffs,
|
||||
InputArray _Rmat,
|
||||
InputArray _Pmat,
|
||||
TermCriteria criteria)
|
||||
void undistortPoints(InputArray _src, OutputArray _dst,
|
||||
InputArray _cameraMatrix,
|
||||
InputArray _distCoeffs,
|
||||
InputArray _Rmat,
|
||||
InputArray _Pmat,
|
||||
TermCriteria criteria)
|
||||
{
|
||||
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
|
||||
Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
|
||||
@@ -578,10 +582,7 @@ void cv::undistortPoints( InputArray _src, OutputArray _dst,
|
||||
cvUndistortPointsInternal(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP, criteria);
|
||||
}
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int projType)
|
||||
static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, enum UndistortTypes projType)
|
||||
{
|
||||
double x = p.x, y = p.y;
|
||||
double beta = 1 + 2*alpha;
|
||||
@@ -613,11 +614,11 @@ static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int pr
|
||||
}
|
||||
return Point2f((float)asin(x1), (float)asin(y1));
|
||||
}
|
||||
CV_Error(CV_StsBadArg, "Unknown projection type");
|
||||
CV_Error(Error::StsBadArg, "Unknown projection type");
|
||||
}
|
||||
|
||||
|
||||
static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
|
||||
static Point2f invMapPointSpherical(Point2f _p, float alpha, enum UndistortTypes projType)
|
||||
{
|
||||
double eps = 1e-12;
|
||||
Vec2d p(_p.x, _p.y), q(_p.x, _p.y), err;
|
||||
@@ -646,11 +647,10 @@ static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
|
||||
return i < maxiter ? Point2f((float)q[0], (float)q[1]) : Point2f(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeffs0,
|
||||
Size imageSize, int destImageWidth, int m1type,
|
||||
OutputArray _map1, OutputArray _map2, int projType, double _alpha )
|
||||
float initWideAngleProjMap(InputArray _cameraMatrix0, InputArray _distCoeffs0,
|
||||
Size imageSize, int destImageWidth, int m1type,
|
||||
OutputArray _map1, OutputArray _map2,
|
||||
enum UndistortTypes projType, double _alpha)
|
||||
{
|
||||
Mat cameraMatrix0 = _cameraMatrix0.getMat(), distCoeffs0 = _distCoeffs0.getMat();
|
||||
double k[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, M[9]={0,0,0,0,0,0,0,0,0};
|
||||
@@ -735,4 +735,5 @@ float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeff
|
||||
return scale;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
/* End of file */
|
||||
@@ -40,8 +40,8 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef OPENCV_IMGPROC_UNDISTORT_HPP
|
||||
#define OPENCV_IMGPROC_UNDISTORT_HPP
|
||||
#ifndef OPENCV_CALIB3D_UNDISTORT_HPP
|
||||
#define OPENCV_CALIB3D_UNDISTORT_HPP
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -54,6 +54,6 @@ namespace cv
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // OPENCV_CALIB3D_UNDISTORT_HPP
|
||||
|
||||
/* End of file */
|
||||
@@ -409,6 +409,8 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
|
||||
int progress = 0;
|
||||
for(int i = 0; i < test_num; ++i)
|
||||
{
|
||||
SCOPED_TRACE(cv::format("test_num=%d", test_num));
|
||||
|
||||
progress = update_progress( progress, i, test_num, 0 );
|
||||
ChessBoardGenerator cbg(sizes[i % sizes_num]);
|
||||
|
||||
@@ -439,13 +441,17 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
|
||||
}
|
||||
|
||||
double err = calcErrorMinError(cbg.cornersSize(), corners_found, corners_generated);
|
||||
if( err > rough_success_error_level )
|
||||
EXPECT_LE(err, rough_success_error_level) << "bad accuracy of corner guesses";
|
||||
#if 0
|
||||
if (err >= rough_success_error_level)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "bad accuracy of corner guesses" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
|
||||
res = false;
|
||||
return res;
|
||||
imshow("cb", cb);
|
||||
Mat cb_corners = cb.clone();
|
||||
cv::drawChessboardCorners(cb_corners, cbg.cornersSize(), Mat(corners_found), found);
|
||||
imshow("corners", cb_corners);
|
||||
waitKey(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ***** negative ***** */
|
||||
@@ -566,7 +572,7 @@ bool CV_ChessboardDetectorTest::checkByGeneratorHighAccuracy()
|
||||
for(int i=15;i<90;i=i+15)
|
||||
{
|
||||
// project 3d points to new camera
|
||||
Vec3f rvec(0.0F,0.05F,float(float(i)/180.0*M_PI));
|
||||
Vec3f rvec(0.0F,0.05F,float(float(i)/180.0*CV_PI));
|
||||
Vec3f tvec(0,0,0);
|
||||
cv::Mat k = (cv::Mat_<double>(3,3) << fx/2,0,center.x*2, 0,fy/2,center.y, 0,0,1);
|
||||
cv::projectPoints(pts3d,rvec,tvec,k,cv::Mat(),pts2_all);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/calib3d/calib3d_c.h"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
@@ -938,4 +939,584 @@ TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest t
|
||||
TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); }
|
||||
TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); }
|
||||
|
||||
////////////////////////////// undistort /////////////////////////////////
|
||||
|
||||
static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy,
|
||||
Mat* mask=0, int interpolation=CV_INTER_LINEAR )
|
||||
{
|
||||
int x, y, k;
|
||||
int drows = dst.rows, dcols = dst.cols;
|
||||
int srows = src.rows, scols = src.cols;
|
||||
const uchar* sptr0 = src.ptr();
|
||||
int depth = src.depth(), cn = src.channels();
|
||||
int elem_size = (int)src.elemSize();
|
||||
int step = (int)(src.step / CV_ELEM_SIZE(depth));
|
||||
int delta;
|
||||
|
||||
if( interpolation != CV_INTER_CUBIC )
|
||||
{
|
||||
delta = 0;
|
||||
scols -= 1; srows -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = 1;
|
||||
scols = MAX(scols - 3, 0);
|
||||
srows = MAX(srows - 3, 0);
|
||||
}
|
||||
|
||||
int scols1 = MAX(scols - 2, 0);
|
||||
int srows1 = MAX(srows - 2, 0);
|
||||
|
||||
if( mask )
|
||||
*mask = Scalar::all(0);
|
||||
|
||||
for( y = 0; y < drows; y++ )
|
||||
{
|
||||
uchar* dptr = dst.ptr(y);
|
||||
const float* mx = mapx.ptr<float>(y);
|
||||
const float* my = mapy.ptr<float>(y);
|
||||
uchar* m = mask ? mask->ptr(y) : 0;
|
||||
|
||||
for( x = 0; x < dcols; x++, dptr += elem_size )
|
||||
{
|
||||
float xs = mx[x];
|
||||
float ys = my[x];
|
||||
int ixs = cvFloor(xs);
|
||||
int iys = cvFloor(ys);
|
||||
|
||||
if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 ||
|
||||
(unsigned)(iys - delta - 1) >= (unsigned)srows1 )
|
||||
{
|
||||
if( m )
|
||||
m[x] = 1;
|
||||
if( (unsigned)(ixs - delta) >= (unsigned)scols ||
|
||||
(unsigned)(iys - delta) >= (unsigned)srows )
|
||||
continue;
|
||||
}
|
||||
|
||||
xs -= ixs;
|
||||
ys -= iys;
|
||||
|
||||
switch( depth )
|
||||
{
|
||||
case CV_8U:
|
||||
{
|
||||
const uchar* sptr = sptr0 + iys*step + ixs*cn;
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
float v00 = sptr[k];
|
||||
float v01 = sptr[cn + k];
|
||||
float v10 = sptr[step + k];
|
||||
float v11 = sptr[step + cn + k];
|
||||
|
||||
v00 = v00 + xs*(v01 - v00);
|
||||
v10 = v10 + xs*(v11 - v10);
|
||||
v00 = v00 + ys*(v10 - v00);
|
||||
dptr[k] = (uchar)cvRound(v00);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CV_16U:
|
||||
{
|
||||
const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn;
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
float v00 = sptr[k];
|
||||
float v01 = sptr[cn + k];
|
||||
float v10 = sptr[step + k];
|
||||
float v11 = sptr[step + cn + k];
|
||||
|
||||
v00 = v00 + xs*(v01 - v00);
|
||||
v10 = v10 + xs*(v11 - v10);
|
||||
v00 = v00 + ys*(v10 - v00);
|
||||
((ushort*)dptr)[k] = (ushort)cvRound(v00);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CV_32F:
|
||||
{
|
||||
const float* sptr = (const float*)sptr0 + iys*step + ixs*cn;
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
float v00 = sptr[k];
|
||||
float v01 = sptr[cn + k];
|
||||
float v10 = sptr[step + k];
|
||||
float v11 = sptr[step + cn + k];
|
||||
|
||||
v00 = v00 + xs*(v01 - v00);
|
||||
v10 = v10 + xs*(v11 - v10);
|
||||
v00 = v00 + ys*(v10 - v00);
|
||||
((float*)dptr)[k] = (float)v00;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CV_ImgWarpBaseTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_ImgWarpBaseTest( bool warp_matrix );
|
||||
|
||||
protected:
|
||||
int read_params( CvFileStorage* fs );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
|
||||
void fill_array( int test_case_idx, int i, int j, Mat& arr );
|
||||
|
||||
int interpolation;
|
||||
int max_interpolation;
|
||||
double spatial_scale_zoom, spatial_scale_decimate;
|
||||
};
|
||||
|
||||
|
||||
CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
if( warp_matrix )
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT_OUTPUT].push_back(NULL);
|
||||
test_array[REF_INPUT_OUTPUT].push_back(NULL);
|
||||
max_interpolation = 5;
|
||||
interpolation = 0;
|
||||
element_wise_relative_error = false;
|
||||
spatial_scale_zoom = 0.01;
|
||||
spatial_scale_decimate = 0.005;
|
||||
}
|
||||
|
||||
|
||||
int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )
|
||||
{
|
||||
int code = cvtest::ArrayTest::read_params( fs );
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
|
||||
{
|
||||
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
|
||||
if( CV_MAT_DEPTH(type) == CV_32F )
|
||||
{
|
||||
low = Scalar::all(-10.);
|
||||
high = Scalar::all(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int depth = cvtest::randInt(rng) % 3;
|
||||
int cn = cvtest::randInt(rng) % 3 + 1;
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F;
|
||||
cn += cn == 2;
|
||||
|
||||
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn);
|
||||
if( test_array[INPUT].size() > 1 )
|
||||
types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1;
|
||||
|
||||
interpolation = cvtest::randInt(rng) % max_interpolation;
|
||||
}
|
||||
|
||||
|
||||
void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
|
||||
{
|
||||
if( i != INPUT || j != 0 )
|
||||
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
|
||||
}
|
||||
|
||||
int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
Mat& img = test_mat[INPUT][0];
|
||||
int i, j, cols = img.cols;
|
||||
int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
double scale = depth == CV_16U ? 1000. : 255.*0.5;
|
||||
double space_scale = spatial_scale_decimate;
|
||||
vector<float> buffer(img.cols*cn);
|
||||
|
||||
if( code <= 0 )
|
||||
return code;
|
||||
|
||||
if( test_mat[INPUT_OUTPUT][0].cols >= img.cols &&
|
||||
test_mat[INPUT_OUTPUT][0].rows >= img.rows )
|
||||
space_scale = spatial_scale_zoom;
|
||||
|
||||
for( i = 0; i < img.rows; i++ )
|
||||
{
|
||||
uchar* ptr = img.ptr(i);
|
||||
switch( cn )
|
||||
{
|
||||
case 1:
|
||||
for( j = 0; j < cols; j++ )
|
||||
buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale);
|
||||
break;
|
||||
case 2:
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale);
|
||||
buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale);
|
||||
buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale);
|
||||
buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for( j = 0; j < cols; j++ )
|
||||
{
|
||||
buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale);
|
||||
buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale);
|
||||
buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
|
||||
buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*switch( depth )
|
||||
{
|
||||
case CV_8U:
|
||||
for( j = 0; j < cols*cn; j++ )
|
||||
ptr[j] = (uchar)cvRound(buffer[j]);
|
||||
break;
|
||||
case CV_16U:
|
||||
for( j = 0; j < cols*cn; j++ )
|
||||
((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]);
|
||||
break;
|
||||
case CV_32F:
|
||||
for( j = 0; j < cols*cn; j++ )
|
||||
((float*)ptr)[j] = (float)buffer[j];
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}*/
|
||||
cv::Mat src(1, cols*cn, CV_32F, &buffer[0]);
|
||||
cv::Mat dst(1, cols*cn, depth, ptr);
|
||||
src.convertTo(dst, dst.type());
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
class CV_UndistortTest : public CV_ImgWarpBaseTest
|
||||
{
|
||||
public:
|
||||
CV_UndistortTest();
|
||||
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
void run_func();
|
||||
int prepare_test_case( int test_case_idx );
|
||||
void prepare_to_validation( int /*test_case_idx*/ );
|
||||
double get_success_error_level( int test_case_idx, int i, int j );
|
||||
void fill_array( int test_case_idx, int i, int j, Mat& arr );
|
||||
|
||||
private:
|
||||
bool useCPlus;
|
||||
cv::Mat input0;
|
||||
cv::Mat input1;
|
||||
cv::Mat input2;
|
||||
cv::Mat input_new_cam;
|
||||
cv::Mat input_output;
|
||||
|
||||
bool zero_new_cam;
|
||||
bool zero_distortion;
|
||||
};
|
||||
|
||||
|
||||
CV_UndistortTest::CV_UndistortTest() : CV_ImgWarpBaseTest( false )
|
||||
{
|
||||
//spatial_scale_zoom = spatial_scale_decimate;
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT].push_back(NULL);
|
||||
|
||||
spatial_scale_decimate = spatial_scale_zoom;
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
int type = types[INPUT][0];
|
||||
type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) );
|
||||
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type;
|
||||
types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
|
||||
types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
|
||||
sizes[INPUT][1] = cvSize(3,3);
|
||||
sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
|
||||
types[INPUT][3] = types[INPUT][1];
|
||||
sizes[INPUT][3] = sizes[INPUT][1];
|
||||
interpolation = CV_INTER_LINEAR;
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
|
||||
{
|
||||
if( i != INPUT )
|
||||
CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortTest::run_func()
|
||||
{
|
||||
if (!useCPlus)
|
||||
{
|
||||
CvMat a = cvMat(test_mat[INPUT][1]), k = cvMat(test_mat[INPUT][2]);
|
||||
cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zero_distortion)
|
||||
{
|
||||
cv::undistort(input0,input_output,input1,cv::Mat());
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::undistort(input0,input_output,input1,input2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double CV_UndistortTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
int depth = test_mat[INPUT][0].depth();
|
||||
return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
|
||||
}
|
||||
|
||||
|
||||
int CV_UndistortTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
|
||||
|
||||
const Mat& src = test_mat[INPUT][0];
|
||||
double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
|
||||
double new_cam[9] = {0,0,0,0,0,0,0,0,1};
|
||||
double sz = MAX(src.rows, src.cols);
|
||||
|
||||
Mat& _new_cam0 = test_mat[INPUT][3];
|
||||
Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam);
|
||||
Mat& _a0 = test_mat[INPUT][1];
|
||||
Mat _a(3,3,CV_64F,a);
|
||||
Mat& _k0 = test_mat[INPUT][2];
|
||||
Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);
|
||||
|
||||
if( code <= 0 )
|
||||
return code;
|
||||
|
||||
double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
|
||||
a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
|
||||
a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
|
||||
a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
|
||||
a[4] = aspect_ratio*a[0];
|
||||
k[0] = cvtest::randReal(rng)*0.06 - 0.03;
|
||||
k[1] = cvtest::randReal(rng)*0.06 - 0.03;
|
||||
if( k[0]*k[1] > 0 )
|
||||
k[1] = -k[1];
|
||||
if( cvtest::randInt(rng)%4 != 0 )
|
||||
{
|
||||
k[2] = cvtest::randReal(rng)*0.004 - 0.002;
|
||||
k[3] = cvtest::randReal(rng)*0.004 - 0.002;
|
||||
}
|
||||
else
|
||||
k[2] = k[3] = 0;
|
||||
|
||||
new_cam[0] = a[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[0]; //10%
|
||||
new_cam[4] = a[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[4]; //10%
|
||||
new_cam[2] = a[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].rows; //15%
|
||||
new_cam[5] = a[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].cols; //15%
|
||||
|
||||
_a.convertTo(_a0, _a0.depth());
|
||||
|
||||
zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;
|
||||
_k.convertTo(_k0, _k0.depth());
|
||||
|
||||
zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;
|
||||
_new_cam.convertTo(_new_cam0, _new_cam0.depth());
|
||||
|
||||
//Testing C++ code
|
||||
useCPlus = ((cvtest::randInt(rng) % 2)!=0);
|
||||
if (useCPlus)
|
||||
{
|
||||
input0 = test_mat[INPUT][0];
|
||||
input1 = test_mat[INPUT][1];
|
||||
input2 = test_mat[INPUT][2];
|
||||
input_new_cam = test_mat[INPUT][3];
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
if (useCPlus)
|
||||
{
|
||||
Mat& output = test_mat[INPUT_OUTPUT][0];
|
||||
input_output.convertTo(output, output.type());
|
||||
}
|
||||
Mat& src = test_mat[INPUT][0];
|
||||
Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
|
||||
Mat& dst0 = test_mat[INPUT_OUTPUT][0];
|
||||
Mat mapx, mapy;
|
||||
cvtest::initUndistortMap( test_mat[INPUT][1], test_mat[INPUT][2], dst.size(), mapx, mapy );
|
||||
Mat mask( dst.size(), CV_8U );
|
||||
test_remap( src, dst, mapx, mapy, &mask, interpolation );
|
||||
dst.setTo(Scalar::all(0), mask);
|
||||
dst0.setTo(Scalar::all(0), mask);
|
||||
}
|
||||
|
||||
|
||||
class CV_UndistortMapTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_UndistortMapTest();
|
||||
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
void run_func();
|
||||
int prepare_test_case( int test_case_idx );
|
||||
void prepare_to_validation( int /*test_case_idx*/ );
|
||||
double get_success_error_level( int test_case_idx, int i, int j );
|
||||
void fill_array( int test_case_idx, int i, int j, Mat& arr );
|
||||
|
||||
private:
|
||||
bool dualChannel;
|
||||
};
|
||||
|
||||
|
||||
CV_UndistortMapTest::CV_UndistortMapTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
|
||||
element_wise_relative_error = false;
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortMapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
int depth = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
|
||||
|
||||
Size sz = sizes[OUTPUT][0];
|
||||
types[INPUT][0] = types[INPUT][1] = depth;
|
||||
dualChannel = cvtest::randInt(rng)%2 == 0;
|
||||
types[OUTPUT][0] = types[OUTPUT][1] =
|
||||
types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F;
|
||||
sizes[INPUT][0] = cvSize(3,3);
|
||||
sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
|
||||
|
||||
sz.width = MAX(sz.width,16);
|
||||
sz.height = MAX(sz.height,16);
|
||||
sizes[OUTPUT][0] = sizes[OUTPUT][1] =
|
||||
sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = sz;
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortMapTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
|
||||
{
|
||||
if( i != INPUT )
|
||||
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortMapTest::run_func()
|
||||
{
|
||||
CvMat a = cvMat(test_mat[INPUT][0]), k = cvMat(test_mat[INPUT][1]);
|
||||
|
||||
if (!dualChannel )
|
||||
cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] );
|
||||
else
|
||||
cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 );
|
||||
}
|
||||
|
||||
|
||||
double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
|
||||
{
|
||||
return 1e-3;
|
||||
}
|
||||
|
||||
|
||||
int CV_UndistortMapTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
const Mat& mapx = test_mat[OUTPUT][0];
|
||||
double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
|
||||
double sz = MAX(mapx.rows, mapx.cols);
|
||||
Mat& _a0 = test_mat[INPUT][0], &_k0 = test_mat[INPUT][1];
|
||||
Mat _a(3,3,CV_64F,a);
|
||||
Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);
|
||||
|
||||
if( code <= 0 )
|
||||
return code;
|
||||
|
||||
double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
|
||||
a[2] = (mapx.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
|
||||
a[5] = (mapx.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
|
||||
a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
|
||||
a[4] = aspect_ratio*a[0];
|
||||
k[0] = cvtest::randReal(rng)*0.06 - 0.03;
|
||||
k[1] = cvtest::randReal(rng)*0.06 - 0.03;
|
||||
if( k[0]*k[1] > 0 )
|
||||
k[1] = -k[1];
|
||||
k[2] = cvtest::randReal(rng)*0.004 - 0.002;
|
||||
k[3] = cvtest::randReal(rng)*0.004 - 0.002;
|
||||
|
||||
_a.convertTo(_a0, _a0.depth());
|
||||
_k.convertTo(_k0, _k0.depth());
|
||||
|
||||
if (dualChannel)
|
||||
{
|
||||
test_mat[REF_OUTPUT][1] = Scalar::all(0);
|
||||
test_mat[OUTPUT][1] = Scalar::all(0);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void CV_UndistortMapTest::prepare_to_validation( int )
|
||||
{
|
||||
Mat mapx, mapy;
|
||||
cvtest::initUndistortMap( test_mat[INPUT][0], test_mat[INPUT][1], test_mat[REF_OUTPUT][0].size(), mapx, mapy );
|
||||
if( !dualChannel )
|
||||
{
|
||||
mapx.copyTo(test_mat[REF_OUTPUT][0]);
|
||||
mapy.copyTo(test_mat[REF_OUTPUT][1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mat p[2] = {mapx, mapy};
|
||||
cv::merge(p, 2, test_mat[REF_OUTPUT][0]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }
|
||||
TEST(Calib3d_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); }
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/calib3d/calib3d_c.h"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
|
||||
@@ -81,10 +81,6 @@ if(HAVE_HPX)
|
||||
ocv_target_link_libraries(${the_module} LINK_PRIVATE "${HPX_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDA)
|
||||
ocv_target_compile_definitions(${the_module} PUBLIC OPENCV_TRAITS_ENABLE_DEPRECATED)
|
||||
endif()
|
||||
|
||||
ocv_add_accuracy_tests()
|
||||
ocv_add_perf_tests()
|
||||
|
||||
|
||||
@@ -415,8 +415,13 @@ The function cv::divide divides one array by another:
|
||||
or a scalar by an array when there is no src1 :
|
||||
\f[\texttt{dst(I) = saturate(scale/src2(I))}\f]
|
||||
|
||||
When src2(I) is zero, dst(I) will also be zero. Different channels of
|
||||
multi-channel arrays are processed independently.
|
||||
Different channels of multi-channel arrays are processed independently.
|
||||
|
||||
For integer types when src2(I) is zero, dst(I) will also be zero.
|
||||
|
||||
@note In case of floating point data there is no special defined behavior for zero src2(I) values.
|
||||
Regular floating-point division is used.
|
||||
Expect correct IEEE-754 behaviour for floating-point data (with NaN, Inf result values).
|
||||
|
||||
@note Saturation is not applied when the output array has the depth CV_32S. You may even get
|
||||
result of an incorrect sign in the case of overflow.
|
||||
@@ -2997,7 +3002,8 @@ public:
|
||||
class CV_EXPORTS Formatter
|
||||
{
|
||||
public:
|
||||
enum { FMT_DEFAULT = 0,
|
||||
enum FormatType {
|
||||
FMT_DEFAULT = 0,
|
||||
FMT_MATLAB = 1,
|
||||
FMT_CSV = 2,
|
||||
FMT_PYTHON = 3,
|
||||
@@ -3014,7 +3020,7 @@ public:
|
||||
virtual void set64fPrecision(int p = 16) = 0;
|
||||
virtual void setMultiline(bool ml = true) = 0;
|
||||
|
||||
static Ptr<Formatter> get(int fmt = FMT_DEFAULT);
|
||||
static Ptr<Formatter> get(Formatter::FormatType fmt = FMT_DEFAULT);
|
||||
|
||||
};
|
||||
|
||||
@@ -3037,7 +3043,7 @@ String& operator << (String& out, const Mat& mtx)
|
||||
|
||||
class CV_EXPORTS Algorithm;
|
||||
|
||||
template<typename _Tp> struct ParamType {};
|
||||
template<typename _Tp, typename _EnumTp = void> struct ParamType {};
|
||||
|
||||
|
||||
/** @brief This is a base class for all more or less complex algorithms in OpenCV
|
||||
@@ -3150,9 +3156,9 @@ protected:
|
||||
void writeFormat(FileStorage& fs) const;
|
||||
};
|
||||
|
||||
struct Param {
|
||||
enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7,
|
||||
UNSIGNED_INT=8, UINT64=9, UCHAR=11, SCALAR=12 };
|
||||
enum struct Param {
|
||||
INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7,
|
||||
UNSIGNED_INT=8, UINT64=9, UCHAR=11, SCALAR=12
|
||||
};
|
||||
|
||||
|
||||
@@ -3162,7 +3168,7 @@ template<> struct ParamType<bool>
|
||||
typedef bool const_param_type;
|
||||
typedef bool member_type;
|
||||
|
||||
enum { type = Param::BOOLEAN };
|
||||
static const Param type = Param::BOOLEAN;
|
||||
};
|
||||
|
||||
template<> struct ParamType<int>
|
||||
@@ -3170,7 +3176,7 @@ template<> struct ParamType<int>
|
||||
typedef int const_param_type;
|
||||
typedef int member_type;
|
||||
|
||||
enum { type = Param::INT };
|
||||
static const Param type = Param::INT;
|
||||
};
|
||||
|
||||
template<> struct ParamType<double>
|
||||
@@ -3178,7 +3184,7 @@ template<> struct ParamType<double>
|
||||
typedef double const_param_type;
|
||||
typedef double member_type;
|
||||
|
||||
enum { type = Param::REAL };
|
||||
static const Param type = Param::REAL;
|
||||
};
|
||||
|
||||
template<> struct ParamType<String>
|
||||
@@ -3186,7 +3192,7 @@ template<> struct ParamType<String>
|
||||
typedef const String& const_param_type;
|
||||
typedef String member_type;
|
||||
|
||||
enum { type = Param::STRING };
|
||||
static const Param type = Param::STRING;
|
||||
};
|
||||
|
||||
template<> struct ParamType<Mat>
|
||||
@@ -3194,7 +3200,7 @@ template<> struct ParamType<Mat>
|
||||
typedef const Mat& const_param_type;
|
||||
typedef Mat member_type;
|
||||
|
||||
enum { type = Param::MAT };
|
||||
static const Param type = Param::MAT;
|
||||
};
|
||||
|
||||
template<> struct ParamType<std::vector<Mat> >
|
||||
@@ -3202,7 +3208,7 @@ template<> struct ParamType<std::vector<Mat> >
|
||||
typedef const std::vector<Mat>& const_param_type;
|
||||
typedef std::vector<Mat> member_type;
|
||||
|
||||
enum { type = Param::MAT_VECTOR };
|
||||
static const Param type = Param::MAT_VECTOR;
|
||||
};
|
||||
|
||||
template<> struct ParamType<Algorithm>
|
||||
@@ -3210,7 +3216,7 @@ template<> struct ParamType<Algorithm>
|
||||
typedef const Ptr<Algorithm>& const_param_type;
|
||||
typedef Ptr<Algorithm> member_type;
|
||||
|
||||
enum { type = Param::ALGORITHM };
|
||||
static const Param type = Param::ALGORITHM;
|
||||
};
|
||||
|
||||
template<> struct ParamType<float>
|
||||
@@ -3218,7 +3224,7 @@ template<> struct ParamType<float>
|
||||
typedef float const_param_type;
|
||||
typedef float member_type;
|
||||
|
||||
enum { type = Param::FLOAT };
|
||||
static const Param type = Param::FLOAT;
|
||||
};
|
||||
|
||||
template<> struct ParamType<unsigned>
|
||||
@@ -3226,7 +3232,7 @@ template<> struct ParamType<unsigned>
|
||||
typedef unsigned const_param_type;
|
||||
typedef unsigned member_type;
|
||||
|
||||
enum { type = Param::UNSIGNED_INT };
|
||||
static const Param type = Param::UNSIGNED_INT;
|
||||
};
|
||||
|
||||
template<> struct ParamType<uint64>
|
||||
@@ -3234,7 +3240,7 @@ template<> struct ParamType<uint64>
|
||||
typedef uint64 const_param_type;
|
||||
typedef uint64 member_type;
|
||||
|
||||
enum { type = Param::UINT64 };
|
||||
static const Param type = Param::UINT64;
|
||||
};
|
||||
|
||||
template<> struct ParamType<uchar>
|
||||
@@ -3242,7 +3248,7 @@ template<> struct ParamType<uchar>
|
||||
typedef uchar const_param_type;
|
||||
typedef uchar member_type;
|
||||
|
||||
enum { type = Param::UCHAR };
|
||||
static const Param type = Param::UCHAR;
|
||||
};
|
||||
|
||||
template<> struct ParamType<Scalar>
|
||||
@@ -3250,7 +3256,16 @@ template<> struct ParamType<Scalar>
|
||||
typedef const Scalar& const_param_type;
|
||||
typedef Scalar member_type;
|
||||
|
||||
enum { type = Param::SCALAR };
|
||||
static const Param type = Param::SCALAR;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct ParamType<_Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type>
|
||||
{
|
||||
typedef typename std::underlying_type<_Tp>::type const_param_type;
|
||||
typedef typename std::underlying_type<_Tp>::type member_type;
|
||||
|
||||
static const Param type = Param::INT;
|
||||
};
|
||||
|
||||
//! @} core_basic
|
||||
|
||||
@@ -390,6 +390,8 @@ CV_EXPORTS CV_NORETURN void error(int _code, const String& _err, const char* _fu
|
||||
#define CV_Error(...) do { abort(); } while (0)
|
||||
#define CV_Error_( code, args ) do { cv::format args; abort(); } while (0)
|
||||
#define CV_Assert( expr ) do { if (!(expr)) abort(); } while (0)
|
||||
#define CV_ErrorNoReturn CV_Error
|
||||
#define CV_ErrorNoReturn_ CV_Error_
|
||||
|
||||
#else // CV_STATIC_ANALYSIS
|
||||
|
||||
@@ -440,17 +442,17 @@ configurations while CV_DbgAssert is only retained in the Debug configuration.
|
||||
#endif
|
||||
|
||||
#define CV_Assert_1 CV_Assert
|
||||
#define CV_Assert_2( expr1, expr2 ) CV_Assert_1(expr1); CV_Assert_1(expr2)
|
||||
#define CV_Assert_3( expr1, expr2, expr3 ) CV_Assert_2(expr1, expr2); CV_Assert_1(expr3)
|
||||
#define CV_Assert_4( expr1, expr2, expr3, expr4 ) CV_Assert_3(expr1, expr2, expr3); CV_Assert_1(expr4)
|
||||
#define CV_Assert_5( expr1, expr2, expr3, expr4, expr5 ) CV_Assert_4(expr1, expr2, expr3, expr4); CV_Assert_1(expr5)
|
||||
#define CV_Assert_6( expr1, expr2, expr3, expr4, expr5, expr6 ) CV_Assert_5(expr1, expr2, expr3, expr4, expr5); CV_Assert_1(expr6)
|
||||
#define CV_Assert_7( expr1, expr2, expr3, expr4, expr5, expr6, expr7 ) CV_Assert_6(expr1, expr2, expr3, expr4, expr5, expr6 ); CV_Assert_1(expr7)
|
||||
#define CV_Assert_8( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8 ) CV_Assert_7(expr1, expr2, expr3, expr4, expr5, expr6, expr7 ); CV_Assert_1(expr8)
|
||||
#define CV_Assert_9( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9 ) CV_Assert_8(expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8 ); CV_Assert_1(expr9)
|
||||
#define CV_Assert_10( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9, expr10 ) CV_Assert_9(expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9 ); CV_Assert_1(expr10)
|
||||
#define CV_Assert_2( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_1( __VA_ARGS__ ))
|
||||
#define CV_Assert_3( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_2( __VA_ARGS__ ))
|
||||
#define CV_Assert_4( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_3( __VA_ARGS__ ))
|
||||
#define CV_Assert_5( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_4( __VA_ARGS__ ))
|
||||
#define CV_Assert_6( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_5( __VA_ARGS__ ))
|
||||
#define CV_Assert_7( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_6( __VA_ARGS__ ))
|
||||
#define CV_Assert_8( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_7( __VA_ARGS__ ))
|
||||
#define CV_Assert_9( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_8( __VA_ARGS__ ))
|
||||
#define CV_Assert_10( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_9( __VA_ARGS__ ))
|
||||
|
||||
#define CV_Assert_N(...) do { __CV_CAT(CV_Assert_, __CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__); } while(0)
|
||||
#define CV_Assert_N(...) do { __CV_EXPAND(__CV_CAT(CV_Assert_, __CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__)); } while(0)
|
||||
|
||||
//! @endcond
|
||||
|
||||
@@ -467,7 +469,7 @@ configurations while CV_DbgAssert is only retained in the Debug configuration.
|
||||
*/
|
||||
struct CV_EXPORTS Hamming
|
||||
{
|
||||
enum { normType = NORM_HAMMING };
|
||||
static const NormTypes normType = NORM_HAMMING;
|
||||
typedef unsigned char ValueType;
|
||||
typedef int ResultType;
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const
|
||||
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);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const double v1, const double v2, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_<int> v1, const Size_<int> v2, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx);
|
||||
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);
|
||||
@@ -77,6 +78,7 @@ CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& c
|
||||
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);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const double v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_<int> v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v, const CheckContext& ctx);
|
||||
CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckContext& ctx);
|
||||
|
||||
@@ -134,8 +134,8 @@ public:
|
||||
CV_WRAP GpuMat(const GpuMat& m);
|
||||
|
||||
//! constructor for GpuMat headers pointing to user-allocated data
|
||||
CV_WRAP GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP);
|
||||
CV_WRAP GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP);
|
||||
GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP);
|
||||
GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP);
|
||||
|
||||
//! creates a GpuMat header for a part of the bigger matrix
|
||||
CV_WRAP GpuMat(const GpuMat& m, Range rowRange, Range colRange);
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
|
||||
#endif
|
||||
|
||||
#define __CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
|
||||
#define __CV_VA_NUM_ARGS(...) __CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
#define __CV_VA_NUM_ARGS(...) __CV_EXPAND(__CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
||||
|
||||
// undef problematic defines sometimes defined by system headers (windows.h in particular)
|
||||
#undef small
|
||||
@@ -330,6 +330,142 @@ Cv64suf;
|
||||
# define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////// Enum operators ///////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
||||
Provides compatibility operators for both classical and C++11 enum classes,
|
||||
as well as exposing the C++11 enum class members for backwards compatibility
|
||||
|
||||
@code
|
||||
// Provides operators required for flag enums
|
||||
CV_ENUM_FLAGS(AccessFlag);
|
||||
|
||||
// Exposes the listed members of the enum class AccessFlag to the current namespace
|
||||
CV_ENUM_CLASS_EXPOSE(AccessFlag, ACCESS_READ [, ACCESS_WRITE [, ...] ]);
|
||||
@endcode
|
||||
*/
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST) \
|
||||
static const EnumType MEMBER_CONST = EnumType::MEMBER_CONST; \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_2(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_1(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_3(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_2(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_4(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_3(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_5(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_4(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_6(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_5(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_7(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_6(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_8(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_7(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_CLASS_EXPOSE_9(EnumType, MEMBER_CONST, ...) \
|
||||
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
|
||||
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_8(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define __CV_ENUM_FLAGS_LOGICAL_NOT(EnumType) \
|
||||
static inline bool operator!(const EnumType& val) \
|
||||
{ \
|
||||
typedef std::underlying_type<EnumType>::type UnderlyingType; \
|
||||
return !static_cast<UnderlyingType>(val); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_LOGICAL_NOT_EQ(Arg1Type, Arg2Type) \
|
||||
static inline bool operator!=(const Arg1Type& a, const Arg2Type& b) \
|
||||
{ \
|
||||
return static_cast<int>(a) != static_cast<int>(b); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_LOGICAL_EQ(Arg1Type, Arg2Type) \
|
||||
static inline bool operator==(const Arg1Type& a, const Arg2Type& b) \
|
||||
{ \
|
||||
return static_cast<int>(a) == static_cast<int>(b); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_NOT(EnumType) \
|
||||
static inline EnumType operator~(const EnumType& val) \
|
||||
{ \
|
||||
typedef std::underlying_type<EnumType>::type UnderlyingType; \
|
||||
return static_cast<EnumType>(~static_cast<UnderlyingType>(val)); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_OR(EnumType, Arg1Type, Arg2Type) \
|
||||
static inline EnumType operator|(const Arg1Type& a, const Arg2Type& b) \
|
||||
{ \
|
||||
typedef std::underlying_type<EnumType>::type UnderlyingType; \
|
||||
return static_cast<EnumType>(static_cast<UnderlyingType>(a) | static_cast<UnderlyingType>(b)); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_AND(EnumType, Arg1Type, Arg2Type) \
|
||||
static inline EnumType operator&(const Arg1Type& a, const Arg2Type& b) \
|
||||
{ \
|
||||
typedef std::underlying_type<EnumType>::type UnderlyingType; \
|
||||
return static_cast<EnumType>(static_cast<UnderlyingType>(a) & static_cast<UnderlyingType>(b)); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_XOR(EnumType, Arg1Type, Arg2Type) \
|
||||
static inline EnumType operator^(const Arg1Type& a, const Arg2Type& b) \
|
||||
{ \
|
||||
typedef std::underlying_type<EnumType>::type UnderlyingType; \
|
||||
return static_cast<EnumType>(static_cast<UnderlyingType>(a) ^ static_cast<UnderlyingType>(b)); \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_OR_EQ(EnumType, Arg1Type) \
|
||||
static inline EnumType& operator|=(EnumType& _this, const Arg1Type& val) \
|
||||
{ \
|
||||
_this = static_cast<EnumType>(static_cast<int>(_this) | static_cast<int>(val)); \
|
||||
return _this; \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_AND_EQ(EnumType, Arg1Type) \
|
||||
static inline EnumType& operator&=(EnumType& _this, const Arg1Type& val) \
|
||||
{ \
|
||||
_this = static_cast<EnumType>(static_cast<int>(_this) & static_cast<int>(val)); \
|
||||
return _this; \
|
||||
} \
|
||||
|
||||
#define __CV_ENUM_FLAGS_BITWISE_XOR_EQ(EnumType, Arg1Type) \
|
||||
static inline EnumType& operator^=(EnumType& _this, const Arg1Type& val) \
|
||||
{ \
|
||||
_this = static_cast<EnumType>(static_cast<int>(_this) ^ static_cast<int>(val)); \
|
||||
return _this; \
|
||||
} \
|
||||
|
||||
#define CV_ENUM_CLASS_EXPOSE(EnumType, ...) \
|
||||
__CV_EXPAND(__CV_CAT(__CV_ENUM_CLASS_EXPOSE_, __CV_VA_NUM_ARGS(__VA_ARGS__))(EnumType, __VA_ARGS__)); \
|
||||
|
||||
#define CV_ENUM_FLAGS(EnumType) \
|
||||
__CV_ENUM_FLAGS_LOGICAL_NOT (EnumType); \
|
||||
__CV_ENUM_FLAGS_LOGICAL_EQ (EnumType, int); \
|
||||
__CV_ENUM_FLAGS_LOGICAL_NOT_EQ (EnumType, int); \
|
||||
\
|
||||
__CV_ENUM_FLAGS_BITWISE_NOT (EnumType); \
|
||||
__CV_ENUM_FLAGS_BITWISE_OR (EnumType, EnumType, EnumType); \
|
||||
__CV_ENUM_FLAGS_BITWISE_AND (EnumType, EnumType, EnumType); \
|
||||
__CV_ENUM_FLAGS_BITWISE_XOR (EnumType, EnumType, EnumType); \
|
||||
\
|
||||
__CV_ENUM_FLAGS_BITWISE_OR_EQ (EnumType, EnumType); \
|
||||
__CV_ENUM_FLAGS_BITWISE_AND_EQ (EnumType, EnumType); \
|
||||
__CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType); \
|
||||
|
||||
/****************************************************************************************\
|
||||
* static analysys *
|
||||
\****************************************************************************************/
|
||||
|
||||
@@ -139,8 +139,14 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
|
||||
# undef CV_FP16
|
||||
#endif
|
||||
|
||||
#if CV_SSE2 || CV_NEON || CV_VSX
|
||||
#define CV__SIMD_FORWARD 128
|
||||
#include "opencv2/core/hal/intrin_forward.hpp"
|
||||
#endif
|
||||
|
||||
#if CV_SSE2
|
||||
|
||||
#include "opencv2/core/hal/intrin_sse_em.hpp"
|
||||
#include "opencv2/core/hal/intrin_sse.hpp"
|
||||
|
||||
#elif CV_NEON
|
||||
@@ -168,6 +174,8 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
|
||||
// (and will be mapped to v256_ counterparts) (e.g. vx_load() => v256_load())
|
||||
#if CV_AVX2
|
||||
|
||||
#define CV__SIMD_FORWARD 256
|
||||
#include "opencv2/core/hal/intrin_forward.hpp"
|
||||
#include "opencv2/core/hal/intrin_avx.hpp"
|
||||
|
||||
#endif
|
||||
@@ -368,6 +376,9 @@ inline unsigned int trailingZeros32(unsigned int value) {
|
||||
unsigned long index = 0;
|
||||
_BitScanForward(&index, value);
|
||||
return (unsigned int)index;
|
||||
#elif defined(__clang__)
|
||||
// clang-cl doesn't export _tzcnt_u32 for non BMI systems
|
||||
return value ? __builtin_ctz(value) : 32;
|
||||
#else
|
||||
return _tzcnt_u32(value);
|
||||
#endif
|
||||
|
||||
@@ -82,6 +82,14 @@ inline __m128 _v256_extract_low(const __m256& v)
|
||||
inline __m128d _v256_extract_low(const __m256d& v)
|
||||
{ return _mm256_castpd256_pd128(v); }
|
||||
|
||||
inline __m256i _v256_packs_epu32(const __m256i& a, const __m256i& b)
|
||||
{
|
||||
const __m256i m = _mm256_set1_epi32(65535);
|
||||
__m256i am = _mm256_min_epu32(a, m);
|
||||
__m256i bm = _mm256_min_epu32(b, m);
|
||||
return _mm256_packus_epi32(am, bm);
|
||||
}
|
||||
|
||||
///////// Types ////////////
|
||||
|
||||
struct v_uint8x32
|
||||
@@ -626,10 +634,8 @@ OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int8x32, _mm256_adds_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int8x32, _mm256_subs_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint16x16, _mm256_adds_epu16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint16x16, _mm256_subs_epu16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_uint16x16, _mm256_mullo_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int16x16, _mm256_adds_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int16x16, _mm256_subs_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_int16x16, _mm256_mullo_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint32x8, _mm256_add_epi32)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint32x8, _mm256_sub_epi32)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_uint32x8, _mm256_mullo_epi32)
|
||||
@@ -650,13 +656,103 @@ OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_float64x4, _mm256_sub_pd)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_float64x4, _mm256_mul_pd)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_OP(/, v_float64x4, _mm256_div_pd)
|
||||
|
||||
// saturating multiply 8-bit, 16-bit
|
||||
inline v_uint8x32 operator * (const v_uint8x32& a, const v_uint8x32& b)
|
||||
{
|
||||
v_uint16x16 c, d;
|
||||
v_mul_expand(a, b, c, d);
|
||||
return v_pack_u(v_reinterpret_as_s16(c), v_reinterpret_as_s16(d));
|
||||
}
|
||||
inline v_int8x32 operator * (const v_int8x32& a, const v_int8x32& b)
|
||||
{
|
||||
v_int16x16 c, d;
|
||||
v_mul_expand(a, b, c, d);
|
||||
return v_pack(c, d);
|
||||
}
|
||||
inline v_uint16x16 operator * (const v_uint16x16& a, const v_uint16x16& b)
|
||||
{
|
||||
__m256i pl = _mm256_mullo_epi16(a.val, b.val);
|
||||
__m256i ph = _mm256_mulhi_epu16(a.val, b.val);
|
||||
__m256i p0 = _mm256_unpacklo_epi16(pl, ph);
|
||||
__m256i p1 = _mm256_unpackhi_epi16(pl, ph);
|
||||
return v_uint16x16(_v256_packs_epu32(p0, p1));
|
||||
}
|
||||
inline v_int16x16 operator * (const v_int16x16& a, const v_int16x16& b)
|
||||
{
|
||||
__m256i pl = _mm256_mullo_epi16(a.val, b.val);
|
||||
__m256i ph = _mm256_mulhi_epi16(a.val, b.val);
|
||||
__m256i p0 = _mm256_unpacklo_epi16(pl, ph);
|
||||
__m256i p1 = _mm256_unpackhi_epi16(pl, ph);
|
||||
return v_int16x16(_mm256_packs_epi32(p0, p1));
|
||||
}
|
||||
inline v_uint8x32& operator *= (v_uint8x32& a, const v_uint8x32& b)
|
||||
{ a = a * b; return a; }
|
||||
inline v_int8x32& operator *= (v_int8x32& a, const v_int8x32& b)
|
||||
{ a = a * b; return a; }
|
||||
inline v_uint16x16& operator *= (v_uint16x16& a, const v_uint16x16& b)
|
||||
{ a = a * b; return a; }
|
||||
inline v_int16x16& operator *= (v_int16x16& a, const v_int16x16& b)
|
||||
{ a = a * b; return a; }
|
||||
|
||||
/** Non-saturating arithmetics **/
|
||||
#define OPENCV_HAL_IMPL_AVX_BIN_FUNC(func, _Tpvec, intrin) \
|
||||
inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
|
||||
{ return _Tpvec(intrin(a.val, b.val)); }
|
||||
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint8x32, _mm256_add_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int8x32, _mm256_add_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint16x16, _mm256_add_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int16x16, _mm256_add_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint8x32, _mm256_sub_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int8x32, _mm256_sub_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint16x16, _mm256_sub_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int16x16, _mm256_sub_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_mul_wrap, v_uint16x16, _mm256_mullo_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_mul_wrap, v_int16x16, _mm256_mullo_epi16)
|
||||
|
||||
inline v_uint8x32 v_mul_wrap(const v_uint8x32& a, const v_uint8x32& b)
|
||||
{
|
||||
__m256i ad = _mm256_srai_epi16(a.val, 8);
|
||||
__m256i bd = _mm256_srai_epi16(b.val, 8);
|
||||
__m256i p0 = _mm256_mullo_epi16(a.val, b.val); // even
|
||||
__m256i p1 = _mm256_slli_epi16(_mm256_mullo_epi16(ad, bd), 8); // odd
|
||||
|
||||
const __m256i b01 = _mm256_set1_epi32(0xFF00FF00);
|
||||
return v_uint8x32(_mm256_blendv_epi8(p0, p1, b01));
|
||||
}
|
||||
inline v_int8x32 v_mul_wrap(const v_int8x32& a, const v_int8x32& b)
|
||||
{
|
||||
return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b)));
|
||||
}
|
||||
|
||||
// Multiply and expand
|
||||
inline void v_mul_expand(const v_uint8x32& a, const v_uint8x32& b,
|
||||
v_uint16x16& c, v_uint16x16& d)
|
||||
{
|
||||
v_uint16x16 a0, a1, b0, b1;
|
||||
v_expand(a, a0, a1);
|
||||
v_expand(b, b0, b1);
|
||||
c = v_mul_wrap(a0, b0);
|
||||
d = v_mul_wrap(a1, b1);
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_int8x32& a, const v_int8x32& b,
|
||||
v_int16x16& c, v_int16x16& d)
|
||||
{
|
||||
v_int16x16 a0, a1, b0, b1;
|
||||
v_expand(a, a0, a1);
|
||||
v_expand(b, b0, b1);
|
||||
c = v_mul_wrap(a0, b0);
|
||||
d = v_mul_wrap(a1, b1);
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_int16x16& a, const v_int16x16& b,
|
||||
v_int32x8& c, v_int32x8& d)
|
||||
{
|
||||
v_int16x16 vhi = v_int16x16(_mm256_mulhi_epi16(a.val, b.val));
|
||||
|
||||
v_int16x16 v0, v1;
|
||||
v_zip(a * b, vhi, v0, v1);
|
||||
v_zip(v_mul_wrap(a, b), vhi, v0, v1);
|
||||
|
||||
c = v_reinterpret_as_s32(v0);
|
||||
d = v_reinterpret_as_s32(v1);
|
||||
@@ -668,7 +764,7 @@ inline void v_mul_expand(const v_uint16x16& a, const v_uint16x16& b,
|
||||
v_uint16x16 vhi = v_uint16x16(_mm256_mulhi_epu16(a.val, b.val));
|
||||
|
||||
v_uint16x16 v0, v1;
|
||||
v_zip(a * b, vhi, v0, v1);
|
||||
v_zip(v_mul_wrap(a, b), vhi, v0, v1);
|
||||
|
||||
c = v_reinterpret_as_u32(v0);
|
||||
d = v_reinterpret_as_u32(v1);
|
||||
@@ -685,20 +781,6 @@ inline void v_mul_expand(const v_uint32x8& a, const v_uint32x8& b,
|
||||
inline v_int16x16 v_mul_hi(const v_int16x16& a, const v_int16x16& b) { return v_int16x16(_mm256_mulhi_epi16(a.val, b.val)); }
|
||||
inline v_uint16x16 v_mul_hi(const v_uint16x16& a, const v_uint16x16& b) { return v_uint16x16(_mm256_mulhi_epu16(a.val, b.val)); }
|
||||
|
||||
/** Non-saturating arithmetics **/
|
||||
#define OPENCV_HAL_IMPL_AVX_BIN_FUNC(func, _Tpvec, intrin) \
|
||||
inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
|
||||
{ return _Tpvec(intrin(a.val, b.val)); }
|
||||
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint8x32, _mm256_add_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int8x32, _mm256_add_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint16x16, _mm256_add_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int16x16, _mm256_add_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint8x32, _mm256_sub_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int8x32, _mm256_sub_epi8)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint16x16, _mm256_sub_epi16)
|
||||
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int16x16, _mm256_sub_epi16)
|
||||
|
||||
/** Bitwise shifts **/
|
||||
#define OPENCV_HAL_IMPL_AVX_SHIFT_OP(_Tpuvec, _Tpsvec, suffix, srai) \
|
||||
inline _Tpuvec operator << (const _Tpuvec& a, int imm) \
|
||||
@@ -1385,6 +1467,10 @@ OPENCV_HAL_IMPL_AVX_TRANSPOSE4x4(v_float32x8, ps, _mm256_castps_si256, _mm256_ca
|
||||
b0.val = intrin(_v256_extract_low(a.val)); \
|
||||
b1.val = intrin(_v256_extract_high(a.val)); \
|
||||
} \
|
||||
inline _Tpwvec v_expand_low(const _Tpvec& a) \
|
||||
{ return _Tpwvec(intrin(_v256_extract_low(a.val))); } \
|
||||
inline _Tpwvec v_expand_high(const _Tpvec& a) \
|
||||
{ return _Tpwvec(intrin(_v256_extract_high(a.val))); } \
|
||||
inline _Tpwvec v256_load_expand(const _Tp* ptr) \
|
||||
{ \
|
||||
__m128i a = _mm_loadu_si128((const __m128i*)ptr); \
|
||||
@@ -1430,7 +1516,12 @@ inline void v_pack_store(schar* ptr, const v_int16x16& a)
|
||||
{ v_store_low(ptr, v_pack(a, a)); }
|
||||
|
||||
inline void v_pack_store(uchar* ptr, const v_uint16x16& a)
|
||||
{ v_store_low(ptr, v_pack(a, a)); }
|
||||
{
|
||||
const __m256i m = _mm256_set1_epi16(255);
|
||||
__m256i am = _mm256_min_epu16(a.val, m);
|
||||
am = _v256_shuffle_odd_64(_mm256_packus_epi16(am, am));
|
||||
v_store_low(ptr, v_uint8x32(am));
|
||||
}
|
||||
|
||||
inline void v_pack_u_store(uchar* ptr, const v_int16x16& a)
|
||||
{ v_store_low(ptr, v_pack_u(a, a)); }
|
||||
@@ -1484,16 +1575,21 @@ inline v_int16x16 v_pack(const v_int32x8& a, const v_int32x8& b)
|
||||
{ return v_int16x16(_v256_shuffle_odd_64(_mm256_packs_epi32(a.val, b.val))); }
|
||||
|
||||
inline v_uint16x16 v_pack(const v_uint32x8& a, const v_uint32x8& b)
|
||||
{ return v_uint16x16(_v256_shuffle_odd_64(_mm256_packus_epi32(a.val, b.val))); }
|
||||
{ return v_uint16x16(_v256_shuffle_odd_64(_v256_packs_epu32(a.val, b.val))); }
|
||||
|
||||
inline v_uint16x16 v_pack_u(const v_int32x8& a, const v_int32x8& b)
|
||||
{ return v_pack(v_reinterpret_as_u32(a), v_reinterpret_as_u32(b)); }
|
||||
{ return v_uint16x16(_v256_shuffle_odd_64(_mm256_packus_epi32(a.val, b.val))); }
|
||||
|
||||
inline void v_pack_store(short* ptr, const v_int32x8& a)
|
||||
{ v_store_low(ptr, v_pack(a, a)); }
|
||||
|
||||
inline void v_pack_store(ushort* ptr, const v_uint32x8& a)
|
||||
{ v_store_low(ptr, v_pack(a, a)); }
|
||||
{
|
||||
const __m256i m = _mm256_set1_epi32(65535);
|
||||
__m256i am = _mm256_min_epu32(a.val, m);
|
||||
am = _v256_shuffle_odd_64(_mm256_packus_epi32(am, am));
|
||||
v_store_low(ptr, v_uint16x16(am));
|
||||
}
|
||||
|
||||
inline void v_pack_u_store(ushort* ptr, const v_int32x8& a)
|
||||
{ v_store_low(ptr, v_pack_u(a, a)); }
|
||||
|
||||
@@ -108,7 +108,7 @@ block and to save contents of the register to memory block.
|
||||
These operations allow to reorder or recombine elements in one or multiple vectors.
|
||||
|
||||
- Interleave, deinterleave (2, 3 and 4 channels): @ref v_load_deinterleave, @ref v_store_interleave
|
||||
- Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand
|
||||
- Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand, @ref v_expand_low, @ref v_expand_high
|
||||
- Pack: @ref v_pack, @ref v_pack_u, @ref v_rshr_pack, @ref v_rshr_pack_u,
|
||||
@ref v_pack_store, @ref v_pack_u_store, @ref v_rshr_pack_store, @ref v_rshr_pack_u_store
|
||||
- Recombine: @ref v_zip, @ref v_recombine, @ref v_combine_low, @ref v_combine_high
|
||||
@@ -185,11 +185,14 @@ Regular integers:
|
||||
|load, store | x | x | x | x | x | x |
|
||||
|interleave | x | x | x | x | x | x |
|
||||
|expand | x | x | x | x | x | x |
|
||||
|expand_low | x | x | x | x | x | x |
|
||||
|expand_high | x | x | x | x | x | x |
|
||||
|expand_q | x | x | | | | |
|
||||
|add, sub | x | x | x | x | x | x |
|
||||
|add_wrap, sub_wrap | x | x | x | x | | |
|
||||
|mul | | | x | x | x | x |
|
||||
|mul_expand | | | x | x | x | |
|
||||
|mul_wrap | x | x | x | x | | |
|
||||
|mul | x | x | x | x | x | x |
|
||||
|mul_expand | x | x | x | x | x | |
|
||||
|compare | x | x | x | x | x | x |
|
||||
|shift | | | x | x | x | x |
|
||||
|dotprod | | | | x | | |
|
||||
@@ -680,7 +683,7 @@ OPENCV_HAL_IMPL_CMP_OP(!=)
|
||||
|
||||
//! @brief Helper macro
|
||||
//! @ingroup core_hal_intrin_impl
|
||||
#define OPENCV_HAL_IMPL_ADD_SUB_OP(func, bin_op, cast_op, _Tp2) \
|
||||
#define OPENCV_HAL_IMPL_ARITHM_OP(func, bin_op, cast_op, _Tp2) \
|
||||
template<typename _Tp, int n> \
|
||||
inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
|
||||
{ \
|
||||
@@ -694,12 +697,17 @@ inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
|
||||
/** @brief Add values without saturation
|
||||
|
||||
For 8- and 16-bit integer values. */
|
||||
OPENCV_HAL_IMPL_ADD_SUB_OP(v_add_wrap, +, (_Tp), _Tp)
|
||||
OPENCV_HAL_IMPL_ARITHM_OP(v_add_wrap, +, (_Tp), _Tp)
|
||||
|
||||
/** @brief Subtract values without saturation
|
||||
|
||||
For 8- and 16-bit integer values. */
|
||||
OPENCV_HAL_IMPL_ADD_SUB_OP(v_sub_wrap, -, (_Tp), _Tp)
|
||||
OPENCV_HAL_IMPL_ARITHM_OP(v_sub_wrap, -, (_Tp), _Tp)
|
||||
|
||||
/** @brief Multiply values without saturation
|
||||
|
||||
For 8- and 16-bit integer values. */
|
||||
OPENCV_HAL_IMPL_ARITHM_OP(v_mul_wrap, *, (_Tp), _Tp)
|
||||
|
||||
//! @cond IGNORED
|
||||
template<typename T> inline T _absdiff(T a, T b)
|
||||
@@ -1106,6 +1114,44 @@ template<typename _Tp, int n> inline void v_expand(const v_reg<_Tp, n>& a,
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Expand lower values to the wider pack type
|
||||
|
||||
Same as cv::v_expand, but return lower half of the vector.
|
||||
|
||||
Scheme:
|
||||
@code
|
||||
int32x4 int64x2
|
||||
{A B C D} ==> {A B}
|
||||
@endcode */
|
||||
template<typename _Tp, int n>
|
||||
inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
|
||||
v_expand_low(const v_reg<_Tp, n>& a)
|
||||
{
|
||||
v_reg<typename V_TypeTraits<_Tp>::w_type, n/2> b;
|
||||
for( int i = 0; i < (n/2); i++ )
|
||||
b.s[i] = a.s[i];
|
||||
return b;
|
||||
}
|
||||
|
||||
/** @brief Expand higher values to the wider pack type
|
||||
|
||||
Same as cv::v_expand_low, but expand higher half of the vector instead.
|
||||
|
||||
Scheme:
|
||||
@code
|
||||
int32x4 int64x2
|
||||
{A B C D} ==> {C D}
|
||||
@endcode */
|
||||
template<typename _Tp, int n>
|
||||
inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
|
||||
v_expand_high(const v_reg<_Tp, n>& a)
|
||||
{
|
||||
v_reg<typename V_TypeTraits<_Tp>::w_type, n/2> b;
|
||||
for( int i = 0; i < (n/2); i++ )
|
||||
b.s[i] = a.s[i+(n/2)];
|
||||
return b;
|
||||
}
|
||||
|
||||
//! @cond IGNORED
|
||||
template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::int_type, n>
|
||||
v_reinterpret_as_int(const v_reg<_Tp, n>& a)
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#ifndef CV__SIMD_FORWARD
|
||||
#error "Need to pre-define forward width"
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
|
||||
|
||||
/** Types **/
|
||||
#if CV__SIMD_FORWARD == 512
|
||||
// [todo] 512
|
||||
#error "AVX512 Not implemented yet"
|
||||
#elif CV__SIMD_FORWARD == 256
|
||||
// 256
|
||||
#define __CV_VX(fun) v256_##fun
|
||||
#define __CV_V_UINT8 v_uint8x32
|
||||
#define __CV_V_INT8 v_int8x32
|
||||
#define __CV_V_UINT16 v_uint16x16
|
||||
#define __CV_V_INT16 v_int16x16
|
||||
#define __CV_V_UINT32 v_uint32x8
|
||||
#define __CV_V_INT32 v_int32x8
|
||||
#define __CV_V_UINT64 v_uint64x4
|
||||
#define __CV_V_INT64 v_int64x4
|
||||
#define __CV_V_FLOAT32 v_float32x8
|
||||
#define __CV_V_FLOAT64 v_float64x4
|
||||
struct v_uint8x32;
|
||||
struct v_int8x32;
|
||||
struct v_uint16x16;
|
||||
struct v_int16x16;
|
||||
struct v_uint32x8;
|
||||
struct v_int32x8;
|
||||
struct v_uint64x4;
|
||||
struct v_int64x4;
|
||||
struct v_float32x8;
|
||||
struct v_float64x4;
|
||||
#else
|
||||
// 128
|
||||
#define __CV_VX(fun) v_##fun
|
||||
#define __CV_V_UINT8 v_uint8x16
|
||||
#define __CV_V_INT8 v_int8x16
|
||||
#define __CV_V_UINT16 v_uint16x8
|
||||
#define __CV_V_INT16 v_int16x8
|
||||
#define __CV_V_UINT32 v_uint32x4
|
||||
#define __CV_V_INT32 v_int32x4
|
||||
#define __CV_V_UINT64 v_uint64x2
|
||||
#define __CV_V_INT64 v_int64x2
|
||||
#define __CV_V_FLOAT32 v_float32x4
|
||||
#define __CV_V_FLOAT64 v_float64x2
|
||||
struct v_uint8x16;
|
||||
struct v_int8x16;
|
||||
struct v_uint16x8;
|
||||
struct v_int16x8;
|
||||
struct v_uint32x4;
|
||||
struct v_int32x4;
|
||||
struct v_uint64x2;
|
||||
struct v_int64x2;
|
||||
struct v_float32x4;
|
||||
struct v_float64x2;
|
||||
#endif
|
||||
|
||||
/** Value reordering **/
|
||||
|
||||
// Expansion
|
||||
void v_expand(const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&);
|
||||
void v_expand(const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&);
|
||||
void v_expand(const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&);
|
||||
void v_expand(const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&);
|
||||
void v_expand(const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&);
|
||||
void v_expand(const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&);
|
||||
// Low Expansion
|
||||
__CV_V_UINT16 v_expand_low(const __CV_V_UINT8&);
|
||||
__CV_V_INT16 v_expand_low(const __CV_V_INT8&);
|
||||
__CV_V_UINT32 v_expand_low(const __CV_V_UINT16&);
|
||||
__CV_V_INT32 v_expand_low(const __CV_V_INT16&);
|
||||
__CV_V_UINT64 v_expand_low(const __CV_V_UINT32&);
|
||||
__CV_V_INT64 v_expand_low(const __CV_V_INT32&);
|
||||
// High Expansion
|
||||
__CV_V_UINT16 v_expand_high(const __CV_V_UINT8&);
|
||||
__CV_V_INT16 v_expand_high(const __CV_V_INT8&);
|
||||
__CV_V_UINT32 v_expand_high(const __CV_V_UINT16&);
|
||||
__CV_V_INT32 v_expand_high(const __CV_V_INT16&);
|
||||
__CV_V_UINT64 v_expand_high(const __CV_V_UINT32&);
|
||||
__CV_V_INT64 v_expand_high(const __CV_V_INT32&);
|
||||
// Load & Low Expansion
|
||||
__CV_V_UINT16 __CV_VX(load_expand)(const uchar*);
|
||||
__CV_V_INT16 __CV_VX(load_expand)(const schar*);
|
||||
__CV_V_UINT32 __CV_VX(load_expand)(const ushort*);
|
||||
__CV_V_INT32 __CV_VX(load_expand)(const short*);
|
||||
__CV_V_UINT64 __CV_VX(load_expand)(const uint*);
|
||||
__CV_V_INT64 __CV_VX(load_expand)(const int*);
|
||||
// Load lower 8-bit and expand into 32-bit
|
||||
__CV_V_UINT32 __CV_VX(load_expand_q)(const uchar*);
|
||||
__CV_V_INT32 __CV_VX(load_expand_q)(const schar*);
|
||||
|
||||
// Saturating Pack
|
||||
__CV_V_UINT8 v_pack(const __CV_V_UINT16&, const __CV_V_UINT16&);
|
||||
__CV_V_INT8 v_pack(const __CV_V_INT16&, const __CV_V_INT16&);
|
||||
__CV_V_UINT16 v_pack(const __CV_V_UINT32&, const __CV_V_UINT32&);
|
||||
__CV_V_INT16 v_pack(const __CV_V_INT32&, const __CV_V_INT32&);
|
||||
// Non-saturating Pack
|
||||
__CV_V_UINT32 v_pack(const __CV_V_UINT64&, const __CV_V_UINT64&);
|
||||
__CV_V_INT32 v_pack(const __CV_V_INT64&, const __CV_V_INT64&);
|
||||
// Pack signed integers with unsigned saturation
|
||||
__CV_V_UINT8 v_pack_u(const __CV_V_INT16&, const __CV_V_INT16&);
|
||||
__CV_V_UINT16 v_pack_u(const __CV_V_INT32&, const __CV_V_INT32&);
|
||||
|
||||
/** Arithmetic, bitwise and comparison operations **/
|
||||
|
||||
// Non-saturating multiply
|
||||
#if CV_VSX
|
||||
template<typename Tvec>
|
||||
Tvec v_mul_wrap(const Tvec& a, const Tvec& b);
|
||||
#else
|
||||
__CV_V_UINT8 v_mul_wrap(const __CV_V_UINT8&, const __CV_V_UINT8&);
|
||||
__CV_V_INT8 v_mul_wrap(const __CV_V_INT8&, const __CV_V_INT8&);
|
||||
__CV_V_UINT16 v_mul_wrap(const __CV_V_UINT16&, const __CV_V_UINT16&);
|
||||
__CV_V_INT16 v_mul_wrap(const __CV_V_INT16&, const __CV_V_INT16&);
|
||||
#endif
|
||||
|
||||
// Multiply and expand
|
||||
#if CV_VSX
|
||||
template<typename Tvec, typename Twvec>
|
||||
void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& d);
|
||||
#else
|
||||
void v_mul_expand(const __CV_V_UINT8&, const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&);
|
||||
void v_mul_expand(const __CV_V_INT8&, const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&);
|
||||
void v_mul_expand(const __CV_V_UINT16&, const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&);
|
||||
void v_mul_expand(const __CV_V_INT16&, const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&);
|
||||
void v_mul_expand(const __CV_V_UINT32&, const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&);
|
||||
void v_mul_expand(const __CV_V_INT32&, const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&);
|
||||
#endif
|
||||
|
||||
/** Cleanup **/
|
||||
#undef CV__SIMD_FORWARD
|
||||
#undef __CV_VX
|
||||
#undef __CV_V_UINT8
|
||||
#undef __CV_V_INT8
|
||||
#undef __CV_V_UINT16
|
||||
#undef __CV_V_INT16
|
||||
#undef __CV_V_UINT32
|
||||
#undef __CV_V_INT32
|
||||
#undef __CV_V_UINT64
|
||||
#undef __CV_V_INT64
|
||||
#undef __CV_V_FLOAT32
|
||||
#undef __CV_V_FLOAT64
|
||||
|
||||
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
|
||||
|
||||
//! @endcond
|
||||
|
||||
} // cv::
|
||||
@@ -435,10 +435,8 @@ OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int8x16, vqaddq_s8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int8x16, vqsubq_s8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint16x8, vqaddq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint16x8, vqsubq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_uint16x8, vmulq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int16x8, vqaddq_s16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int16x8, vqsubq_s16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int16x8, vmulq_s16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int32x4, vaddq_s32)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int32x4, vsubq_s32)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int32x4, vmulq_s32)
|
||||
@@ -476,6 +474,37 @@ inline v_float32x4& operator /= (v_float32x4& a, const v_float32x4& b)
|
||||
}
|
||||
#endif
|
||||
|
||||
// saturating multiply 8-bit, 16-bit
|
||||
#define OPENCV_HAL_IMPL_NEON_MUL_SAT(_Tpvec, _Tpwvec) \
|
||||
inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
|
||||
{ \
|
||||
_Tpwvec c, d; \
|
||||
v_mul_expand(a, b, c, d); \
|
||||
return v_pack(c, d); \
|
||||
} \
|
||||
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
|
||||
{ a = a * b; return a; }
|
||||
|
||||
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_int8x16, v_int16x8)
|
||||
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_uint8x16, v_uint16x8)
|
||||
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_int16x8, v_int32x4)
|
||||
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_uint16x8, v_uint32x4)
|
||||
|
||||
// Multiply and expand
|
||||
inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b,
|
||||
v_int16x8& c, v_int16x8& d)
|
||||
{
|
||||
c.val = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val));
|
||||
d.val = vmull_s8(vget_high_s8(a.val), vget_high_s8(b.val));
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b,
|
||||
v_uint16x8& c, v_uint16x8& d)
|
||||
{
|
||||
c.val = vmull_u8(vget_low_u8(a.val), vget_low_u8(b.val));
|
||||
d.val = vmull_u8(vget_high_u8(a.val), vget_high_u8(b.val));
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
|
||||
v_int32x4& c, v_int32x4& d)
|
||||
{
|
||||
@@ -714,6 +743,10 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_sub_wrap, vsubq_u8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_sub_wrap, vsubq_s8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_sub_wrap, vsubq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_sub_wrap, vsubq_s16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_mul_wrap, vmulq_u8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_mul_wrap, vmulq_s8)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_mul_wrap, vmulq_u16)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mul_wrap, vmulq_s16)
|
||||
|
||||
// TODO: absdiff for signed integers
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_absdiff, vabdq_u8)
|
||||
@@ -1056,6 +1089,14 @@ inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
|
||||
b0.val = vmovl_##suffix(vget_low_##suffix(a.val)); \
|
||||
b1.val = vmovl_##suffix(vget_high_##suffix(a.val)); \
|
||||
} \
|
||||
inline _Tpwvec v_expand_low(const _Tpvec& a) \
|
||||
{ \
|
||||
return _Tpwvec(vmovl_##suffix(vget_low_##suffix(a.val))); \
|
||||
} \
|
||||
inline _Tpwvec v_expand_high(const _Tpvec& a) \
|
||||
{ \
|
||||
return _Tpwvec(vmovl_##suffix(vget_high_##suffix(a.val))); \
|
||||
} \
|
||||
inline _Tpwvec v_load_expand(const _Tp* ptr) \
|
||||
{ \
|
||||
return _Tpwvec(vmovl_##suffix(vld1_##suffix(ptr))); \
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace cv
|
||||
|
||||
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
|
||||
|
||||
///////// Types ////////////
|
||||
|
||||
struct v_uint8x16
|
||||
{
|
||||
typedef uchar lane_type;
|
||||
@@ -436,13 +438,7 @@ inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b)
|
||||
}
|
||||
|
||||
inline v_uint16x8 v_pack(const v_uint32x4& a, const v_uint32x4& b)
|
||||
{
|
||||
__m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768);
|
||||
__m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32);
|
||||
__m128i b1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, b.val), maxval32, b.val), delta32);
|
||||
__m128i r = _mm_packs_epi32(a1, b1);
|
||||
return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768)));
|
||||
}
|
||||
{ return v_uint16x8(_v128_packs_epu32(a.val, b.val)); }
|
||||
|
||||
inline void v_pack_store(ushort* ptr, const v_uint32x4& a)
|
||||
{
|
||||
@@ -472,6 +468,9 @@ void v_rshr_pack_store(ushort* ptr, const v_uint32x4& a)
|
||||
|
||||
inline v_uint16x8 v_pack_u(const v_int32x4& a, const v_int32x4& b)
|
||||
{
|
||||
#if CV_SSE4_1
|
||||
return v_uint16x8(_mm_packus_epi32(a.val, b.val));
|
||||
#else
|
||||
__m128i delta32 = _mm_set1_epi32(32768);
|
||||
|
||||
// preliminary saturate negative values to zero
|
||||
@@ -480,34 +479,51 @@ inline v_uint16x8 v_pack_u(const v_int32x4& a, const v_int32x4& b)
|
||||
|
||||
__m128i r = _mm_packs_epi32(_mm_sub_epi32(a1, delta32), _mm_sub_epi32(b1, delta32));
|
||||
return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768)));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void v_pack_u_store(ushort* ptr, const v_int32x4& a)
|
||||
{
|
||||
#if CV_SSE4_1
|
||||
_mm_storel_epi64((__m128i*)ptr, _mm_packus_epi32(a.val, a.val));
|
||||
#else
|
||||
__m128i delta32 = _mm_set1_epi32(32768);
|
||||
__m128i a1 = _mm_sub_epi32(a.val, delta32);
|
||||
__m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
|
||||
_mm_storel_epi64((__m128i*)ptr, r);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int n> inline
|
||||
v_uint16x8 v_rshr_pack_u(const v_int32x4& a, const v_int32x4& b)
|
||||
{
|
||||
#if CV_SSE4_1
|
||||
__m128i delta = _mm_set1_epi32(1 << (n - 1));
|
||||
return v_uint16x8(_mm_packus_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n),
|
||||
_mm_srai_epi32(_mm_add_epi32(b.val, delta), n)));
|
||||
#else
|
||||
__m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
|
||||
__m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32);
|
||||
__m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
|
||||
__m128i b1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(b.val, delta), n), delta32);
|
||||
__m128i b2 = _mm_sub_epi16(_mm_packs_epi32(b1, b1), _mm_set1_epi16(-32768));
|
||||
return v_uint16x8(_mm_unpacklo_epi64(a2, b2));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int n> inline
|
||||
void v_rshr_pack_u_store(ushort* ptr, const v_int32x4& a)
|
||||
{
|
||||
#if CV_SSE4_1
|
||||
__m128i delta = _mm_set1_epi32(1 << (n - 1));
|
||||
__m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n);
|
||||
_mm_storel_epi64((__m128i*)ptr, _mm_packus_epi32(a1, a1));
|
||||
#else
|
||||
__m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
|
||||
__m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32);
|
||||
__m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
|
||||
_mm_storel_epi64((__m128i*)ptr, a2);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline v_int16x8 v_pack(const v_int32x4& a, const v_int32x4& b)
|
||||
@@ -658,14 +674,14 @@ OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int8x16, _mm_adds_epi8)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int8x16, _mm_subs_epi8)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint16x8, _mm_adds_epu16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint16x8, _mm_subs_epu16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_uint16x8, _mm_mullo_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int16x8, _mm_adds_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int16x8, _mm_subs_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int16x8, _mm_mullo_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint32x4, _mm_add_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint32x4, _mm_sub_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_uint32x4, _v128_mullo_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int32x4, _mm_add_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int32x4, _v128_mullo_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float32x4, _mm_add_ps)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float32x4, _mm_sub_ps)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float32x4, _mm_mul_ps)
|
||||
@@ -679,35 +695,49 @@ OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint64x2, _mm_sub_epi64)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int64x2, _mm_add_epi64)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int64x2, _mm_sub_epi64)
|
||||
|
||||
inline v_uint32x4 operator * (const v_uint32x4& a, const v_uint32x4& b)
|
||||
// saturating multiply 8-bit, 16-bit
|
||||
#define OPENCV_HAL_IMPL_SSE_MUL_SAT(_Tpvec, _Tpwvec) \
|
||||
inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
|
||||
{ \
|
||||
_Tpwvec c, d; \
|
||||
v_mul_expand(a, b, c, d); \
|
||||
return v_pack(c, d); \
|
||||
} \
|
||||
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
|
||||
{ a = a * b; return a; }
|
||||
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int8x16, v_int16x8)
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_uint16x8, v_uint32x4)
|
||||
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int16x8, v_int32x4)
|
||||
|
||||
inline v_uint8x16 operator * (const v_uint8x16& a, const v_uint8x16& b)
|
||||
{
|
||||
__m128i c0 = _mm_mul_epu32(a.val, b.val);
|
||||
__m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32));
|
||||
__m128i d0 = _mm_unpacklo_epi32(c0, c1);
|
||||
__m128i d1 = _mm_unpackhi_epi32(c0, c1);
|
||||
return v_uint32x4(_mm_unpacklo_epi64(d0, d1));
|
||||
v_uint16x8 c, d;
|
||||
v_mul_expand(a, b, c, d);
|
||||
return v_pack_u(v_reinterpret_as_s16(c), v_reinterpret_as_s16(d));
|
||||
}
|
||||
inline v_int32x4 operator * (const v_int32x4& a, const v_int32x4& b)
|
||||
inline v_uint8x16& operator *= (v_uint8x16& a, const v_uint8x16& b)
|
||||
{ a = a * b; return a; }
|
||||
|
||||
// Multiply and expand
|
||||
inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b,
|
||||
v_uint16x8& c, v_uint16x8& d)
|
||||
{
|
||||
#if CV_SSE4_1
|
||||
return v_int32x4(_mm_mullo_epi32(a.val, b.val));
|
||||
#else
|
||||
__m128i c0 = _mm_mul_epu32(a.val, b.val);
|
||||
__m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32));
|
||||
__m128i d0 = _mm_unpacklo_epi32(c0, c1);
|
||||
__m128i d1 = _mm_unpackhi_epi32(c0, c1);
|
||||
return v_int32x4(_mm_unpacklo_epi64(d0, d1));
|
||||
#endif
|
||||
v_uint16x8 a0, a1, b0, b1;
|
||||
v_expand(a, a0, a1);
|
||||
v_expand(b, b0, b1);
|
||||
c = v_mul_wrap(a0, b0);
|
||||
d = v_mul_wrap(a1, b1);
|
||||
}
|
||||
inline v_uint32x4& operator *= (v_uint32x4& a, const v_uint32x4& b)
|
||||
|
||||
inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b,
|
||||
v_int16x8& c, v_int16x8& d)
|
||||
{
|
||||
a = a * b;
|
||||
return a;
|
||||
}
|
||||
inline v_int32x4& operator *= (v_int32x4& a, const v_int32x4& b)
|
||||
{
|
||||
a = a * b;
|
||||
return a;
|
||||
v_int16x8 a0, a1, b0, b1;
|
||||
v_expand(a, a0, a1);
|
||||
v_expand(b, b0, b1);
|
||||
c = v_mul_wrap(a0, b0);
|
||||
d = v_mul_wrap(a1, b1);
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
|
||||
@@ -998,6 +1028,22 @@ OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_sub_wrap, _mm_sub_epi8)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_sub_wrap, _mm_sub_epi8)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_sub_wrap, _mm_sub_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_sub_wrap, _mm_sub_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_mul_wrap, _mm_mullo_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_mul_wrap, _mm_mullo_epi16)
|
||||
|
||||
inline v_uint8x16 v_mul_wrap(const v_uint8x16& a, const v_uint8x16& b)
|
||||
{
|
||||
__m128i ad = _mm_srai_epi16(a.val, 8);
|
||||
__m128i bd = _mm_srai_epi16(b.val, 8);
|
||||
__m128i p0 = _mm_mullo_epi16(a.val, b.val); // even
|
||||
__m128i p1 = _mm_slli_epi16(_mm_mullo_epi16(ad, bd), 8); // odd
|
||||
const __m128i b01 = _mm_set1_epi32(0xFF00FF00);
|
||||
return v_uint8x16(_v128_blendv_epi8(p0, p1, b01));
|
||||
}
|
||||
inline v_int8x16 v_mul_wrap(const v_int8x16& a, const v_int8x16& b)
|
||||
{
|
||||
return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b)));
|
||||
}
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, smask32) \
|
||||
inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \
|
||||
@@ -1482,70 +1528,39 @@ OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, ps)
|
||||
OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, pd)
|
||||
#endif
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpuvec, _Tpwuvec, _Tpu, _Tpsvec, _Tpwsvec, _Tps, suffix, wsuffix, shift) \
|
||||
inline void v_expand(const _Tpuvec& a, _Tpwuvec& b0, _Tpwuvec& b1) \
|
||||
{ \
|
||||
__m128i z = _mm_setzero_si128(); \
|
||||
b0.val = _mm_unpacklo_##suffix(a.val, z); \
|
||||
b1.val = _mm_unpackhi_##suffix(a.val, z); \
|
||||
} \
|
||||
inline _Tpwuvec v_load_expand(const _Tpu* ptr) \
|
||||
{ \
|
||||
__m128i z = _mm_setzero_si128(); \
|
||||
return _Tpwuvec(_mm_unpacklo_##suffix(_mm_loadl_epi64((const __m128i*)ptr), z)); \
|
||||
} \
|
||||
inline void v_expand(const _Tpsvec& a, _Tpwsvec& b0, _Tpwsvec& b1) \
|
||||
{ \
|
||||
b0.val = _mm_srai_##wsuffix(_mm_unpacklo_##suffix(a.val, a.val), shift); \
|
||||
b1.val = _mm_srai_##wsuffix(_mm_unpackhi_##suffix(a.val, a.val), shift); \
|
||||
} \
|
||||
inline _Tpwsvec v_load_expand(const _Tps* ptr) \
|
||||
{ \
|
||||
__m128i a = _mm_loadl_epi64((const __m128i*)ptr); \
|
||||
return _Tpwsvec(_mm_srai_##wsuffix(_mm_unpacklo_##suffix(a, a), shift)); \
|
||||
}
|
||||
/* Expand */
|
||||
#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpvec, _Tpwvec, _Tp, intrin) \
|
||||
inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
|
||||
{ \
|
||||
b0.val = intrin(a.val); \
|
||||
b1.val = __CV_CAT(intrin, _high)(a.val); \
|
||||
} \
|
||||
inline _Tpwvec v_expand_low(const _Tpvec& a) \
|
||||
{ return _Tpwvec(intrin(a.val)); } \
|
||||
inline _Tpwvec v_expand_high(const _Tpvec& a) \
|
||||
{ return _Tpwvec(__CV_CAT(intrin, _high)(a.val)); } \
|
||||
inline _Tpwvec v_load_expand(const _Tp* ptr) \
|
||||
{ \
|
||||
__m128i a = _mm_loadl_epi64((const __m128i*)ptr); \
|
||||
return _Tpwvec(intrin(a)); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, v_int8x16, v_int16x8, schar, epi8, epi16, 8)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, v_int16x8, v_int32x4, short, epi16, epi32, 16)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, _v128_cvtepu8_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_int8x16, v_int16x8, schar, _v128_cvtepi8_epi16)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, _v128_cvtepu16_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_int16x8, v_int32x4, short, _v128_cvtepi16_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint32x4, v_uint64x2, unsigned, _v128_cvtepu32_epi64)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_int32x4, v_int64x2, int, _v128_cvtepi32_epi64)
|
||||
|
||||
inline void v_expand(const v_uint32x4& a, v_uint64x2& b0, v_uint64x2& b1)
|
||||
{
|
||||
__m128i z = _mm_setzero_si128();
|
||||
b0.val = _mm_unpacklo_epi32(a.val, z);
|
||||
b1.val = _mm_unpackhi_epi32(a.val, z);
|
||||
}
|
||||
inline v_uint64x2 v_load_expand(const unsigned* ptr)
|
||||
{
|
||||
__m128i z = _mm_setzero_si128();
|
||||
return v_uint64x2(_mm_unpacklo_epi32(_mm_loadl_epi64((const __m128i*)ptr), z));
|
||||
}
|
||||
inline void v_expand(const v_int32x4& a, v_int64x2& b0, v_int64x2& b1)
|
||||
{
|
||||
__m128i s = _mm_srai_epi32(a.val, 31);
|
||||
b0.val = _mm_unpacklo_epi32(a.val, s);
|
||||
b1.val = _mm_unpackhi_epi32(a.val, s);
|
||||
}
|
||||
inline v_int64x2 v_load_expand(const int* ptr)
|
||||
{
|
||||
__m128i a = _mm_loadl_epi64((const __m128i*)ptr);
|
||||
__m128i s = _mm_srai_epi32(a, 31);
|
||||
return v_int64x2(_mm_unpacklo_epi32(a, s));
|
||||
}
|
||||
#define OPENCV_HAL_IMPL_SSE_EXPAND_Q(_Tpvec, _Tp, intrin) \
|
||||
inline _Tpvec v_load_expand_q(const _Tp* ptr) \
|
||||
{ \
|
||||
__m128i a = _mm_cvtsi32_si128(*(const int*)ptr); \
|
||||
return _Tpvec(intrin(a)); \
|
||||
}
|
||||
|
||||
inline v_uint32x4 v_load_expand_q(const uchar* ptr)
|
||||
{
|
||||
__m128i z = _mm_setzero_si128();
|
||||
__m128i a = _mm_cvtsi32_si128(*(const int*)ptr);
|
||||
return v_uint32x4(_mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z));
|
||||
}
|
||||
|
||||
inline v_int32x4 v_load_expand_q(const schar* ptr)
|
||||
{
|
||||
__m128i a = _mm_cvtsi32_si128(*(const int*)ptr);
|
||||
a = _mm_unpacklo_epi8(a, a);
|
||||
a = _mm_unpacklo_epi8(a, a);
|
||||
return v_int32x4(_mm_srai_epi32(a, 24));
|
||||
}
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_uint32x4, uchar, _v128_cvtepu8_epi32)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_int32x4, schar, _v128_cvtepi8_epi32)
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_UNPACKS(_Tpvec, suffix, cast_from, cast_to) \
|
||||
inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1) \
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#ifndef OPENCV_HAL_INTRIN_SSE_EM_HPP
|
||||
#define OPENCV_HAL_INTRIN_SSE_EM_HPP
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
|
||||
|
||||
#define OPENCV_HAL_SSE_WRAP_1(fun, tp) \
|
||||
inline tp _v128_##fun(const tp& a) \
|
||||
{ return _mm_##fun(a); }
|
||||
|
||||
#define OPENCV_HAL_SSE_WRAP_2(fun, tp) \
|
||||
inline tp _v128_##fun(const tp& a, const tp& b) \
|
||||
{ return _mm_##fun(a, b); }
|
||||
|
||||
#define OPENCV_HAL_SSE_WRAP_3(fun, tp) \
|
||||
inline tp _v128_##fun(const tp& a, const tp& b, const tp& c) \
|
||||
{ return _mm_##fun(a, b, c); }
|
||||
|
||||
///////////////////////////// XOP /////////////////////////////
|
||||
|
||||
// [todo] define CV_XOP
|
||||
#if 1 // CV_XOP
|
||||
inline __m128i _v128_comgt_epu32(const __m128i& a, const __m128i& b)
|
||||
{
|
||||
const __m128i delta = _mm_set1_epi32((int)0x80000000);
|
||||
return _mm_cmpgt_epi32(_mm_xor_si128(a, delta), _mm_xor_si128(b, delta));
|
||||
}
|
||||
// wrapping XOP
|
||||
#else
|
||||
OPENCV_HAL_SSE_WRAP_2(_v128_comgt_epu32, __m128i)
|
||||
#endif // !CV_XOP
|
||||
|
||||
///////////////////////////// SSE4.1 /////////////////////////////
|
||||
|
||||
#if !CV_SSE4_1
|
||||
|
||||
/** Swizzle **/
|
||||
inline __m128i _v128_blendv_epi8(const __m128i& a, const __m128i& b, const __m128i& mask)
|
||||
{ return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(b, a), mask)); }
|
||||
|
||||
/** Convert **/
|
||||
// 8 >> 16
|
||||
inline __m128i _v128_cvtepu8_epi16(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpacklo_epi8(a, z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi8_epi16(const __m128i& a)
|
||||
{ return _mm_srai_epi16(_mm_unpacklo_epi8(a, a), 8); }
|
||||
// 8 >> 32
|
||||
inline __m128i _v128_cvtepu8_epi32(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi8_epi32(const __m128i& a)
|
||||
{
|
||||
__m128i r = _mm_unpacklo_epi8(a, a);
|
||||
r = _mm_unpacklo_epi8(r, r);
|
||||
return _mm_srai_epi32(r, 24);
|
||||
}
|
||||
// 16 >> 32
|
||||
inline __m128i _v128_cvtepu16_epi32(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpacklo_epi16(a, z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi16_epi32(const __m128i& a)
|
||||
{ return _mm_srai_epi32(_mm_unpacklo_epi16(a, a), 16); }
|
||||
// 32 >> 64
|
||||
inline __m128i _v128_cvtepu32_epi64(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpacklo_epi32(a, z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi32_epi64(const __m128i& a)
|
||||
{ return _mm_unpacklo_epi32(a, _mm_srai_epi32(a, 31)); }
|
||||
|
||||
/** Arithmetic **/
|
||||
inline __m128i _v128_mullo_epi32(const __m128i& a, const __m128i& b)
|
||||
{
|
||||
__m128i c0 = _mm_mul_epu32(a, b);
|
||||
__m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a, 32), _mm_srli_epi64(b, 32));
|
||||
__m128i d0 = _mm_unpacklo_epi32(c0, c1);
|
||||
__m128i d1 = _mm_unpackhi_epi32(c0, c1);
|
||||
return _mm_unpacklo_epi64(d0, d1);
|
||||
}
|
||||
|
||||
/** Math **/
|
||||
inline __m128i _v128_min_epu32(const __m128i& a, const __m128i& b)
|
||||
{ return _v128_blendv_epi8(a, b, _v128_comgt_epu32(a, b)); }
|
||||
|
||||
// wrapping SSE4.1
|
||||
#else
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepu8_epi16, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepi8_epi16, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepu8_epi32, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepi8_epi32, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepu16_epi32, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepi16_epi32, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepu32_epi64, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_1(cvtepi32_epi64, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_2(min_epu32, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_2(mullo_epi32, __m128i)
|
||||
OPENCV_HAL_SSE_WRAP_3(blendv_epi8, __m128i)
|
||||
#endif // !CV_SSE4_1
|
||||
|
||||
///////////////////////////// Revolutionary /////////////////////////////
|
||||
|
||||
/** Convert **/
|
||||
// 16 << 8
|
||||
inline __m128i _v128_cvtepu8_epi16_high(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpackhi_epi8(a, z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi8_epi16_high(const __m128i& a)
|
||||
{ return _mm_srai_epi16(_mm_unpackhi_epi8(a, a), 8); }
|
||||
// 32 << 16
|
||||
inline __m128i _v128_cvtepu16_epi32_high(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpackhi_epi16(a, z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi16_epi32_high(const __m128i& a)
|
||||
{ return _mm_srai_epi32(_mm_unpackhi_epi16(a, a), 16); }
|
||||
// 64 << 32
|
||||
inline __m128i _v128_cvtepu32_epi64_high(const __m128i& a)
|
||||
{
|
||||
const __m128i z = _mm_setzero_si128();
|
||||
return _mm_unpackhi_epi32(a, z);
|
||||
}
|
||||
inline __m128i _v128_cvtepi32_epi64_high(const __m128i& a)
|
||||
{ return _mm_unpackhi_epi32(a, _mm_srai_epi32(a, 31)); }
|
||||
|
||||
/** Miscellaneous **/
|
||||
inline __m128i _v128_packs_epu32(const __m128i& a, const __m128i& b)
|
||||
{
|
||||
const __m128i m = _mm_set1_epi32(65535);
|
||||
__m128i am = _v128_min_epu32(a, m);
|
||||
__m128i bm = _v128_min_epu32(b, m);
|
||||
#if CV_SSE4_1
|
||||
return _mm_packus_epi32(am, bm);
|
||||
#else
|
||||
const __m128i d = _mm_set1_epi32(32768), nd = _mm_set1_epi16(-32768);
|
||||
am = _mm_sub_epi32(am, d);
|
||||
bm = _mm_sub_epi32(bm, d);
|
||||
am = _mm_packs_epi32(am, bm);
|
||||
return _mm_sub_epi16(am, nd);
|
||||
#endif
|
||||
}
|
||||
|
||||
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
|
||||
|
||||
//! @endcond
|
||||
|
||||
} // cv::
|
||||
|
||||
#endif // OPENCV_HAL_INTRIN_SSE_EM_HPP
|
||||
@@ -315,6 +315,10 @@ inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
|
||||
b0.val = fh(a.val); \
|
||||
b1.val = fl(a.val); \
|
||||
} \
|
||||
inline _Tpwvec v_expand_low(const _Tpvec& a) \
|
||||
{ return _Tpwvec(fh(a.val)); } \
|
||||
inline _Tpwvec v_expand_high(const _Tpvec& a) \
|
||||
{ return _Tpwvec(fl(a.val)); } \
|
||||
inline _Tpwvec v_load_expand(const _Tp* ptr) \
|
||||
{ return _Tpwvec(fh(vec_ld_l8(ptr))); }
|
||||
|
||||
@@ -418,10 +422,8 @@ OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int8x16, vec_adds)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int8x16, vec_subs)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_uint16x8, vec_adds)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint16x8, vec_subs)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_uint16x8, vec_mul)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int16x8, vec_adds)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int16x8, vec_subs)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_int16x8, vec_mul)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_uint32x4, vec_add)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint32x4, vec_sub)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_uint32x4, vec_mul)
|
||||
@@ -441,16 +443,30 @@ OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint64x2, vec_sub)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int64x2, vec_add)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int64x2, vec_sub)
|
||||
|
||||
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b, v_int32x4& c, v_int32x4& d)
|
||||
// saturating multiply
|
||||
#define OPENCV_HAL_IMPL_VSX_MUL_SAT(_Tpvec, _Tpwvec) \
|
||||
inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
|
||||
{ \
|
||||
_Tpwvec c, d; \
|
||||
v_mul_expand(a, b, c, d); \
|
||||
return v_pack(c, d); \
|
||||
} \
|
||||
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
|
||||
{ a = a * b; return a; }
|
||||
|
||||
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_int8x16, v_int16x8)
|
||||
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_uint8x16, v_uint16x8)
|
||||
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_int16x8, v_int32x4)
|
||||
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_uint16x8, v_uint32x4)
|
||||
|
||||
template<typename Tvec, typename Twvec>
|
||||
inline void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& d)
|
||||
{
|
||||
c.val = vec_mul(vec_unpackh(a.val), vec_unpackh(b.val));
|
||||
d.val = vec_mul(vec_unpackl(a.val), vec_unpackl(b.val));
|
||||
}
|
||||
inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b, v_uint32x4& c, v_uint32x4& d)
|
||||
{
|
||||
c.val = vec_mul(vec_unpackhu(a.val), vec_unpackhu(b.val));
|
||||
d.val = vec_mul(vec_unpacklu(a.val), vec_unpacklu(b.val));
|
||||
Twvec p0 = Twvec(vec_mule(a.val, b.val));
|
||||
Twvec p1 = Twvec(vec_mulo(a.val, b.val));
|
||||
v_zip(p0, p1, c, d);
|
||||
}
|
||||
|
||||
inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, v_uint64x2& c, v_uint64x2& d)
|
||||
{
|
||||
c.val = vec_mul(vec_unpackhu(a.val), vec_unpackhu(b.val));
|
||||
@@ -459,17 +475,17 @@ inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, v_uint64x2& c
|
||||
|
||||
inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b)
|
||||
{
|
||||
return v_int16x8(vec_packs(
|
||||
vec_sra(vec_mul(vec_unpackh(a.val), vec_unpackh(b.val)), vec_uint4_sp(16)),
|
||||
vec_sra(vec_mul(vec_unpackl(a.val), vec_unpackl(b.val)), vec_uint4_sp(16))
|
||||
));
|
||||
vec_int4 p0 = vec_mule(a.val, b.val);
|
||||
vec_int4 p1 = vec_mulo(a.val, b.val);
|
||||
static const vec_uchar16 perm = {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31};
|
||||
return v_int16x8(vec_perm(vec_short8_c(p0), vec_short8_c(p1), perm));
|
||||
}
|
||||
inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b)
|
||||
{
|
||||
return v_uint16x8(vec_packs(
|
||||
vec_sr(vec_mul(vec_unpackhu(a.val), vec_unpackhu(b.val)), vec_uint4_sp(16)),
|
||||
vec_sr(vec_mul(vec_unpacklu(a.val), vec_unpacklu(b.val)), vec_uint4_sp(16))
|
||||
));
|
||||
vec_uint4 p0 = vec_mule(a.val, b.val);
|
||||
vec_uint4 p1 = vec_mulo(a.val, b.val);
|
||||
static const vec_uchar16 perm = {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31};
|
||||
return v_uint16x8(vec_perm(vec_ushort8_c(p0), vec_ushort8_c(p1), perm));
|
||||
}
|
||||
|
||||
/** Non-saturating arithmetics **/
|
||||
@@ -480,6 +496,7 @@ inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
|
||||
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_add_wrap, vec_add)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_sub_wrap, vec_sub)
|
||||
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_mul_wrap, vec_mul)
|
||||
|
||||
/** Bitwise shifts **/
|
||||
#define OPENCV_HAL_IMPL_VSX_SHIFT_OP(_Tpvec, shr, splfunc) \
|
||||
|
||||
@@ -61,8 +61,10 @@ namespace cv
|
||||
//! @addtogroup core_basic
|
||||
//! @{
|
||||
|
||||
enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
|
||||
enum AccessFlag { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
|
||||
ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 };
|
||||
CV_ENUM_FLAGS(AccessFlag);
|
||||
__CV_ENUM_FLAGS_BITWISE_AND(AccessFlag, int, AccessFlag);
|
||||
|
||||
CV__DEBUG_NS_BEGIN
|
||||
|
||||
@@ -156,7 +158,7 @@ Custom type is wrapped as Mat-compatible `CV_8UC<N>` values (N = sizeof(T), N <=
|
||||
class CV_EXPORTS _InputArray
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
enum KindFlag {
|
||||
KIND_SHIFT = 16,
|
||||
FIXED_TYPE = 0x8000 << KIND_SHIFT,
|
||||
FIXED_SIZE = 0x4000 << KIND_SHIFT,
|
||||
@@ -221,7 +223,7 @@ public:
|
||||
void* getObj() const;
|
||||
Size getSz() const;
|
||||
|
||||
int kind() const;
|
||||
_InputArray::KindFlag kind() const;
|
||||
int dims(int i=-1) const;
|
||||
int cols(int i=-1) const;
|
||||
int rows(int i=-1) const;
|
||||
@@ -257,7 +259,8 @@ protected:
|
||||
void init(int _flags, const void* _obj);
|
||||
void init(int _flags, const void* _obj, Size _sz);
|
||||
};
|
||||
|
||||
CV_ENUM_FLAGS(_InputArray::KindFlag);
|
||||
__CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag);
|
||||
|
||||
/** @brief This type is very similar to InputArray except that it is used for input/output and output function
|
||||
parameters.
|
||||
@@ -287,7 +290,7 @@ generators:
|
||||
class CV_EXPORTS _OutputArray : public _InputArray
|
||||
{
|
||||
public:
|
||||
enum
|
||||
enum DepthMask
|
||||
{
|
||||
DEPTH_MASK_8U = 1 << CV_8U,
|
||||
DEPTH_MASK_8S = 1 << CV_8S,
|
||||
@@ -356,9 +359,9 @@ public:
|
||||
std::vector<cuda::GpuMat>& getGpuMatVecRef() const;
|
||||
ogl::Buffer& getOGlBufferRef() const;
|
||||
cuda::HostMem& getHostMemRef() const;
|
||||
void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
|
||||
void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
|
||||
void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
|
||||
void create(Size sz, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
|
||||
void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
|
||||
void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
|
||||
void createSameSize(const _InputArray& arr, int mtype) const;
|
||||
void release() const;
|
||||
void clear() const;
|
||||
@@ -467,10 +470,10 @@ public:
|
||||
// uchar*& datastart, uchar*& data, size_t* step) = 0;
|
||||
//virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
|
||||
virtual UMatData* allocate(int dims, const int* sizes, int type,
|
||||
void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const = 0;
|
||||
virtual bool allocate(UMatData* data, int accessflags, UMatUsageFlags usageFlags) const = 0;
|
||||
void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const = 0;
|
||||
virtual bool allocate(UMatData* data, AccessFlag accessflags, UMatUsageFlags usageFlags) const = 0;
|
||||
virtual void deallocate(UMatData* data) const = 0;
|
||||
virtual void map(UMatData* data, int accessflags) const;
|
||||
virtual void map(UMatData* data, AccessFlag accessflags) const;
|
||||
virtual void unmap(UMatData* data) const;
|
||||
virtual void download(UMatData* data, void* dst, int dims, const size_t sz[],
|
||||
const size_t srcofs[], const size_t srcstep[],
|
||||
@@ -523,7 +526,7 @@ protected:
|
||||
// it should be explicitly initialized using init().
|
||||
struct CV_EXPORTS UMatData
|
||||
{
|
||||
enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
|
||||
enum MemoryFlag { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
|
||||
DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
|
||||
USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64,
|
||||
ASYNC_CLEANUP=128
|
||||
@@ -553,13 +556,14 @@ struct CV_EXPORTS UMatData
|
||||
uchar* origdata;
|
||||
size_t size;
|
||||
|
||||
int flags;
|
||||
UMatData::MemoryFlag flags;
|
||||
void* handle;
|
||||
void* userdata;
|
||||
int allocatorFlags_;
|
||||
int mapcount;
|
||||
UMatData* originalUMatData;
|
||||
};
|
||||
CV_ENUM_FLAGS(UMatData::MemoryFlag);
|
||||
|
||||
|
||||
struct CV_EXPORTS MatSize
|
||||
@@ -1061,7 +1065,7 @@ public:
|
||||
Mat& operator = (const MatExpr& expr);
|
||||
|
||||
//! retrieve UMat from Mat
|
||||
UMat getUMat(int accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const;
|
||||
UMat getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const;
|
||||
|
||||
/** @brief Creates a matrix header for the specified matrix row.
|
||||
|
||||
@@ -2420,7 +2424,7 @@ public:
|
||||
//! assignment operators
|
||||
UMat& operator = (const UMat& m);
|
||||
|
||||
Mat getMat(int flags) const;
|
||||
Mat getMat(AccessFlag flags) const;
|
||||
|
||||
//! returns a new matrix header for the specified row
|
||||
UMat row(int y) const;
|
||||
@@ -2546,7 +2550,7 @@ public:
|
||||
The UMat instance should be kept alive during the use of the handle to prevent the buffer to be
|
||||
returned to the OpenCV buffer pool.
|
||||
*/
|
||||
void* handle(int accessFlags) const;
|
||||
void* handle(AccessFlag accessFlags) const;
|
||||
void ndoffset(size_t* ofs) const;
|
||||
|
||||
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
|
||||
|
||||
@@ -83,7 +83,7 @@ inline void* _InputArray::getObj() const { return obj; }
|
||||
inline int _InputArray::getFlags() const { return flags; }
|
||||
inline Size _InputArray::getSz() const { return sz; }
|
||||
|
||||
inline _InputArray::_InputArray() { init(NONE, 0); }
|
||||
inline _InputArray::_InputArray() { init(0 + NONE, 0); }
|
||||
inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
|
||||
inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
|
||||
inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
|
||||
@@ -185,12 +185,12 @@ inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
|
||||
inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
|
||||
inline _OutputArray::_OutputArray() { init(NONE + ACCESS_WRITE, 0); }
|
||||
inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags + ACCESS_WRITE, _obj); }
|
||||
inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
|
||||
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
|
||||
inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
|
||||
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
|
||||
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
|
||||
inline _OutputArray::_OutputArray(UMat& m) { init(UMAT + ACCESS_WRITE, &m); }
|
||||
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
|
||||
|
||||
template<typename _Tp> inline
|
||||
_OutputArray::_OutputArray(std::vector<_Tp>& vec)
|
||||
@@ -311,8 +311,8 @@ _OutputArray _OutputArray::rawOut(std::array<_Tp, _Nm>& arr)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
|
||||
inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
|
||||
inline _InputOutputArray::_InputOutputArray() { init(0+ACCESS_RW, 0); }
|
||||
inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags+ACCESS_RW, _obj); }
|
||||
inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
|
||||
inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
|
||||
inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
|
||||
@@ -600,7 +600,7 @@ Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
|
||||
cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if(vec.empty())
|
||||
@@ -637,7 +637,7 @@ Mat::Mat(const std::initializer_list<int> sizes, const std::initializer_list<_Tp
|
||||
|
||||
template<typename _Tp, std::size_t _Nm> inline
|
||||
Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()),
|
||||
cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if(arr.empty())
|
||||
@@ -654,7 +654,7 @@ Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
|
||||
|
||||
template<typename _Tp, int n> inline
|
||||
Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
|
||||
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if( !copyData )
|
||||
@@ -670,7 +670,7 @@ Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
|
||||
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if( !copyData )
|
||||
@@ -686,7 +686,7 @@ Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat::Mat(const Point_<_Tp>& pt, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
|
||||
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if( !copyData )
|
||||
@@ -705,7 +705,7 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData)
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
|
||||
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if( !copyData )
|
||||
@@ -725,7 +725,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
|
||||
datastart(0), dataend(0), allocator(0), u(0), size(&rows)
|
||||
{
|
||||
*this = commaInitializer.operator Mat_<_Tp>();
|
||||
@@ -1554,7 +1554,7 @@ template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_()
|
||||
: Mat()
|
||||
{
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
@@ -1611,7 +1611,7 @@ template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_(const Mat& m)
|
||||
: Mat()
|
||||
{
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
|
||||
*this = m;
|
||||
}
|
||||
|
||||
@@ -1751,7 +1751,7 @@ void Mat_<_Tp>::release()
|
||||
{
|
||||
Mat::release();
|
||||
#ifdef _DEBUG
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2069,7 +2069,7 @@ template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_(Mat&& m)
|
||||
: Mat()
|
||||
{
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
|
||||
*this = m;
|
||||
}
|
||||
|
||||
@@ -2095,7 +2095,7 @@ template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_(MatExpr&& e)
|
||||
: Mat()
|
||||
{
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
|
||||
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
|
||||
*this = Mat(e);
|
||||
}
|
||||
|
||||
@@ -2431,7 +2431,7 @@ SparseMatConstIterator_<_Tp> SparseMat::end() const
|
||||
template<typename _Tp> inline
|
||||
SparseMat_<_Tp>::SparseMat_()
|
||||
{
|
||||
flags = MAGIC_VAL | traits::Type<_Tp>::value;
|
||||
flags = MAGIC_VAL + traits::Type<_Tp>::value;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
@@ -3654,7 +3654,7 @@ UMat::UMat(const UMat& m)
|
||||
|
||||
template<typename _Tp> inline
|
||||
UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
|
||||
: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
|
||||
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
|
||||
cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
|
||||
{
|
||||
if(vec.empty())
|
||||
|
||||
@@ -59,7 +59,7 @@ CV_EXPORTS_W void finish();
|
||||
CV_EXPORTS bool haveSVM();
|
||||
|
||||
class CV_EXPORTS Context;
|
||||
class CV_EXPORTS Device;
|
||||
class CV_EXPORTS_W_SIMPLE Device;
|
||||
class CV_EXPORTS Kernel;
|
||||
class CV_EXPORTS Program;
|
||||
class CV_EXPORTS ProgramSource;
|
||||
@@ -67,14 +67,14 @@ class CV_EXPORTS Queue;
|
||||
class CV_EXPORTS PlatformInfo;
|
||||
class CV_EXPORTS Image2D;
|
||||
|
||||
class CV_EXPORTS Device
|
||||
class CV_EXPORTS_W_SIMPLE Device
|
||||
{
|
||||
public:
|
||||
Device();
|
||||
CV_WRAP Device();
|
||||
explicit Device(void* d);
|
||||
Device(const Device& d);
|
||||
Device& operator = (const Device& d);
|
||||
~Device();
|
||||
CV_WRAP ~Device();
|
||||
|
||||
void set(void* d);
|
||||
|
||||
@@ -89,24 +89,24 @@ public:
|
||||
TYPE_ALL = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
String name() const;
|
||||
String extensions() const;
|
||||
bool isExtensionSupported(const String& extensionName) const;
|
||||
String version() const;
|
||||
String vendorName() const;
|
||||
String OpenCL_C_Version() const;
|
||||
String OpenCLVersion() const;
|
||||
int deviceVersionMajor() const;
|
||||
int deviceVersionMinor() const;
|
||||
String driverVersion() const;
|
||||
CV_WRAP String name() const;
|
||||
CV_WRAP String extensions() const;
|
||||
CV_WRAP bool isExtensionSupported(const String& extensionName) const;
|
||||
CV_WRAP String version() const;
|
||||
CV_WRAP String vendorName() const;
|
||||
CV_WRAP String OpenCL_C_Version() const;
|
||||
CV_WRAP String OpenCLVersion() const;
|
||||
CV_WRAP int deviceVersionMajor() const;
|
||||
CV_WRAP int deviceVersionMinor() const;
|
||||
CV_WRAP String driverVersion() const;
|
||||
void* ptr() const;
|
||||
|
||||
int type() const;
|
||||
CV_WRAP int type() const;
|
||||
|
||||
int addressBits() const;
|
||||
bool available() const;
|
||||
bool compilerAvailable() const;
|
||||
bool linkerAvailable() const;
|
||||
CV_WRAP int addressBits() const;
|
||||
CV_WRAP bool available() const;
|
||||
CV_WRAP bool compilerAvailable() const;
|
||||
CV_WRAP bool linkerAvailable() const;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -119,21 +119,21 @@ public:
|
||||
FP_SOFT_FLOAT=(1 << 6),
|
||||
FP_CORRECTLY_ROUNDED_DIVIDE_SQRT=(1 << 7)
|
||||
};
|
||||
int doubleFPConfig() const;
|
||||
int singleFPConfig() const;
|
||||
int halfFPConfig() const;
|
||||
CV_WRAP int doubleFPConfig() const;
|
||||
CV_WRAP int singleFPConfig() const;
|
||||
CV_WRAP int halfFPConfig() const;
|
||||
|
||||
bool endianLittle() const;
|
||||
bool errorCorrectionSupport() const;
|
||||
CV_WRAP bool endianLittle() const;
|
||||
CV_WRAP bool errorCorrectionSupport() const;
|
||||
|
||||
enum
|
||||
{
|
||||
EXEC_KERNEL=(1 << 0),
|
||||
EXEC_NATIVE_KERNEL=(1 << 1)
|
||||
};
|
||||
int executionCapabilities() const;
|
||||
CV_WRAP int executionCapabilities() const;
|
||||
|
||||
size_t globalMemCacheSize() const;
|
||||
CV_WRAP size_t globalMemCacheSize() const;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -141,38 +141,38 @@ public:
|
||||
READ_ONLY_CACHE=1,
|
||||
READ_WRITE_CACHE=2
|
||||
};
|
||||
int globalMemCacheType() const;
|
||||
int globalMemCacheLineSize() const;
|
||||
size_t globalMemSize() const;
|
||||
CV_WRAP int globalMemCacheType() const;
|
||||
CV_WRAP int globalMemCacheLineSize() const;
|
||||
CV_WRAP size_t globalMemSize() const;
|
||||
|
||||
size_t localMemSize() const;
|
||||
CV_WRAP size_t localMemSize() const;
|
||||
enum
|
||||
{
|
||||
NO_LOCAL_MEM=0,
|
||||
LOCAL_IS_LOCAL=1,
|
||||
LOCAL_IS_GLOBAL=2
|
||||
};
|
||||
int localMemType() const;
|
||||
bool hostUnifiedMemory() const;
|
||||
CV_WRAP int localMemType() const;
|
||||
CV_WRAP bool hostUnifiedMemory() const;
|
||||
|
||||
bool imageSupport() const;
|
||||
CV_WRAP bool imageSupport() const;
|
||||
|
||||
bool imageFromBufferSupport() const;
|
||||
CV_WRAP bool imageFromBufferSupport() const;
|
||||
uint imagePitchAlignment() const;
|
||||
uint imageBaseAddressAlignment() const;
|
||||
|
||||
/// deprecated, use isExtensionSupported() method (probably with "cl_khr_subgroups" value)
|
||||
bool intelSubgroupsSupport() const;
|
||||
CV_WRAP bool intelSubgroupsSupport() const;
|
||||
|
||||
size_t image2DMaxWidth() const;
|
||||
size_t image2DMaxHeight() const;
|
||||
CV_WRAP size_t image2DMaxWidth() const;
|
||||
CV_WRAP size_t image2DMaxHeight() const;
|
||||
|
||||
size_t image3DMaxWidth() const;
|
||||
size_t image3DMaxHeight() const;
|
||||
size_t image3DMaxDepth() const;
|
||||
CV_WRAP size_t image3DMaxWidth() const;
|
||||
CV_WRAP size_t image3DMaxHeight() const;
|
||||
CV_WRAP size_t image3DMaxDepth() const;
|
||||
|
||||
size_t imageMaxBufferSize() const;
|
||||
size_t imageMaxArraySize() const;
|
||||
CV_WRAP size_t imageMaxBufferSize() const;
|
||||
CV_WRAP size_t imageMaxArraySize() const;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -181,53 +181,53 @@ public:
|
||||
VENDOR_INTEL=2,
|
||||
VENDOR_NVIDIA=3
|
||||
};
|
||||
int vendorID() const;
|
||||
CV_WRAP int vendorID() const;
|
||||
// FIXIT
|
||||
// dev.isAMD() doesn't work for OpenCL CPU devices from AMD OpenCL platform.
|
||||
// This method should use platform name instead of vendor name.
|
||||
// After fix restore code in arithm.cpp: ocl_compare()
|
||||
inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
|
||||
inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }
|
||||
inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; }
|
||||
CV_WRAP inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
|
||||
CV_WRAP inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }
|
||||
CV_WRAP inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; }
|
||||
|
||||
int maxClockFrequency() const;
|
||||
int maxComputeUnits() const;
|
||||
int maxConstantArgs() const;
|
||||
size_t maxConstantBufferSize() const;
|
||||
CV_WRAP int maxClockFrequency() const;
|
||||
CV_WRAP int maxComputeUnits() const;
|
||||
CV_WRAP int maxConstantArgs() const;
|
||||
CV_WRAP size_t maxConstantBufferSize() const;
|
||||
|
||||
size_t maxMemAllocSize() const;
|
||||
size_t maxParameterSize() const;
|
||||
CV_WRAP size_t maxMemAllocSize() const;
|
||||
CV_WRAP size_t maxParameterSize() const;
|
||||
|
||||
int maxReadImageArgs() const;
|
||||
int maxWriteImageArgs() const;
|
||||
int maxSamplers() const;
|
||||
CV_WRAP int maxReadImageArgs() const;
|
||||
CV_WRAP int maxWriteImageArgs() const;
|
||||
CV_WRAP int maxSamplers() const;
|
||||
|
||||
size_t maxWorkGroupSize() const;
|
||||
int maxWorkItemDims() const;
|
||||
CV_WRAP size_t maxWorkGroupSize() const;
|
||||
CV_WRAP int maxWorkItemDims() const;
|
||||
void maxWorkItemSizes(size_t*) const;
|
||||
|
||||
int memBaseAddrAlign() const;
|
||||
CV_WRAP int memBaseAddrAlign() const;
|
||||
|
||||
int nativeVectorWidthChar() const;
|
||||
int nativeVectorWidthShort() const;
|
||||
int nativeVectorWidthInt() const;
|
||||
int nativeVectorWidthLong() const;
|
||||
int nativeVectorWidthFloat() const;
|
||||
int nativeVectorWidthDouble() const;
|
||||
int nativeVectorWidthHalf() const;
|
||||
CV_WRAP int nativeVectorWidthChar() const;
|
||||
CV_WRAP int nativeVectorWidthShort() const;
|
||||
CV_WRAP int nativeVectorWidthInt() const;
|
||||
CV_WRAP int nativeVectorWidthLong() const;
|
||||
CV_WRAP int nativeVectorWidthFloat() const;
|
||||
CV_WRAP int nativeVectorWidthDouble() const;
|
||||
CV_WRAP int nativeVectorWidthHalf() const;
|
||||
|
||||
int preferredVectorWidthChar() const;
|
||||
int preferredVectorWidthShort() const;
|
||||
int preferredVectorWidthInt() const;
|
||||
int preferredVectorWidthLong() const;
|
||||
int preferredVectorWidthFloat() const;
|
||||
int preferredVectorWidthDouble() const;
|
||||
int preferredVectorWidthHalf() const;
|
||||
CV_WRAP int preferredVectorWidthChar() const;
|
||||
CV_WRAP int preferredVectorWidthShort() const;
|
||||
CV_WRAP int preferredVectorWidthInt() const;
|
||||
CV_WRAP int preferredVectorWidthLong() const;
|
||||
CV_WRAP int preferredVectorWidthFloat() const;
|
||||
CV_WRAP int preferredVectorWidthDouble() const;
|
||||
CV_WRAP int preferredVectorWidthHalf() const;
|
||||
|
||||
size_t printfBufferSize() const;
|
||||
size_t profilingTimerResolution() const;
|
||||
CV_WRAP size_t printfBufferSize() const;
|
||||
CV_WRAP size_t profilingTimerResolution() const;
|
||||
|
||||
static const Device& getDefault();
|
||||
CV_WRAP static const Device& getDefault();
|
||||
|
||||
protected:
|
||||
struct Impl;
|
||||
@@ -352,7 +352,8 @@ public:
|
||||
KernelArg(int _flags, UMat* _m, int wscale=1, int iwscale=1, const void* _obj=0, size_t _sz=0);
|
||||
KernelArg();
|
||||
|
||||
static KernelArg Local() { return KernelArg(LOCAL, 0); }
|
||||
static KernelArg Local(size_t localMemSize)
|
||||
{ return KernelArg(LOCAL, 0, 1, 1, 0, localMemSize); }
|
||||
static KernelArg PtrWriteOnly(const UMat& m)
|
||||
{ return KernelArg(PTR_ONLY+WRITE_ONLY, (UMat*)&m); }
|
||||
static KernelArg PtrReadOnly(const UMat& m)
|
||||
|
||||
@@ -59,11 +59,18 @@ static inline bool isOpenCLActivated() { return false; }
|
||||
}
|
||||
#else
|
||||
#define CV_OCL_RUN_(condition, func, ...) \
|
||||
try \
|
||||
{ \
|
||||
if (cv::ocl::isOpenCLActivated() && (condition) && func) \
|
||||
{ \
|
||||
CV_IMPL_ADD(CV_IMPL_OCL); \
|
||||
return __VA_ARGS__; \
|
||||
}
|
||||
} \
|
||||
} \
|
||||
catch (const cv::Exception& e) \
|
||||
{ \
|
||||
CV_UNUSED(e); /* TODO: Add some logging here */ \
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -548,7 +548,7 @@ calling unmapGLBuffer() function.
|
||||
@param accessFlags - data access flags (ACCESS_READ|ACCESS_WRITE).
|
||||
@return Returns UMat object
|
||||
*/
|
||||
CV_EXPORTS UMat mapGLBuffer(const Buffer& buffer, int accessFlags = ACCESS_READ|ACCESS_WRITE);
|
||||
CV_EXPORTS UMat mapGLBuffer(const Buffer& buffer, AccessFlag accessFlags = ACCESS_READ | ACCESS_WRITE);
|
||||
|
||||
/** @brief Unmaps Buffer object (releases UMat, previously mapped from Buffer).
|
||||
|
||||
@@ -558,13 +558,11 @@ by the call to mapGLBuffer() function.
|
||||
*/
|
||||
CV_EXPORTS void unmapGLBuffer(UMat& u);
|
||||
|
||||
//! @}
|
||||
}} // namespace cv::ogl
|
||||
|
||||
namespace cv { namespace cuda {
|
||||
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
|
||||
/** @brief Sets a CUDA device and initializes it for the current thread with OpenGL interoperability.
|
||||
|
||||
This function should be explicitly called after OpenGL context creation and before any CUDA calls.
|
||||
@@ -573,8 +571,6 @@ This function should be explicitly called after OpenGL context creation and befo
|
||||
*/
|
||||
CV_EXPORTS void setGlDevice(int device = 0);
|
||||
|
||||
//! @}
|
||||
|
||||
}}
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__) // at least GCC 3.1+, clang 3.5+
|
||||
# define CV_FORMAT_PRINTF(string_idx, first_to_check) __attribute__ ((format (printf, string_idx, first_to_check)))
|
||||
#else
|
||||
# define CV_FORMAT_PRINTF(A, B)
|
||||
#endif
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv
|
||||
@@ -386,13 +392,24 @@ template<typename _Tp> static inline _Tp randu()
|
||||
The function acts like sprintf but forms and returns an STL string. It can be used to form an error
|
||||
message in the Exception constructor.
|
||||
@param fmt printf-compatible formatting specifiers.
|
||||
|
||||
**Note**:
|
||||
|Type|Specifier|
|
||||
|-|-|
|
||||
|`const char*`|`%s`|
|
||||
|`char`|`%c`|
|
||||
|`float` / `double`|`%f`,`%g`|
|
||||
|`int`, `long`, `long long`|`%d`, `%ld`, ``%lld`|
|
||||
|`unsigned`, `unsigned long`, `unsigned long long`|`%u`, `%lu`, `%llu`|
|
||||
|`uint64` -> `uintmax_t`, `int64` -> `intmax_t`|`%ju`, `%jd`|
|
||||
|`size_t`|`%zu`|
|
||||
*/
|
||||
CV_EXPORTS String format( const char* fmt, ... );
|
||||
CV_EXPORTS String format( const char* fmt, ... ) CV_FORMAT_PRINTF(1, 2);
|
||||
|
||||
///////////////////////////////// Formatted output of cv::Mat /////////////////////////////////
|
||||
|
||||
static inline
|
||||
Ptr<Formatted> format(InputArray mtx, int fmt)
|
||||
Ptr<Formatted> format(InputArray mtx, Formatter::FormatType fmt)
|
||||
{
|
||||
return Formatter::get(fmt)->format(mtx.getMat());
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ and the remaining to \f$A\f$. It should contain 32- or 64-bit floating point num
|
||||
formulation above. It will contain 64-bit floating point numbers.
|
||||
@return One of cv::SolveLPResult
|
||||
*/
|
||||
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
|
||||
CV_EXPORTS_W int solveLP(InputArray Func, InputArray Constr, OutputArray z);
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
@@ -544,6 +544,11 @@ public:
|
||||
*/
|
||||
CV_WRAP_AS(at) FileNode operator[](int i) const;
|
||||
|
||||
/** @brief Returns keys of a mapping node.
|
||||
@returns Keys of a mapping node.
|
||||
*/
|
||||
CV_WRAP std::vector<String> keys() const;
|
||||
|
||||
/** @brief Returns type of the node.
|
||||
@returns Type of the node. See FileNode::Type
|
||||
*/
|
||||
@@ -1049,6 +1054,12 @@ void write(FileStorage& fs, const String& name, const DMatch& m)
|
||||
write(fs, m.distance);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type* = nullptr>
|
||||
static inline void write( FileStorage& fs, const String& name, const _Tp& val )
|
||||
{
|
||||
write(fs, name, static_cast<int>(val));
|
||||
}
|
||||
|
||||
template<typename _Tp> static inline
|
||||
void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
|
||||
{
|
||||
@@ -1137,6 +1148,14 @@ void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_
|
||||
r(vec, maxCount);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type* = nullptr>
|
||||
static inline void read(const FileNode& node, _Tp& value, const _Tp& default_value = static_cast<_Tp>(0))
|
||||
{
|
||||
int temp;
|
||||
read(node, temp, static_cast<int>(default_value));
|
||||
value = static_cast<_Tp>(temp);
|
||||
}
|
||||
|
||||
template<typename _Tp> static inline
|
||||
void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() )
|
||||
{
|
||||
|
||||
@@ -142,9 +142,13 @@ namespace cv
|
||||
CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
|
||||
|
||||
//! Allocate all memory buffers which will not be freed, ease filtering memcheck issues
|
||||
template <typename T>
|
||||
T* allocSingleton(size_t count) { return static_cast<T*>(fastMalloc(sizeof(T) * count)); }
|
||||
}
|
||||
CV_EXPORTS void* allocSingletonBuffer(size_t size);
|
||||
|
||||
//! Allocate all memory buffers which will not be freed, ease filtering memcheck issues
|
||||
template <typename T> static inline
|
||||
T* allocSingleton(size_t count = 1) { return static_cast<T*>(allocSingletonBuffer(sizeof(T) * count)); }
|
||||
|
||||
} // namespace
|
||||
|
||||
#if 1 // TODO: Remove in OpenCV 4.x
|
||||
|
||||
@@ -704,12 +708,12 @@ CV_EXPORTS InstrNode* getCurrentNode();
|
||||
if(::cv::instr::useInstrumentation()){\
|
||||
::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
|
||||
try{\
|
||||
auto status = ((FUN)(__VA_ARGS__));\
|
||||
auto instrStatus = ((FUN)(__VA_ARGS__));\
|
||||
if(ERROR_COND){\
|
||||
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
|
||||
CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
|
||||
}\
|
||||
return status;\
|
||||
return instrStatus;\
|
||||
}catch(...){\
|
||||
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
|
||||
CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
|
||||
@@ -750,7 +754,7 @@ CV_EXPORTS InstrNode* getCurrentNode();
|
||||
// Wrapper region instrumentation macro
|
||||
#define CV_INSTRUMENT_REGION_IPP(); CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
|
||||
// Function instrumentation macro
|
||||
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, status < 0, FUN, __VA_ARGS__)
|
||||
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, instrStatus < 0, FUN, __VA_ARGS__)
|
||||
// Diagnostic markers
|
||||
#define CV_INSTRUMENT_MARK_IPP(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)
|
||||
|
||||
|
||||
@@ -58,7 +58,9 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
#if !defined(_M_CEE)
|
||||
#include <mutex> // std::mutex, std::lock_guard
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -674,8 +676,10 @@ void Mat::forEach_impl(const Functor& operation) {
|
||||
|
||||
/////////////////////////// Synchronization Primitives ///////////////////////////////
|
||||
|
||||
#if !defined(_M_CEE)
|
||||
typedef std::recursive_mutex Mutex;
|
||||
typedef std::lock_guard<cv::Mutex> AutoLock;
|
||||
#endif
|
||||
|
||||
// TLS interface
|
||||
class CV_EXPORTS TLSDataContainer
|
||||
@@ -943,8 +947,8 @@ public:
|
||||
void printErrors() const;
|
||||
|
||||
protected:
|
||||
void getByName(const String& name, bool space_delete, int type, void* dst) const;
|
||||
void getByIndex(int index, bool space_delete, int type, void* dst) const;
|
||||
void getByName(const String& name, bool space_delete, Param type, void* dst) const;
|
||||
void getByIndex(int index, bool space_delete, Param type, void* dst) const;
|
||||
|
||||
struct Impl;
|
||||
Impl* impl;
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
#ifndef OPENCV_CONFIGURATION_PRIVATE_HPP
|
||||
#define OPENCV_CONFIGURATION_PRIVATE_HPP
|
||||
|
||||
#include "opencv2/core/cvstd.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace cv { namespace utils {
|
||||
|
||||
typedef std::vector<std::string> Paths;
|
||||
CV_EXPORTS bool getConfigurationParameterBool(const char* name, bool defaultValue);
|
||||
CV_EXPORTS size_t getConfigurationParameterSizeT(const char* name, size_t defaultValue);
|
||||
CV_EXPORTS cv::String getConfigurationParameterString(const char* name, const char* defaultValue);
|
||||
CV_EXPORTS Paths getConfigurationParameterPaths(const char* name, const Paths &defaultValue = Paths());
|
||||
|
||||
}} // namespace
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace trace {
|
||||
//! @cond IGNORED
|
||||
#define CV_TRACE_NS cv::utils::trace
|
||||
|
||||
#if !defined(OPENCV_DISABLE_TRACE) && defined(__EMSCRIPTEN__)
|
||||
#define OPENCV_DISABLE_TRACE 1
|
||||
#endif
|
||||
|
||||
namespace details {
|
||||
|
||||
#ifndef __OPENCV_TRACE
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define CV_VERSION_MAJOR 4
|
||||
#define CV_VERSION_MINOR 0
|
||||
#define CV_VERSION_REVISION 0
|
||||
#define CV_VERSION_STATUS "-alpha"
|
||||
#define CV_VERSION_STATUS "-beta"
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -130,19 +130,21 @@ VSX_FINLINE(rt) fnm(const rg& a, const rg& b) \
|
||||
# undef vec_mul
|
||||
# endif
|
||||
/*
|
||||
* there's no a direct instruction for supporting 16-bit multiplication in ISA 2.07,
|
||||
* there's no a direct instruction for supporting 8-bit, 16-bit multiplication in ISA 2.07,
|
||||
* XLC Implement it by using instruction "multiply even", "multiply odd" and "permute"
|
||||
* todo: Do I need to support 8-bit ?
|
||||
**/
|
||||
# define VSX_IMPL_MULH(Tvec, Tcast) \
|
||||
VSX_FINLINE(Tvec) vec_mul(const Tvec& a, const Tvec& b) \
|
||||
{ \
|
||||
static const vec_uchar16 even_perm = {0, 1, 16, 17, 4, 5, 20, 21, \
|
||||
8, 9, 24, 25, 12, 13, 28, 29}; \
|
||||
return vec_perm(Tcast(vec_mule(a, b)), Tcast(vec_mulo(a, b)), even_perm); \
|
||||
# define VSX_IMPL_MULH(Tvec, cperm) \
|
||||
VSX_FINLINE(Tvec) vec_mul(const Tvec& a, const Tvec& b) \
|
||||
{ \
|
||||
static const vec_uchar16 ev_od = {cperm}; \
|
||||
return vec_perm((Tvec)vec_mule(a, b), (Tvec)vec_mulo(a, b), ev_od); \
|
||||
}
|
||||
VSX_IMPL_MULH(vec_short8, vec_short8_c)
|
||||
VSX_IMPL_MULH(vec_ushort8, vec_ushort8_c)
|
||||
#define VSX_IMPL_MULH_P16 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30
|
||||
VSX_IMPL_MULH(vec_char16, VSX_IMPL_MULH_P16)
|
||||
VSX_IMPL_MULH(vec_uchar16, VSX_IMPL_MULH_P16)
|
||||
#define VSX_IMPL_MULH_P8 0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29
|
||||
VSX_IMPL_MULH(vec_short8, VSX_IMPL_MULH_P8)
|
||||
VSX_IMPL_MULH(vec_ushort8, VSX_IMPL_MULH_P8)
|
||||
// vmuluwm can be used for unsigned or signed integers, that's what they said
|
||||
VSX_IMPL_2VRG(vec_int4, vec_int4, vmuluwm, vec_mul)
|
||||
VSX_IMPL_2VRG(vec_uint4, vec_uint4, vmuluwm, vec_mul)
|
||||
|
||||
+13
-6
@@ -7,6 +7,19 @@ typedef cuda::GpuMat::Allocator GpuMat_Allocator;
|
||||
typedef cuda::HostMem::AllocType HostMem_AllocType;
|
||||
typedef cuda::Event::CreateFlags Event_CreateFlags;
|
||||
|
||||
template<> struct pyopencvVecConverter<cuda::GpuMat>
|
||||
{
|
||||
static bool to(PyObject* obj, std::vector<cuda::GpuMat>& value, const ArgInfo info)
|
||||
{
|
||||
return pyopencv_to_generic_vec(obj, value, info);
|
||||
}
|
||||
|
||||
static PyObject* from(const std::vector<cuda::GpuMat>& value)
|
||||
{
|
||||
return pyopencv_from_generic_vec(value);
|
||||
}
|
||||
};
|
||||
|
||||
CV_PY_TO_CLASS(cuda::GpuMat);
|
||||
CV_PY_TO_CLASS(cuda::Stream);
|
||||
CV_PY_TO_CLASS(cuda::Event);
|
||||
@@ -15,16 +28,10 @@ CV_PY_TO_CLASS(cuda::HostMem);
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMat);
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMat::Allocator);
|
||||
|
||||
CV_PY_TO_ENUM(cuda::Event::CreateFlags);
|
||||
CV_PY_TO_ENUM(cuda::HostMem::AllocType);
|
||||
CV_PY_TO_ENUM(cuda::FeatureSet);
|
||||
|
||||
CV_PY_FROM_CLASS(cuda::GpuMat);
|
||||
CV_PY_FROM_CLASS(cuda::Stream);
|
||||
CV_PY_FROM_CLASS(cuda::HostMem);
|
||||
|
||||
CV_PY_FROM_CLASS_PTR(cuda::GpuMat::Allocator);
|
||||
|
||||
CV_PY_FROM_ENUM(cuda::DeviceInfo::ComputeMode);
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,6 @@ typedef std::vector<Range> vector_Range;
|
||||
|
||||
CV_PY_TO_CLASS(UMat);
|
||||
CV_PY_FROM_CLASS(UMat);
|
||||
CV_PY_TO_ENUM(UMatUsageFlags);
|
||||
|
||||
static bool cv_mappable_to(const Ptr<Mat>& src, Ptr<UMat>& dst)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
The UMat instance should be kept alive during the use of the handle to prevent the buffer to be
|
||||
returned to the OpenCV buffer pool.
|
||||
*/
|
||||
CV_WRAP void* handle(int accessFlags) const;
|
||||
CV_WRAP void* handle(AccessFlag accessFlags) const;
|
||||
|
||||
// offset of the submatrix (or 0)
|
||||
CV_PROP_RW size_t offset;
|
||||
|
||||
+20
-16
@@ -105,14 +105,18 @@ static bool ocl_binary_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
int scalarcn = kercn == 3 ? 4 : kercn;
|
||||
int rowsPerWI = d.isIntel() ? 4 : 1;
|
||||
|
||||
sprintf(opts, "-D %s%s -D %s -D dstT=%s%s -D dstT_C1=%s -D workST=%s -D cn=%d -D rowsPerWI=%d",
|
||||
const int dstDepth = srcdepth;
|
||||
const int dstType = CV_MAKETYPE(dstDepth, kercn);
|
||||
const int dstType1 = CV_MAKETYPE(dstDepth, 1);
|
||||
const int scalarType = CV_MAKETYPE(srcdepth, scalarcn);
|
||||
|
||||
sprintf(opts, "-D %s%s -D %s%s -D dstT=%s -D DEPTH_dst=%d -D dstT_C1=%s -D workST=%s -D cn=%d -D rowsPerWI=%d",
|
||||
haveMask ? "MASK_" : "", haveScalar ? "UNARY_OP" : "BINARY_OP", oclop2str[oclop],
|
||||
bitwise ? ocl::memopTypeToStr(CV_MAKETYPE(srcdepth, kercn)) :
|
||||
ocl::typeToStr(CV_MAKETYPE(srcdepth, kercn)), doubleSupport ? " -D DOUBLE_SUPPORT" : "",
|
||||
bitwise ? ocl::memopTypeToStr(CV_MAKETYPE(srcdepth, 1)) :
|
||||
ocl::typeToStr(CV_MAKETYPE(srcdepth, 1)),
|
||||
bitwise ? ocl::memopTypeToStr(CV_MAKETYPE(srcdepth, scalarcn)) :
|
||||
ocl::typeToStr(CV_MAKETYPE(srcdepth, scalarcn)),
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : "",
|
||||
bitwise ? ocl::memopTypeToStr(dstType) : ocl::typeToStr(dstType),
|
||||
dstDepth,
|
||||
bitwise ? ocl::memopTypeToStr(dstType1) : ocl::typeToStr(dstType1),
|
||||
bitwise ? ocl::memopTypeToStr(scalarType) : ocl::typeToStr(scalarType),
|
||||
kercn, rowsPerWI);
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc, opts);
|
||||
@@ -167,7 +171,7 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
bool bitwise, int oclop )
|
||||
{
|
||||
const _InputArray *psrc1 = &_src1, *psrc2 = &_src2;
|
||||
int kind1 = psrc1->kind(), kind2 = psrc2->kind();
|
||||
_InputArray::KindFlag kind1 = psrc1->kind(), kind2 = psrc2->kind();
|
||||
int type1 = psrc1->type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1);
|
||||
int type2 = psrc2->type(), depth2 = CV_MAT_DEPTH(type2), cn2 = CV_MAT_CN(type2);
|
||||
int dims1 = psrc1->dims(), dims2 = psrc2->dims();
|
||||
@@ -501,12 +505,12 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
|
||||
char cvtstr[4][32], opts[1024];
|
||||
sprintf(opts, "-D %s%s -D %s -D srcT1=%s -D srcT1_C1=%s -D srcT2=%s -D srcT2_C1=%s "
|
||||
"-D dstT=%s -D dstT_C1=%s -D workT=%s -D workST=%s -D scaleT=%s -D wdepth=%d -D convertToWT1=%s "
|
||||
"-D dstT=%s -D DEPTH_dst=%d -D dstT_C1=%s -D workT=%s -D workST=%s -D scaleT=%s -D wdepth=%d -D convertToWT1=%s "
|
||||
"-D convertToWT2=%s -D convertToDT=%s%s -D cn=%d -D rowsPerWI=%d -D convertFromU=%s",
|
||||
(haveMask ? "MASK_" : ""), (haveScalar ? "UNARY_OP" : "BINARY_OP"),
|
||||
oclop2str[oclop], ocl::typeToStr(CV_MAKETYPE(depth1, kercn)),
|
||||
ocl::typeToStr(depth1), ocl::typeToStr(CV_MAKETYPE(depth2, kercn)),
|
||||
ocl::typeToStr(depth2), ocl::typeToStr(CV_MAKETYPE(ddepth, kercn)),
|
||||
ocl::typeToStr(depth2), ocl::typeToStr(CV_MAKETYPE(ddepth, kercn)), ddepth,
|
||||
ocl::typeToStr(ddepth), ocl::typeToStr(CV_MAKETYPE(wdepth, kercn)),
|
||||
ocl::typeToStr(CV_MAKETYPE(wdepth, scalarcn)),
|
||||
ocl::typeToStr(wdepth), wdepth,
|
||||
@@ -600,7 +604,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
void* usrdata=0, int oclop=-1 )
|
||||
{
|
||||
const _InputArray *psrc1 = &_src1, *psrc2 = &_src2;
|
||||
int kind1 = psrc1->kind(), kind2 = psrc2->kind();
|
||||
_InputArray::KindFlag kind1 = psrc1->kind(), kind2 = psrc2->kind();
|
||||
bool haveMask = !_mask.empty();
|
||||
bool reallocate = false;
|
||||
int type1 = psrc1->type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1);
|
||||
@@ -1099,12 +1103,12 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
|
||||
const char * const operationMap[] = { "==", ">", ">=", "<", "<=", "!=" };
|
||||
char cvt[40];
|
||||
|
||||
String opts = format("-D %s -D srcT1=%s -D dstT=%s -D workT=srcT1 -D cn=%d"
|
||||
String opts = format("-D %s -D srcT1=%s -D dstT=%s -D DEPTH_dst=%d -D workT=srcT1 -D cn=%d"
|
||||
" -D convertToDT=%s -D OP_CMP -D CMP_OPERATOR=%s -D srcT1_C1=%s"
|
||||
" -D srcT2_C1=%s -D dstT_C1=%s -D workST=%s -D rowsPerWI=%d%s",
|
||||
haveScalar ? "UNARY_OP" : "BINARY_OP",
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth1, kercn)),
|
||||
ocl::typeToStr(CV_8UC(kercn)), kercn,
|
||||
ocl::typeToStr(CV_8UC(kercn)), CV_8U, kercn,
|
||||
ocl::convertTypeStr(depth1, CV_8U, kercn, cvt),
|
||||
operationMap[op], ocl::typeToStr(depth1),
|
||||
ocl::typeToStr(depth1), ocl::typeToStr(CV_8U),
|
||||
@@ -1214,7 +1218,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
|
||||
CV_OCL_RUN(_src1.dims() <= 2 && _src2.dims() <= 2 && OCL_PERFORMANCE_CHECK(_dst.isUMat()),
|
||||
ocl_compare(_src1, _src2, _dst, op, haveScalar))
|
||||
|
||||
int kind1 = _src1.kind(), kind2 = _src2.kind();
|
||||
_InputArray::KindFlag kind1 = _src1.kind(), kind2 = _src2.kind();
|
||||
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
|
||||
|
||||
if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 && src1.size() == src2.size() && src1.type() == src2.type() )
|
||||
@@ -1587,7 +1591,7 @@ static bool ocl_inRange( InputArray _src, InputArray _lowerb,
|
||||
InputArray _upperb, OutputArray _dst )
|
||||
{
|
||||
const ocl::Device & d = ocl::Device::getDefault();
|
||||
int skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
|
||||
_InputArray::KindFlag skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
|
||||
Size ssize = _src.size(), lsize = _lowerb.size(), usize = _upperb.size();
|
||||
int stype = _src.type(), ltype = _lowerb.type(), utype = _upperb.type();
|
||||
int sdepth = CV_MAT_DEPTH(stype), ldepth = CV_MAT_DEPTH(ltype), udepth = CV_MAT_DEPTH(utype);
|
||||
@@ -1712,7 +1716,7 @@ void cv::inRange(InputArray _src, InputArray _lowerb,
|
||||
_upperb.dims() <= 2 && OCL_PERFORMANCE_CHECK(_dst.isUMat()),
|
||||
ocl_inRange(_src, _lowerb, _upperb, _dst))
|
||||
|
||||
int skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
|
||||
_InputArray::KindFlag skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
|
||||
Mat src = _src.getMat(), lb = _lowerb.getMat(), ub = _upperb.getMat();
|
||||
|
||||
bool lbScalar = false, ubScalar = false;
|
||||
|
||||
@@ -516,7 +516,10 @@ div_i( const T* src1, size_t step1, const T* src2, size_t step2,
|
||||
for( ; i < width; i++ )
|
||||
{
|
||||
T num = src1[i], denom = src2[i];
|
||||
dst[i] = denom != 0 ? saturate_cast<T>(num*scale_f/denom) : (T)0;
|
||||
T v = 0;
|
||||
if (denom != 0)
|
||||
v = saturate_cast<T>(num*scale_f/denom);
|
||||
dst[i] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -538,7 +541,7 @@ div_f( const T* src1, size_t step1, const T* src2, size_t step2,
|
||||
for( ; i < width; i++ )
|
||||
{
|
||||
T num = src1[i], denom = src2[i];
|
||||
dst[i] = denom != 0 ? saturate_cast<T>(num*scale_f/denom) : (T)0;
|
||||
dst[i] = saturate_cast<T>(num*scale_f/denom);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,7 +562,10 @@ recip_i( const T* src2, size_t step2,
|
||||
for( ; i < width; i++ )
|
||||
{
|
||||
T denom = src2[i];
|
||||
dst[i] = denom != 0 ? saturate_cast<T>(scale_f/denom) : (T)0;
|
||||
T v = 0;
|
||||
if (denom != 0)
|
||||
v = saturate_cast<T>(scale_f/denom);
|
||||
dst[i] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,7 +586,7 @@ recip_f( const T* src2, size_t step2,
|
||||
for( ; i < width; i++ )
|
||||
{
|
||||
T denom = src2[i];
|
||||
dst[i] = denom != 0 ? saturate_cast<T>(scale_f/denom) : (T)0;
|
||||
dst[i] = saturate_cast<T>(scale_f/denom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1433,7 +1433,6 @@ struct Div_SIMD<float>
|
||||
return x;
|
||||
|
||||
v_float32x4 v_scale = v_setall_f32((float)scale);
|
||||
v_float32x4 v_zero = v_setzero_f32();
|
||||
|
||||
for ( ; x <= width - 8; x += 8)
|
||||
{
|
||||
@@ -1445,9 +1444,6 @@ struct Div_SIMD<float>
|
||||
v_float32x4 res0 = f0 * v_scale / f2;
|
||||
v_float32x4 res1 = f1 * v_scale / f3;
|
||||
|
||||
res0 = v_select(f2 == v_zero, v_zero, res0);
|
||||
res1 = v_select(f3 == v_zero, v_zero, res1);
|
||||
|
||||
v_store(dst + x, res0);
|
||||
v_store(dst + x + 4, res1);
|
||||
}
|
||||
@@ -1675,7 +1671,6 @@ struct Recip_SIMD<float>
|
||||
return x;
|
||||
|
||||
v_float32x4 v_scale = v_setall_f32((float)scale);
|
||||
v_float32x4 v_zero = v_setzero_f32();
|
||||
|
||||
for ( ; x <= width - 8; x += 8)
|
||||
{
|
||||
@@ -1685,9 +1680,6 @@ struct Recip_SIMD<float>
|
||||
v_float32x4 res0 = v_scale / f0;
|
||||
v_float32x4 res1 = v_scale / f1;
|
||||
|
||||
res0 = v_select(f0 == v_zero, v_zero, res0);
|
||||
res1 = v_select(f1 == v_zero, v_zero, res1);
|
||||
|
||||
v_store(dst + x, res0);
|
||||
v_store(dst + x + 4, res1);
|
||||
}
|
||||
@@ -1712,7 +1704,6 @@ struct Div_SIMD<double>
|
||||
return x;
|
||||
|
||||
v_float64x2 v_scale = v_setall_f64(scale);
|
||||
v_float64x2 v_zero = v_setzero_f64();
|
||||
|
||||
for ( ; x <= width - 4; x += 4)
|
||||
{
|
||||
@@ -1724,9 +1715,6 @@ struct Div_SIMD<double>
|
||||
v_float64x2 res0 = f0 * v_scale / f2;
|
||||
v_float64x2 res1 = f1 * v_scale / f3;
|
||||
|
||||
res0 = v_select(f2 == v_zero, v_zero, res0);
|
||||
res1 = v_select(f3 == v_zero, v_zero, res1);
|
||||
|
||||
v_store(dst + x, res0);
|
||||
v_store(dst + x + 2, res1);
|
||||
}
|
||||
@@ -1749,7 +1737,6 @@ struct Recip_SIMD<double>
|
||||
return x;
|
||||
|
||||
v_float64x2 v_scale = v_setall_f64(scale);
|
||||
v_float64x2 v_zero = v_setzero_f64();
|
||||
|
||||
for ( ; x <= width - 4; x += 4)
|
||||
{
|
||||
@@ -1759,9 +1746,6 @@ struct Recip_SIMD<double>
|
||||
v_float64x2 res0 = v_scale / f0;
|
||||
v_float64x2 res1 = v_scale / f1;
|
||||
|
||||
res0 = v_select(f0 == v_zero, v_zero, res0);
|
||||
res1 = v_select(f1 == v_zero, v_zero, res1);
|
||||
|
||||
v_store(dst + x, res0);
|
||||
v_store(dst + x + 2, res1);
|
||||
}
|
||||
|
||||
@@ -237,11 +237,11 @@ static bool ocl_mixChannels(InputArrayOfArrays _src, InputOutputArrayOfArrays _d
|
||||
dstargs[i] = dst[dst_idx];
|
||||
dstargs[i].offset += dst_cnidx * esz;
|
||||
|
||||
declsrc += format("DECLARE_INPUT_MAT(%d)", i);
|
||||
decldst += format("DECLARE_OUTPUT_MAT(%d)", i);
|
||||
indexdecl += format("DECLARE_INDEX(%d)", i);
|
||||
declproc += format("PROCESS_ELEM(%d)", i);
|
||||
declcn += format(" -D scn%d=%d -D dcn%d=%d", i, src[src_idx].channels(), i, dst[dst_idx].channels());
|
||||
declsrc += format("DECLARE_INPUT_MAT(%zu)", i);
|
||||
decldst += format("DECLARE_OUTPUT_MAT(%zu)", i);
|
||||
indexdecl += format("DECLARE_INDEX(%zu)", i);
|
||||
declproc += format("PROCESS_ELEM(%zu)", i);
|
||||
declcn += format(" -D scn%zu=%d -D dcn%zu=%d", i, src[src_idx].channels(), i, dst[dst_idx].channels());
|
||||
}
|
||||
|
||||
ocl::Kernel k("mixChannels", ocl::core::mixchannels_oclsrc,
|
||||
|
||||
@@ -113,6 +113,10 @@ void check_failed_auto(const double v1, const double v2, const CheckContext& ctx
|
||||
{
|
||||
check_failed_auto_<double>(v1, v2, ctx);
|
||||
}
|
||||
void check_failed_auto(const Size_<int> v1, const Size_<int> v2, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_< Size_<int> >(v1, v2, ctx);
|
||||
}
|
||||
|
||||
|
||||
template<typename T> static CV_NORETURN
|
||||
@@ -163,6 +167,10 @@ void check_failed_auto(const double v, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_<double>(v, ctx);
|
||||
}
|
||||
void check_failed_auto(const Size_<int> v, const CheckContext& ctx)
|
||||
{
|
||||
check_failed_auto_< Size_<int> >(v, ctx);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -53,7 +53,7 @@ struct CommandLineParser::Impl
|
||||
};
|
||||
|
||||
|
||||
static const char* get_type_name(int type)
|
||||
static const char* get_type_name(Param type)
|
||||
{
|
||||
if( type == Param::INT )
|
||||
return "int";
|
||||
@@ -81,7 +81,7 @@ static bool parse_bool(std::string str)
|
||||
return b;
|
||||
}
|
||||
|
||||
static void from_str(const String& str, int type, void* dst)
|
||||
static void from_str(const String& str, Param type, void* dst)
|
||||
{
|
||||
std::stringstream ss(str.c_str());
|
||||
if( type == Param::INT )
|
||||
@@ -117,7 +117,7 @@ static void from_str(const String& str, int type, void* dst)
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLineParser::getByName(const String& name, bool space_delete, int type, void* dst) const
|
||||
void CommandLineParser::getByName(const String& name, bool space_delete, Param type, void* dst) const
|
||||
{
|
||||
CV_TRY
|
||||
{
|
||||
@@ -154,7 +154,7 @@ void CommandLineParser::getByName(const String& name, bool space_delete, int typ
|
||||
}
|
||||
|
||||
|
||||
void CommandLineParser::getByIndex(int index, bool space_delete, int type, void* dst) const
|
||||
void CommandLineParser::getByIndex(int index, bool space_delete, Param type, void* dst) const
|
||||
{
|
||||
CV_TRY
|
||||
{
|
||||
|
||||
@@ -375,10 +375,10 @@ static bool ocl_convertScaleAbs( InputArray _src, OutputArray _dst, double alpha
|
||||
int rowsPerWI = d.isIntel() ? 4 : 1;
|
||||
char cvt[2][50];
|
||||
int wdepth = std::max(depth, CV_32F);
|
||||
String build_opt = format("-D OP_CONVERT_SCALE_ABS -D UNARY_OP -D dstT=%s -D srcT1=%s"
|
||||
String build_opt = format("-D OP_CONVERT_SCALE_ABS -D UNARY_OP -D dstT=%s -D DEPTH_dst=%d -D srcT1=%s"
|
||||
" -D workT=%s -D wdepth=%d -D convertToWT1=%s -D convertToDT=%s"
|
||||
" -D workT1=%s -D rowsPerWI=%d%s",
|
||||
ocl::typeToStr(CV_8UC(kercn)),
|
||||
ocl::typeToStr(CV_8UC(kercn)), CV_8U,
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)),
|
||||
ocl::typeToStr(CV_MAKE_TYPE(wdepth, kercn)), wdepth,
|
||||
ocl::convertTypeStr(depth, wdepth, kercn, cvt[0]),
|
||||
|
||||
+16
-14
@@ -90,20 +90,21 @@ copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mste
|
||||
const uchar* src = (const uchar*)_src;
|
||||
uchar* dst = (uchar*)_dst;
|
||||
int x = 0;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
v_uint8 v_zero = vx_setzero_u8();
|
||||
|
||||
for( ; x <= size.width - 16; x += 16 )
|
||||
for( ; x <= size.width - v_uint8::nlanes; x += v_uint8::nlanes )
|
||||
{
|
||||
v_uint8x16 v_src = v_load(src + x),
|
||||
v_dst = v_load(dst + x),
|
||||
v_nmask = v_load(mask + x) == v_zero;
|
||||
v_uint8 v_src = vx_load(src + x),
|
||||
v_dst = vx_load(dst + x),
|
||||
v_nmask = vx_load(mask + x) == v_zero;
|
||||
|
||||
v_dst = v_select(v_nmask, v_dst, v_src);
|
||||
v_store(dst + x, v_dst);
|
||||
}
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
if( mask[x] )
|
||||
@@ -121,25 +122,26 @@ copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mst
|
||||
const ushort* src = (const ushort*)_src;
|
||||
ushort* dst = (ushort*)_dst;
|
||||
int x = 0;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
v_uint8 v_zero = vx_setzero_u8();
|
||||
|
||||
for( ; x <= size.width - 16; x += 16 )
|
||||
for( ; x <= size.width - v_uint8::nlanes; x += v_uint8::nlanes )
|
||||
{
|
||||
v_uint16x8 v_src1 = v_load(src + x), v_src2 = v_load(src + x + 8),
|
||||
v_dst1 = v_load(dst + x), v_dst2 = v_load(dst + x + 8);
|
||||
v_uint16 v_src1 = vx_load(src + x), v_src2 = vx_load(src + x + v_uint16::nlanes),
|
||||
v_dst1 = vx_load(dst + x), v_dst2 = vx_load(dst + x + v_uint16::nlanes);
|
||||
|
||||
v_uint8x16 v_nmask1, v_nmask2;
|
||||
v_uint8x16 v_nmask = v_load(mask + x) == v_zero;
|
||||
v_uint8 v_nmask1, v_nmask2;
|
||||
v_uint8 v_nmask = vx_load(mask + x) == v_zero;
|
||||
v_zip(v_nmask, v_nmask, v_nmask1, v_nmask2);
|
||||
|
||||
v_dst1 = v_select(v_reinterpret_as_u16(v_nmask1), v_dst1, v_src1);
|
||||
v_dst2 = v_select(v_reinterpret_as_u16(v_nmask2), v_dst2, v_src2);
|
||||
v_store(dst + x, v_dst1);
|
||||
v_store(dst + x + 8, v_dst2);
|
||||
v_store(dst + x + v_uint16::nlanes, v_dst2);
|
||||
}
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
if( mask[x] )
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
UMatData* allocate(int dims, const int* sizes, int type,
|
||||
void* data0, size_t* step,
|
||||
int /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
AccessFlag /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
{
|
||||
size_t total = CV_ELEM_SIZE(type);
|
||||
for (int i = dims-1; i >= 0; i--)
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
return u;
|
||||
}
|
||||
|
||||
bool allocate(UMatData* u, int /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
bool allocate(UMatData* u, AccessFlag /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
{
|
||||
return (u != NULL);
|
||||
}
|
||||
|
||||
+83
-106
@@ -277,40 +277,42 @@ template<typename T> struct VBLAS
|
||||
int givensx(T*, T*, int, T, T, T*, T*) const { return 0; }
|
||||
};
|
||||
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
template<> inline int VBLAS<float>::dot(const float* a, const float* b, int n, float* result) const
|
||||
{
|
||||
if( n < 8 )
|
||||
if( n < 2*v_float32::nlanes )
|
||||
return 0;
|
||||
int k = 0;
|
||||
v_float32x4 s0 = v_setzero_f32();
|
||||
for( ; k <= n - v_float32x4::nlanes; k += v_float32x4::nlanes )
|
||||
v_float32 s0 = vx_setzero_f32();
|
||||
for( ; k <= n - v_float32::nlanes; k += v_float32::nlanes )
|
||||
{
|
||||
v_float32x4 a0 = v_load(a + k);
|
||||
v_float32x4 b0 = v_load(b + k);
|
||||
v_float32 a0 = vx_load(a + k);
|
||||
v_float32 b0 = vx_load(b + k);
|
||||
|
||||
s0 += a0 * b0;
|
||||
}
|
||||
*result = v_reduce_sum(s0);
|
||||
vx_cleanup();
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
template<> inline int VBLAS<float>::givens(float* a, float* b, int n, float c, float s) const
|
||||
{
|
||||
if( n < 4 )
|
||||
if( n < v_float32::nlanes)
|
||||
return 0;
|
||||
int k = 0;
|
||||
v_float32x4 c4 = v_setall_f32(c), s4 = v_setall_f32(s);
|
||||
for( ; k <= n - v_float32x4::nlanes; k += v_float32x4::nlanes )
|
||||
v_float32 c4 = vx_setall_f32(c), s4 = vx_setall_f32(s);
|
||||
for( ; k <= n - v_float32::nlanes; k += v_float32::nlanes )
|
||||
{
|
||||
v_float32x4 a0 = v_load(a + k);
|
||||
v_float32x4 b0 = v_load(b + k);
|
||||
v_float32x4 t0 = (a0 * c4) + (b0 * s4);
|
||||
v_float32x4 t1 = (b0 * c4) - (a0 * s4);
|
||||
v_float32 a0 = vx_load(a + k);
|
||||
v_float32 b0 = vx_load(b + k);
|
||||
v_float32 t0 = (a0 * c4) + (b0 * s4);
|
||||
v_float32 t1 = (b0 * c4) - (a0 * s4);
|
||||
v_store(a + k, t0);
|
||||
v_store(b + k, t1);
|
||||
}
|
||||
vx_cleanup();
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -318,17 +320,17 @@ template<> inline int VBLAS<float>::givens(float* a, float* b, int n, float c, f
|
||||
template<> inline int VBLAS<float>::givensx(float* a, float* b, int n, float c, float s,
|
||||
float* anorm, float* bnorm) const
|
||||
{
|
||||
if( n < 4 )
|
||||
if( n < v_float32::nlanes)
|
||||
return 0;
|
||||
int k = 0;
|
||||
v_float32x4 c4 = v_setall_f32(c), s4 = v_setall_f32(s);
|
||||
v_float32x4 sa = v_setzero_f32(), sb = v_setzero_f32();
|
||||
for( ; k <= n - v_float32x4::nlanes; k += v_float32x4::nlanes )
|
||||
v_float32 c4 = vx_setall_f32(c), s4 = vx_setall_f32(s);
|
||||
v_float32 sa = vx_setzero_f32(), sb = vx_setzero_f32();
|
||||
for( ; k <= n - v_float32::nlanes; k += v_float32::nlanes )
|
||||
{
|
||||
v_float32x4 a0 = v_load(a + k);
|
||||
v_float32x4 b0 = v_load(b + k);
|
||||
v_float32x4 t0 = (a0 * c4) + (b0 * s4);
|
||||
v_float32x4 t1 = (b0 * c4) - (a0 * s4);
|
||||
v_float32 a0 = vx_load(a + k);
|
||||
v_float32 b0 = vx_load(b + k);
|
||||
v_float32 t0 = (a0 * c4) + (b0 * s4);
|
||||
v_float32 t1 = (b0 * c4) - (a0 * s4);
|
||||
v_store(a + k, t0);
|
||||
v_store(b + k, t1);
|
||||
sa += t0 + t0;
|
||||
@@ -336,26 +338,28 @@ template<> inline int VBLAS<float>::givensx(float* a, float* b, int n, float c,
|
||||
}
|
||||
*anorm = v_reduce_sum(sa);
|
||||
*bnorm = v_reduce_sum(sb);
|
||||
vx_cleanup();
|
||||
return k;
|
||||
}
|
||||
|
||||
#if CV_SIMD128_64F
|
||||
#if CV_SIMD_64F
|
||||
template<> inline int VBLAS<double>::dot(const double* a, const double* b, int n, double* result) const
|
||||
{
|
||||
if( n < 4 )
|
||||
if( n < 2*v_float64::nlanes )
|
||||
return 0;
|
||||
int k = 0;
|
||||
v_float64x2 s0 = v_setzero_f64();
|
||||
for( ; k <= n - v_float64x2::nlanes; k += v_float64x2::nlanes )
|
||||
v_float64 s0 = vx_setzero_f64();
|
||||
for( ; k <= n - v_float64::nlanes; k += v_float64::nlanes )
|
||||
{
|
||||
v_float64x2 a0 = v_load(a + k);
|
||||
v_float64x2 b0 = v_load(b + k);
|
||||
v_float64 a0 = vx_load(a + k);
|
||||
v_float64 b0 = vx_load(b + k);
|
||||
|
||||
s0 += a0 * b0;
|
||||
}
|
||||
double sbuf[2];
|
||||
v_store(sbuf, s0);
|
||||
*result = sbuf[0] + sbuf[1];
|
||||
vx_cleanup();
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -363,16 +367,17 @@ template<> inline int VBLAS<double>::dot(const double* a, const double* b, int n
|
||||
template<> inline int VBLAS<double>::givens(double* a, double* b, int n, double c, double s) const
|
||||
{
|
||||
int k = 0;
|
||||
v_float64x2 c2 = v_setall_f64(c), s2 = v_setall_f64(s);
|
||||
for( ; k <= n - v_float64x2::nlanes; k += v_float64x2::nlanes )
|
||||
v_float64 c2 = vx_setall_f64(c), s2 = vx_setall_f64(s);
|
||||
for( ; k <= n - v_float64::nlanes; k += v_float64::nlanes )
|
||||
{
|
||||
v_float64x2 a0 = v_load(a + k);
|
||||
v_float64x2 b0 = v_load(b + k);
|
||||
v_float64x2 t0 = (a0 * c2) + (b0 * s2);
|
||||
v_float64x2 t1 = (b0 * c2) - (a0 * s2);
|
||||
v_float64 a0 = vx_load(a + k);
|
||||
v_float64 b0 = vx_load(b + k);
|
||||
v_float64 t0 = (a0 * c2) + (b0 * s2);
|
||||
v_float64 t1 = (b0 * c2) - (a0 * s2);
|
||||
v_store(a + k, t0);
|
||||
v_store(b + k, t1);
|
||||
}
|
||||
vx_cleanup();
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -381,14 +386,14 @@ template<> inline int VBLAS<double>::givensx(double* a, double* b, int n, double
|
||||
double* anorm, double* bnorm) const
|
||||
{
|
||||
int k = 0;
|
||||
v_float64x2 c2 = v_setall_f64(c), s2 = v_setall_f64(s);
|
||||
v_float64x2 sa = v_setzero_f64(), sb = v_setzero_f64();
|
||||
for( ; k <= n - v_float64x2::nlanes; k += v_float64x2::nlanes )
|
||||
v_float64 c2 = vx_setall_f64(c), s2 = vx_setall_f64(s);
|
||||
v_float64 sa = vx_setzero_f64(), sb = vx_setzero_f64();
|
||||
for( ; k <= n - v_float64::nlanes; k += v_float64::nlanes )
|
||||
{
|
||||
v_float64x2 a0 = v_load(a + k);
|
||||
v_float64x2 b0 = v_load(b + k);
|
||||
v_float64x2 t0 = (a0 * c2) + (b0 * s2);
|
||||
v_float64x2 t1 = (b0 * c2) - (a0 * s2);
|
||||
v_float64 a0 = vx_load(a + k);
|
||||
v_float64 b0 = vx_load(b + k);
|
||||
v_float64 t0 = (a0 * c2) + (b0 * s2);
|
||||
v_float64 t1 = (b0 * c2) - (a0 * s2);
|
||||
v_store(a + k, t0);
|
||||
v_store(b + k, t1);
|
||||
sa += t0 * t0;
|
||||
@@ -401,8 +406,8 @@ template<> inline int VBLAS<double>::givensx(double* a, double* b, int n, double
|
||||
*bnorm = bbuf[0] + bbuf[1];
|
||||
return k;
|
||||
}
|
||||
#endif //CV_SIMD128_64F
|
||||
#endif //CV_SIMD128
|
||||
#endif //CV_SIMD_64F
|
||||
#endif //CV_SIMD
|
||||
|
||||
template<typename _Tp> void
|
||||
JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep,
|
||||
@@ -910,37 +915,23 @@ double cv::invert( InputArray _src, OutputArray _dst, int method )
|
||||
{
|
||||
result = true;
|
||||
d = 1./d;
|
||||
|
||||
#if CV_SSE2
|
||||
if(USE_SSE2)
|
||||
{
|
||||
__m128 zero = _mm_setzero_ps();
|
||||
__m128 t0 = _mm_loadl_pi(zero, (const __m64*)srcdata); //t0 = sf(0,0) sf(0,1)
|
||||
__m128 t1 = _mm_loadh_pi(zero, (const __m64*)(srcdata+srcstep)); //t1 = sf(1,0) sf(1,1)
|
||||
__m128 s0 = _mm_or_ps(t0, t1);
|
||||
__m128 det =_mm_set1_ps((float)d);
|
||||
s0 = _mm_mul_ps(s0, det);
|
||||
static const uchar CV_DECL_ALIGNED(16) inv[16] = {0,0,0,0,0,0,0,0x80,0,0,0,0x80,0,0,0,0};
|
||||
__m128 pattern = _mm_load_ps((const float*)inv);
|
||||
s0 = _mm_xor_ps(s0, pattern);//==-1*s0
|
||||
s0 = _mm_shuffle_ps(s0, s0, _MM_SHUFFLE(0,2,1,3));
|
||||
_mm_storel_pi((__m64*)dstdata, s0);
|
||||
_mm_storeh_pi((__m64*)((float*)(dstdata+dststep)), s0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
double t0, t1;
|
||||
t0 = Sf(0,0)*d;
|
||||
t1 = Sf(1,1)*d;
|
||||
Df(1,1) = (float)t0;
|
||||
Df(0,0) = (float)t1;
|
||||
t0 = -Sf(0,1)*d;
|
||||
t1 = -Sf(1,0)*d;
|
||||
Df(0,1) = (float)t0;
|
||||
Df(1,0) = (float)t1;
|
||||
}
|
||||
|
||||
#if CV_SIMD128
|
||||
static const float CV_DECL_ALIGNED(16) inv[4] = { 0.f,-0.f,-0.f,0.f };
|
||||
v_float32x4 s0 = (v_load_halves((const float*)srcdata, (const float*)(srcdata + srcstep)) * v_setall_f32((float)d)) ^ v_load((const float *)inv);//0123//3120
|
||||
s0 = v_extract<3>(s0, v_combine_low(v_rotate_right<1>(s0), s0));
|
||||
v_store_low((float*)dstdata, s0);
|
||||
v_store_high((float*)(dstdata + dststep), s0);
|
||||
#else
|
||||
double t0, t1;
|
||||
t0 = Sf(0,0)*d;
|
||||
t1 = Sf(1,1)*d;
|
||||
Df(1,1) = (float)t0;
|
||||
Df(0,0) = (float)t1;
|
||||
t0 = -Sf(0,1)*d;
|
||||
t1 = -Sf(1,0)*d;
|
||||
Df(0,1) = (float)t0;
|
||||
Df(1,0) = (float)t1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -950,39 +941,25 @@ double cv::invert( InputArray _src, OutputArray _dst, int method )
|
||||
{
|
||||
result = true;
|
||||
d = 1./d;
|
||||
#if CV_SSE2
|
||||
if(USE_SSE2)
|
||||
{
|
||||
__m128d s0 = _mm_loadu_pd((const double*)srcdata); //s0 = sf(0,0) sf(0,1)
|
||||
__m128d s1 = _mm_loadu_pd ((const double*)(srcdata+srcstep));//s1 = sf(1,0) sf(1,1)
|
||||
__m128d sm = _mm_unpacklo_pd(s0, _mm_load_sd((const double*)(srcdata+srcstep)+1)); //sm = sf(0,0) sf(1,1) - main diagonal
|
||||
__m128d ss = _mm_shuffle_pd(s0, s1, _MM_SHUFFLE2(0,1)); //ss = sf(0,1) sf(1,0) - secondary diagonal
|
||||
__m128d det = _mm_load1_pd((const double*)&d);
|
||||
sm = _mm_mul_pd(sm, det);
|
||||
|
||||
static const uchar CV_DECL_ALIGNED(16) inv[8] = {0,0,0,0,0,0,0,0x80};
|
||||
__m128d pattern = _mm_load1_pd((double*)inv);
|
||||
ss = _mm_mul_pd(ss, det);
|
||||
ss = _mm_xor_pd(ss, pattern);//==-1*ss
|
||||
|
||||
s0 = _mm_shuffle_pd(sm, ss, _MM_SHUFFLE2(0,1));
|
||||
s1 = _mm_shuffle_pd(ss, sm, _MM_SHUFFLE2(0,1));
|
||||
_mm_storeu_pd((double*)dstdata, s0);
|
||||
_mm_storeu_pd((double*)(dstdata+dststep), s1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
double t0, t1;
|
||||
t0 = Sd(0,0)*d;
|
||||
t1 = Sd(1,1)*d;
|
||||
Dd(1,1) = t0;
|
||||
Dd(0,0) = t1;
|
||||
t0 = -Sd(0,1)*d;
|
||||
t1 = -Sd(1,0)*d;
|
||||
Dd(0,1) = t0;
|
||||
Dd(1,0) = t1;
|
||||
}
|
||||
#if CV_SIMD128_64F
|
||||
v_float64x2 det = v_setall_f64(d);
|
||||
v_float64x2 s0 = v_load((const double*)srcdata) * det;
|
||||
v_float64x2 s1 = v_load((const double*)(srcdata+srcstep)) * det;
|
||||
v_float64x2 sm = v_extract<1>(s1, s0);//30
|
||||
v_float64x2 ss = v_extract<1>(s0, s1) ^ v_setall_f64(-0.);//12
|
||||
v_store((double*)dstdata, v_combine_low(sm, ss));//31
|
||||
v_store((double*)(dstdata + dststep), v_combine_high(ss, sm));//20
|
||||
#else
|
||||
double t0, t1;
|
||||
t0 = Sd(0,0)*d;
|
||||
t1 = Sd(1,1)*d;
|
||||
Dd(1,1) = t0;
|
||||
Dd(0,0) = t1;
|
||||
t0 = -Sd(0,1)*d;
|
||||
t1 = -Sd(1,0)*d;
|
||||
Dd(0,1) = t0;
|
||||
Dd(1,0) = t1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ Mat LDA::subspaceProject(InputArray _W, InputArray _mean, InputArray _src) {
|
||||
}
|
||||
// make sure mean is correct if not empty
|
||||
if(!mean.empty() && (mean.total() != (size_t) d)) {
|
||||
String error_message = format("Wrong mean shape for the given data matrix. Expected %d, but was %d.", d, mean.total());
|
||||
String error_message = format("Wrong mean shape for the given data matrix. Expected %d, but was %zu.", d, mean.total());
|
||||
CV_Error(Error::StsBadArg, error_message);
|
||||
}
|
||||
// create temporary matrices
|
||||
@@ -222,7 +222,7 @@ Mat LDA::subspaceReconstruct(InputArray _W, InputArray _mean, InputArray _src)
|
||||
}
|
||||
// make sure mean is correct if not empty
|
||||
if(!mean.empty() && (mean.total() != (size_t) W.rows)) {
|
||||
String error_message = format("Wrong mean shape for the given eigenvector matrix. Expected %d, but was %d.", W.cols, mean.total());
|
||||
String error_message = format("Wrong mean shape for the given eigenvector matrix. Expected %d, but was %zu.", W.cols, mean.total());
|
||||
CV_Error(Error::StsBadArg, error_message);
|
||||
}
|
||||
// initialize temporary matrices
|
||||
@@ -1076,7 +1076,7 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
|
||||
}
|
||||
// throw error if less labels, than samples
|
||||
if (labels.size() != static_cast<size_t>(N)) {
|
||||
String error_message = format("The number of samples must equal the number of labels. Given %d labels, %d samples. ", labels.size(), N);
|
||||
String error_message = format("The number of samples must equal the number of labels. Given %zu labels, %d samples. ", labels.size(), N);
|
||||
CV_Error(Error::StsBadArg, error_message);
|
||||
}
|
||||
// warn if within-classes scatter matrix becomes singular
|
||||
|
||||
@@ -90,18 +90,20 @@ static void swap_columns(Mat_<double>& A,int col1,int col2);
|
||||
#define SWAP(type,a,b) {type tmp=(a);(a)=(b);(b)=tmp;}
|
||||
|
||||
//return codes:-2 (no_sol - unbdd),-1(no_sol - unfsbl), 0(single_sol), 1(multiple_sol=>least_l2_norm)
|
||||
int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
|
||||
int solveLP(InputArray Func_, InputArray Constr_, OutputArray z_)
|
||||
{
|
||||
dprintf(("call to solveLP\n"));
|
||||
|
||||
//sanity check (size, type, no. of channels)
|
||||
CV_Assert(Func.type()==CV_64FC1 || Func.type()==CV_32FC1);
|
||||
CV_Assert(Constr.type()==CV_64FC1 || Constr.type()==CV_32FC1);
|
||||
CV_Assert((Func.rows==1 && (Constr.cols-Func.cols==1))||
|
||||
(Func.cols==1 && (Constr.cols-Func.rows==1)));
|
||||
if (!z.empty())
|
||||
CV_CheckTypeEQ(z.type(), CV_64FC1, "");
|
||||
else
|
||||
CV_CheckType(z.type(), z.type() == CV_64FC1 || z.type() == CV_8UC1/*empty cv::Mat*/, "");
|
||||
CV_Assert(Func_.type()==CV_64FC1 || Func_.type()==CV_32FC1);
|
||||
CV_Assert(Constr_.type()==CV_64FC1 || Constr_.type()==CV_32FC1);
|
||||
CV_Assert((Func_.rows()==1 && (Constr_.cols()-Func_.cols()==1))||
|
||||
(Func_.cols()==1 && (Constr_.cols()-Func_.rows()==1)));
|
||||
if (z_.fixedType())
|
||||
CV_CheckType(z_.type(), z_.type() == CV_64FC1 || z_.type() == CV_32FC1 || z_.type() == CV_32SC1, "");
|
||||
|
||||
Mat Func = Func_.getMat();
|
||||
Mat Constr = Constr_.getMat();
|
||||
|
||||
//copy arguments for we will shall modify them
|
||||
Mat_<double> bigC=Mat_<double>(1,(Func.rows==1?Func.cols:Func.rows)+1),
|
||||
@@ -129,7 +131,7 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
|
||||
}
|
||||
|
||||
//return the optimal solution
|
||||
z.create(c.cols,1,CV_64FC1);
|
||||
Mat z(c.cols,1,CV_64FC1);
|
||||
MatIterator_<double> it=z.begin<double>();
|
||||
unsigned int nsize = (unsigned int)N.size();
|
||||
for(int i=1;i<=c.cols;i++,it++){
|
||||
@@ -140,6 +142,7 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
|
||||
}
|
||||
}
|
||||
|
||||
z.copyTo(z_);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ static bool ocl_math_op(InputArray _src1, InputArray _src2, OutputArray _dst, in
|
||||
int rowsPerWI = d.isIntel() ? 4 : 1;
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D %s -D %s -D dstT=%s -D rowsPerWI=%d%s", _src2.empty() ? "UNARY_OP" : "BINARY_OP",
|
||||
oclop2str[oclop], ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), rowsPerWI,
|
||||
format("-D %s -D %s -D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d%s", _src2.empty() ? "UNARY_OP" : "BINARY_OP",
|
||||
oclop2str[oclop], ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), depth, rowsPerWI,
|
||||
double_support ? " -D DOUBLE_SUPPORT" : ""));
|
||||
if (k.empty())
|
||||
return false;
|
||||
@@ -238,9 +238,9 @@ static bool ocl_cartToPolar( InputArray _src1, InputArray _src2,
|
||||
return false;
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D BINARY_OP -D dstT=%s -D depth=%d -D rowsPerWI=%d -D OP_CTP_%s%s",
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)),
|
||||
depth, rowsPerWI, angleInDegrees ? "AD" : "AR",
|
||||
format("-D BINARY_OP -D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D OP_CTP_%s%s",
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), depth,
|
||||
rowsPerWI, angleInDegrees ? "AD" : "AR",
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
|
||||
if (k.empty())
|
||||
return false;
|
||||
@@ -474,9 +474,10 @@ static bool ocl_polarToCart( InputArray _mag, InputArray _angle,
|
||||
return false;
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D dstT=%s -D rowsPerWI=%d -D depth=%d -D BINARY_OP -D OP_PTC_%s%s",
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), rowsPerWI,
|
||||
depth, angleInDegrees ? "AD" : "AR",
|
||||
format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D BINARY_OP -D OP_PTC_%s%s",
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), depth,
|
||||
rowsPerWI,
|
||||
angleInDegrees ? "AD" : "AR",
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
|
||||
if (k.empty())
|
||||
return false;
|
||||
@@ -606,17 +607,15 @@ void polarToCart( InputArray src1, InputArray src2,
|
||||
{
|
||||
k = 0;
|
||||
|
||||
#if CV_SIMD128
|
||||
if( hasSIMD128() )
|
||||
#if CV_SIMD
|
||||
int cWidth = v_float32::nlanes;
|
||||
for( ; k <= len - cWidth; k += cWidth )
|
||||
{
|
||||
int cWidth = v_float32x4::nlanes;
|
||||
for( ; k <= len - cWidth; k += cWidth )
|
||||
{
|
||||
v_float32x4 v_m = v_load(mag + k);
|
||||
v_store(x + k, v_load(x + k) * v_m);
|
||||
v_store(y + k, v_load(y + k) * v_m);
|
||||
}
|
||||
v_float32 v_m = vx_load(mag + k);
|
||||
v_store(x + k, vx_load(x + k) * v_m);
|
||||
v_store(y + k, vx_load(y + k) * v_m);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
|
||||
for( ; k < len; k++ )
|
||||
@@ -735,7 +734,7 @@ struct iPow_SIMD
|
||||
}
|
||||
};
|
||||
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<uchar, int>
|
||||
@@ -743,13 +742,13 @@ struct iPow_SIMD<uchar, int>
|
||||
int operator() ( const uchar * src, uchar * dst, int len, int power )
|
||||
{
|
||||
int i = 0;
|
||||
v_uint32x4 v_1 = v_setall_u32(1u);
|
||||
v_uint32 v_1 = vx_setall_u32(1u);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
for ( ; i <= len - v_uint16::nlanes; i += v_uint16::nlanes)
|
||||
{
|
||||
v_uint32x4 v_a1 = v_1, v_a2 = v_1;
|
||||
v_uint16x8 v = v_load_expand(src + i);
|
||||
v_uint32x4 v_b1, v_b2;
|
||||
v_uint32 v_a1 = v_1, v_a2 = v_1;
|
||||
v_uint16 v = vx_load_expand(src + i);
|
||||
v_uint32 v_b1, v_b2;
|
||||
v_expand(v, v_b1, v_b2);
|
||||
int p = power;
|
||||
|
||||
@@ -771,6 +770,7 @@ struct iPow_SIMD<uchar, int>
|
||||
v = v_pack(v_a1, v_a2);
|
||||
v_pack_store(dst + i, v);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -782,13 +782,13 @@ struct iPow_SIMD<schar, int>
|
||||
int operator() ( const schar * src, schar * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
v_int32x4 v_1 = v_setall_s32(1);
|
||||
v_int32 v_1 = vx_setall_s32(1);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
for ( ; i <= len - v_int16::nlanes; i += v_int16::nlanes)
|
||||
{
|
||||
v_int32x4 v_a1 = v_1, v_a2 = v_1;
|
||||
v_int16x8 v = v_load_expand(src + i);
|
||||
v_int32x4 v_b1, v_b2;
|
||||
v_int32 v_a1 = v_1, v_a2 = v_1;
|
||||
v_int16 v = vx_load_expand(src + i);
|
||||
v_int32 v_b1, v_b2;
|
||||
v_expand(v, v_b1, v_b2);
|
||||
int p = power;
|
||||
|
||||
@@ -810,6 +810,7 @@ struct iPow_SIMD<schar, int>
|
||||
v = v_pack(v_a1, v_a2);
|
||||
v_pack_store(dst + i, v);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -821,13 +822,13 @@ struct iPow_SIMD<ushort, int>
|
||||
int operator() ( const ushort * src, ushort * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
v_uint32x4 v_1 = v_setall_u32(1u);
|
||||
v_uint32 v_1 = vx_setall_u32(1u);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
for ( ; i <= len - v_uint16::nlanes; i += v_uint16::nlanes)
|
||||
{
|
||||
v_uint32x4 v_a1 = v_1, v_a2 = v_1;
|
||||
v_uint16x8 v = v_load(src + i);
|
||||
v_uint32x4 v_b1, v_b2;
|
||||
v_uint32 v_a1 = v_1, v_a2 = v_1;
|
||||
v_uint16 v = vx_load(src + i);
|
||||
v_uint32 v_b1, v_b2;
|
||||
v_expand(v, v_b1, v_b2);
|
||||
int p = power;
|
||||
|
||||
@@ -849,6 +850,7 @@ struct iPow_SIMD<ushort, int>
|
||||
v = v_pack(v_a1, v_a2);
|
||||
v_store(dst + i, v);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -860,13 +862,13 @@ struct iPow_SIMD<short, int>
|
||||
int operator() ( const short * src, short * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
v_int32x4 v_1 = v_setall_s32(1);
|
||||
v_int32 v_1 = vx_setall_s32(1);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
for ( ; i <= len - v_int16::nlanes; i += v_int16::nlanes)
|
||||
{
|
||||
v_int32x4 v_a1 = v_1, v_a2 = v_1;
|
||||
v_int16x8 v = v_load(src + i);
|
||||
v_int32x4 v_b1, v_b2;
|
||||
v_int32 v_a1 = v_1, v_a2 = v_1;
|
||||
v_int16 v = vx_load(src + i);
|
||||
v_int32 v_b1, v_b2;
|
||||
v_expand(v, v_b1, v_b2);
|
||||
int p = power;
|
||||
|
||||
@@ -888,6 +890,7 @@ struct iPow_SIMD<short, int>
|
||||
v = v_pack(v_a1, v_a2);
|
||||
v_store(dst + i, v);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -899,12 +902,12 @@ struct iPow_SIMD<int, int>
|
||||
int operator() ( const int * src, int * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
v_int32x4 v_1 = v_setall_s32(1);
|
||||
v_int32 v_1 = vx_setall_s32(1);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
for ( ; i <= len - v_int32::nlanes*2; i += v_int32::nlanes*2)
|
||||
{
|
||||
v_int32x4 v_a1 = v_1, v_a2 = v_1;
|
||||
v_int32x4 v_b1 = v_load(src + i), v_b2 = v_load(src + i + 4);
|
||||
v_int32 v_a1 = v_1, v_a2 = v_1;
|
||||
v_int32 v_b1 = vx_load(src + i), v_b2 = vx_load(src + i + v_int32::nlanes);
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
@@ -923,8 +926,9 @@ struct iPow_SIMD<int, int>
|
||||
v_a2 *= v_b2;
|
||||
|
||||
v_store(dst + i, v_a1);
|
||||
v_store(dst + i + 4, v_a2);
|
||||
v_store(dst + i + v_int32::nlanes, v_a2);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -936,12 +940,12 @@ struct iPow_SIMD<float, float>
|
||||
int operator() ( const float * src, float * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
v_float32x4 v_1 = v_setall_f32(1.f);
|
||||
v_float32 v_1 = vx_setall_f32(1.f);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
for ( ; i <= len - v_float32::nlanes*2; i += v_float32::nlanes*2)
|
||||
{
|
||||
v_float32x4 v_a1 = v_1, v_a2 = v_1;
|
||||
v_float32x4 v_b1 = v_load(src + i), v_b2 = v_load(src + i + 4);
|
||||
v_float32 v_a1 = v_1, v_a2 = v_1;
|
||||
v_float32 v_b1 = vx_load(src + i), v_b2 = vx_load(src + i + v_float32::nlanes);
|
||||
int p = std::abs(power);
|
||||
if( power < 0 )
|
||||
{
|
||||
@@ -965,26 +969,27 @@ struct iPow_SIMD<float, float>
|
||||
v_a2 *= v_b2;
|
||||
|
||||
v_store(dst + i, v_a1);
|
||||
v_store(dst + i + 4, v_a2);
|
||||
v_store(dst + i + v_float32::nlanes, v_a2);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
#if CV_SIMD128_64F
|
||||
#if CV_SIMD_64F
|
||||
template <>
|
||||
struct iPow_SIMD<double, double>
|
||||
{
|
||||
int operator() ( const double * src, double * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
v_float64x2 v_1 = v_setall_f64(1.);
|
||||
v_float64 v_1 = vx_setall_f64(1.);
|
||||
|
||||
for ( ; i <= len - 4; i += 4)
|
||||
for ( ; i <= len - v_float64::nlanes*2; i += v_float64::nlanes*2)
|
||||
{
|
||||
v_float64x2 v_a1 = v_1, v_a2 = v_1;
|
||||
v_float64x2 v_b1 = v_load(src + i), v_b2 = v_load(src + i + 2);
|
||||
v_float64 v_a1 = v_1, v_a2 = v_1;
|
||||
v_float64 v_b1 = vx_load(src + i), v_b2 = vx_load(src + i + v_float64::nlanes);
|
||||
int p = std::abs(power);
|
||||
if( power < 0 )
|
||||
{
|
||||
@@ -1008,8 +1013,9 @@ struct iPow_SIMD<double, double>
|
||||
v_a2 *= v_b2;
|
||||
|
||||
v_store(dst + i, v_a1);
|
||||
v_store(dst + i + 2, v_a2);
|
||||
v_store(dst + i + v_float64::nlanes, v_a2);
|
||||
}
|
||||
vx_cleanup();
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -1169,8 +1175,8 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst,
|
||||
const char * const op = issqrt ? "OP_SQRT" : is_ipower ? "OP_POWN" : "OP_POW";
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D dstT=%s -D depth=%d -D rowsPerWI=%d -D %s -D UNARY_OP%s",
|
||||
ocl::typeToStr(depth), depth, rowsPerWI, op,
|
||||
format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D %s -D UNARY_OP%s",
|
||||
ocl::typeToStr(depth), depth, rowsPerWI, op,
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
|
||||
if (k.empty())
|
||||
return false;
|
||||
@@ -1271,10 +1277,17 @@ void pow( InputArray _src, double power, OutputArray _dst )
|
||||
Cv64suf inf64, nan64;
|
||||
float* fbuf = 0;
|
||||
double* dbuf = 0;
|
||||
#ifndef __EMSCRIPTEN__
|
||||
inf32.i = 0x7f800000;
|
||||
nan32.i = 0x7fffffff;
|
||||
inf64.i = CV_BIG_INT(0x7FF0000000000000);
|
||||
nan64.i = CV_BIG_INT(0x7FFFFFFFFFFFFFFF);
|
||||
#else
|
||||
inf32.f = std::numeric_limits<float>::infinity();
|
||||
nan32.f = std::numeric_limits<float>::quiet_NaN();
|
||||
inf64.f = std::numeric_limits<double>::infinity();
|
||||
nan64.f = std::numeric_limits<double>::quiet_NaN();
|
||||
#endif
|
||||
|
||||
if( src.ptr() == dst.ptr() )
|
||||
{
|
||||
@@ -1560,8 +1573,8 @@ static bool ocl_patchNaNs( InputOutputArray _a, float value )
|
||||
{
|
||||
int rowsPerWI = ocl::Device::getDefault().isIntel() ? 4 : 1;
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D UNARY_OP -D OP_PATCH_NANS -D dstT=float -D rowsPerWI=%d",
|
||||
rowsPerWI));
|
||||
format("-D UNARY_OP -D OP_PATCH_NANS -D dstT=float -D DEPTH_dst=%d -D rowsPerWI=%d",
|
||||
CV_32F, rowsPerWI));
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
@@ -1594,9 +1607,9 @@ void patchNaNs( InputOutputArray _a, double _val )
|
||||
Cv32suf val;
|
||||
val.f = (float)_val;
|
||||
|
||||
#if CV_SIMD128
|
||||
v_int32x4 v_mask1 = v_setall_s32(0x7fffffff), v_mask2 = v_setall_s32(0x7f800000);
|
||||
v_int32x4 v_val = v_setall_s32(val.i);
|
||||
#if CV_SIMD
|
||||
v_int32 v_mask1 = vx_setall_s32(0x7fffffff), v_mask2 = vx_setall_s32(0x7f800000);
|
||||
v_int32 v_val = vx_setall_s32(val.i);
|
||||
#endif
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
@@ -1604,18 +1617,16 @@ void patchNaNs( InputOutputArray _a, double _val )
|
||||
int* tptr = ptrs[0];
|
||||
size_t j = 0;
|
||||
|
||||
#if CV_SIMD128
|
||||
if( hasSIMD128() )
|
||||
#if CV_SIMD
|
||||
size_t cWidth = (size_t)v_int32::nlanes;
|
||||
for ( ; j + cWidth <= len; j += cWidth)
|
||||
{
|
||||
size_t cWidth = (size_t)v_int32x4::nlanes;
|
||||
for ( ; j + cWidth <= len; j += cWidth)
|
||||
{
|
||||
v_int32x4 v_src = v_load(tptr + j);
|
||||
v_int32x4 v_cmp_mask = v_mask2 < (v_src & v_mask1);
|
||||
v_int32x4 v_dst = v_select(v_cmp_mask, v_val, v_src);
|
||||
v_store(tptr + j, v_dst);
|
||||
}
|
||||
v_int32 v_src = vx_load(tptr + j);
|
||||
v_int32 v_cmp_mask = v_mask2 < (v_src & v_mask1);
|
||||
v_int32 v_dst = v_select(v_cmp_mask, v_val, v_src);
|
||||
v_store(tptr + j, v_dst);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
|
||||
for( ; j < len; j++ )
|
||||
|
||||
@@ -27,16 +27,26 @@ float fastAtan2(float y, float x);
|
||||
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
static inline float atan_f32(float y, float x)
|
||||
{
|
||||
float a = atan2(y, x) * 180.0f / CV_PI;
|
||||
if (a < 0.0f)
|
||||
a += 360.0f;
|
||||
if (a >= 360.0f)
|
||||
a -= 360.0f;
|
||||
return a; // range [0; 360)
|
||||
}
|
||||
#else
|
||||
static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI);
|
||||
static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
|
||||
static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI);
|
||||
static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI);
|
||||
|
||||
using namespace cv;
|
||||
|
||||
static inline float atan_f32(float y, float x)
|
||||
{
|
||||
float ax = std::abs(x), ay = std::abs(y);
|
||||
@@ -59,6 +69,7 @@ static inline float atan_f32(float y, float x)
|
||||
a = 360.f - a;
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CV_SIMD
|
||||
|
||||
@@ -363,7 +374,7 @@ void sqrt64f(const double* src, double* dst, int len)
|
||||
// Workaround for ICE in MSVS 2015 update 3 (issue #7795)
|
||||
// CV_AVX is not used here, because generated code is faster in non-AVX mode.
|
||||
// (tested with disabled IPP on i5-6300U)
|
||||
#if (defined _MSC_VER && _MSC_VER >= 1900)
|
||||
#if (defined _MSC_VER && _MSC_VER >= 1900) || defined(__EMSCRIPTEN__)
|
||||
void exp32f(const float *src, float *dst, int n)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
+85
-107
@@ -2310,18 +2310,12 @@ static void scaleAdd_32f(const float* src1, const float* src2, float* dst,
|
||||
{
|
||||
float alpha = *_alpha;
|
||||
int i = 0;
|
||||
#if CV_SIMD128
|
||||
if (hasSIMD128())
|
||||
{
|
||||
v_float32x4 v_alpha = v_setall_f32(alpha);
|
||||
const int cWidth = v_float32x4::nlanes;
|
||||
for (; i <= len - cWidth; i += cWidth)
|
||||
{
|
||||
v_float32x4 v_src1 = v_load(src1 + i);
|
||||
v_float32x4 v_src2 = v_load(src2 + i);
|
||||
v_store(dst + i, (v_src1 * v_alpha) + v_src2);
|
||||
}
|
||||
}
|
||||
#if CV_SIMD
|
||||
v_float32 v_alpha = vx_setall_f32(alpha);
|
||||
const int cWidth = v_float32::nlanes;
|
||||
for (; i <= len - cWidth; i += cWidth)
|
||||
v_store(dst + i, v_muladd(vx_load(src1 + i), v_alpha, vx_load(src2 + i)));
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for (; i < len; i++)
|
||||
dst[i] = src1[i] * alpha + src2[i];
|
||||
@@ -2333,22 +2327,12 @@ static void scaleAdd_64f(const double* src1, const double* src2, double* dst,
|
||||
{
|
||||
double alpha = *_alpha;
|
||||
int i = 0;
|
||||
#if CV_SIMD128_64F
|
||||
if (hasSIMD128())
|
||||
{
|
||||
v_float64x2 a2 = v_setall_f64(alpha);
|
||||
const int cWidth = v_float64x2::nlanes;
|
||||
for (; i <= len - cWidth * 2; i += cWidth * 2)
|
||||
{
|
||||
v_float64x2 x0, x1, y0, y1, t0, t1;
|
||||
x0 = v_load(src1 + i); x1 = v_load(src1 + i + cWidth);
|
||||
y0 = v_load(src2 + i); y1 = v_load(src2 + i + cWidth);
|
||||
t0 = x0 * a2 + y0;
|
||||
t1 = x1 * a2 + y1;
|
||||
v_store(dst + i, t0);
|
||||
v_store(dst + i + cWidth, t1);
|
||||
}
|
||||
}
|
||||
#if CV_SIMD_64F
|
||||
v_float64 a2 = vx_setall_f64(alpha);
|
||||
const int cWidth = v_float64::nlanes;
|
||||
for (; i <= len - cWidth; i += cWidth)
|
||||
v_store(dst + i, v_muladd(vx_load(src1 + i), a2, vx_load(src2 + i)));
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for (; i < len; i++)
|
||||
dst[i] = src1[i] * alpha + src2[i];
|
||||
@@ -2375,10 +2359,10 @@ static bool ocl_scaleAdd( InputArray _src1, double alpha, InputArray _src2, Outp
|
||||
|
||||
char cvt[2][50];
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D OP_SCALE_ADD -D BINARY_OP -D dstT=%s -D workT=%s -D convertToWT1=%s"
|
||||
format("-D OP_SCALE_ADD -D BINARY_OP -D dstT=%s -D DEPTH_dst=%d -D workT=%s -D convertToWT1=%s"
|
||||
" -D srcT1=dstT -D srcT2=dstT -D convertToDT=%s -D workT1=%s"
|
||||
" -D wdepth=%d%s -D rowsPerWI=%d",
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)),
|
||||
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), depth,
|
||||
ocl::typeToStr(CV_MAKE_TYPE(wdepth, kercn)),
|
||||
ocl::convertTypeStr(depth, wdepth, kercn, cvt[0]),
|
||||
ocl::convertTypeStr(wdepth, depth, kercn, cvt[1]),
|
||||
@@ -3025,42 +3009,40 @@ static double dotProd_8u(const uchar* src1, const uchar* src2, int len)
|
||||
#endif
|
||||
int i = 0;
|
||||
|
||||
#if CV_SIMD128
|
||||
if (hasSIMD128())
|
||||
#if CV_SIMD
|
||||
int len0 = len & -v_uint16::nlanes, blockSize0 = (1 << 15), blockSize;
|
||||
|
||||
while (i < len0)
|
||||
{
|
||||
int len0 = len & -8, blockSize0 = (1 << 15), blockSize;
|
||||
blockSize = std::min(len0 - i, blockSize0);
|
||||
v_int32 v_sum = vx_setzero_s32();
|
||||
const int cWidth = v_uint16::nlanes;
|
||||
|
||||
while (i < len0)
|
||||
int j = 0;
|
||||
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
|
||||
{
|
||||
blockSize = std::min(len0 - i, blockSize0);
|
||||
v_int32x4 v_sum = v_setzero_s32();
|
||||
const int cWidth = v_uint16x8::nlanes;
|
||||
v_uint16 v_src10, v_src20, v_src11, v_src21;
|
||||
v_expand(vx_load(src1 + j), v_src10, v_src11);
|
||||
v_expand(vx_load(src2 + j), v_src20, v_src21);
|
||||
|
||||
int j = 0;
|
||||
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
|
||||
{
|
||||
v_uint16x8 v_src10, v_src20, v_src11, v_src21;
|
||||
v_expand(v_load(src1 + j), v_src10, v_src11);
|
||||
v_expand(v_load(src2 + j), v_src20, v_src21);
|
||||
|
||||
v_sum += v_dotprod(v_reinterpret_as_s16(v_src10), v_reinterpret_as_s16(v_src20));
|
||||
v_sum += v_dotprod(v_reinterpret_as_s16(v_src11), v_reinterpret_as_s16(v_src21));
|
||||
}
|
||||
|
||||
for (; j <= blockSize - cWidth; j += cWidth)
|
||||
{
|
||||
v_int16x8 v_src10 = v_reinterpret_as_s16(v_load_expand(src1 + j));
|
||||
v_int16x8 v_src20 = v_reinterpret_as_s16(v_load_expand(src2 + j));
|
||||
|
||||
v_sum += v_dotprod(v_src10, v_src20);
|
||||
}
|
||||
r += (double)v_reduce_sum(v_sum);
|
||||
|
||||
src1 += blockSize;
|
||||
src2 += blockSize;
|
||||
i += blockSize;
|
||||
v_sum += v_dotprod(v_reinterpret_as_s16(v_src10), v_reinterpret_as_s16(v_src20));
|
||||
v_sum += v_dotprod(v_reinterpret_as_s16(v_src11), v_reinterpret_as_s16(v_src21));
|
||||
}
|
||||
|
||||
for (; j <= blockSize - cWidth; j += cWidth)
|
||||
{
|
||||
v_int16 v_src10 = v_reinterpret_as_s16(vx_load_expand(src1 + j));
|
||||
v_int16 v_src20 = v_reinterpret_as_s16(vx_load_expand(src2 + j));
|
||||
|
||||
v_sum += v_dotprod(v_src10, v_src20);
|
||||
}
|
||||
r += (double)v_reduce_sum(v_sum);
|
||||
|
||||
src1 += blockSize;
|
||||
src2 += blockSize;
|
||||
i += blockSize;
|
||||
}
|
||||
vx_cleanup();
|
||||
#elif CV_NEON
|
||||
if( cv::checkHardwareSupport(CV_CPU_NEON) )
|
||||
{
|
||||
@@ -3113,42 +3095,40 @@ static double dotProd_8s(const schar* src1, const schar* src2, int len)
|
||||
double r = 0.0;
|
||||
int i = 0;
|
||||
|
||||
#if CV_SIMD128
|
||||
if (hasSIMD128())
|
||||
#if CV_SIMD
|
||||
int len0 = len & -v_int16::nlanes, blockSize0 = (1 << 14), blockSize;
|
||||
|
||||
while (i < len0)
|
||||
{
|
||||
int len0 = len & -8, blockSize0 = (1 << 14), blockSize;
|
||||
blockSize = std::min(len0 - i, blockSize0);
|
||||
v_int32 v_sum = vx_setzero_s32();
|
||||
const int cWidth = v_int16::nlanes;
|
||||
|
||||
while (i < len0)
|
||||
int j = 0;
|
||||
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
|
||||
{
|
||||
blockSize = std::min(len0 - i, blockSize0);
|
||||
v_int32x4 v_sum = v_setzero_s32();
|
||||
const int cWidth = v_int16x8::nlanes;
|
||||
v_int16 v_src10, v_src20, v_src11, v_src21;
|
||||
v_expand(vx_load(src1 + j), v_src10, v_src11);
|
||||
v_expand(vx_load(src2 + j), v_src20, v_src21);
|
||||
|
||||
int j = 0;
|
||||
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
|
||||
{
|
||||
v_int16x8 v_src10, v_src20, v_src11, v_src21;
|
||||
v_expand(v_load(src1 + j), v_src10, v_src11);
|
||||
v_expand(v_load(src2 + j), v_src20, v_src21);
|
||||
|
||||
v_sum += v_dotprod(v_src10, v_src20);
|
||||
v_sum += v_dotprod(v_src11, v_src21);
|
||||
}
|
||||
|
||||
for (; j <= blockSize - cWidth; j += cWidth)
|
||||
{
|
||||
v_int16x8 v_src10 = v_load_expand(src1 + j);
|
||||
v_int16x8 v_src20 = v_load_expand(src2 + j);
|
||||
|
||||
v_sum += v_dotprod(v_src10, v_src20);
|
||||
}
|
||||
r += (double)v_reduce_sum(v_sum);
|
||||
|
||||
src1 += blockSize;
|
||||
src2 += blockSize;
|
||||
i += blockSize;
|
||||
v_sum += v_dotprod(v_src10, v_src20);
|
||||
v_sum += v_dotprod(v_src11, v_src21);
|
||||
}
|
||||
|
||||
for (; j <= blockSize - cWidth; j += cWidth)
|
||||
{
|
||||
v_int16 v_src10 = vx_load_expand(src1 + j);
|
||||
v_int16 v_src20 = vx_load_expand(src2 + j);
|
||||
|
||||
v_sum += v_dotprod(v_src10, v_src20);
|
||||
}
|
||||
r += (double)v_reduce_sum(v_sum);
|
||||
|
||||
src1 += blockSize;
|
||||
src2 += blockSize;
|
||||
i += blockSize;
|
||||
}
|
||||
vx_cleanup();
|
||||
#elif CV_NEON
|
||||
if( cv::checkHardwareSupport(CV_CPU_NEON) )
|
||||
{
|
||||
@@ -3232,28 +3212,26 @@ static double dotProd_32f(const float* src1, const float* src2, int len)
|
||||
#endif
|
||||
int i = 0;
|
||||
|
||||
#if CV_SIMD128
|
||||
if (hasSIMD128())
|
||||
#if CV_SIMD
|
||||
int len0 = len & -v_float32::nlanes, blockSize0 = (1 << 13), blockSize;
|
||||
|
||||
while (i < len0)
|
||||
{
|
||||
int len0 = len & -4, blockSize0 = (1 << 13), blockSize;
|
||||
blockSize = std::min(len0 - i, blockSize0);
|
||||
v_float32 v_sum = vx_setzero_f32();
|
||||
|
||||
while (i < len0)
|
||||
{
|
||||
blockSize = std::min(len0 - i, blockSize0);
|
||||
v_float32x4 v_sum = v_setzero_f32();
|
||||
int j = 0;
|
||||
int cWidth = v_float32::nlanes;
|
||||
for (; j <= blockSize - cWidth; j += cWidth)
|
||||
v_sum = v_muladd(vx_load(src1 + j), vx_load(src2 + j), v_sum);
|
||||
|
||||
int j = 0;
|
||||
int cWidth = v_float32x4::nlanes;
|
||||
for (; j <= blockSize - cWidth; j += cWidth)
|
||||
v_sum = v_muladd(v_load(src1 + j), v_load(src2 + j), v_sum);
|
||||
r += v_reduce_sum(v_sum);
|
||||
|
||||
r += v_reduce_sum(v_sum);
|
||||
|
||||
src1 += blockSize;
|
||||
src2 += blockSize;
|
||||
i += blockSize;
|
||||
}
|
||||
src1 += blockSize;
|
||||
src2 += blockSize;
|
||||
i += blockSize;
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
return r + dotProd_(src1, src2, len - i);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
void MatAllocator::map(UMatData*, int) const
|
||||
void MatAllocator::map(UMatData*, AccessFlag) const
|
||||
{
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class StdMatAllocator CV_FINAL : public MatAllocator
|
||||
{
|
||||
public:
|
||||
UMatData* allocate(int dims, const int* sizes, int type,
|
||||
void* data0, size_t* step, int /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
void* data0, size_t* step, AccessFlag /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
{
|
||||
size_t total = CV_ELEM_SIZE(type);
|
||||
for( int i = dims-1; i >= 0; i-- )
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
return u;
|
||||
}
|
||||
|
||||
bool allocate(UMatData* u, int /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
bool allocate(UMatData* u, AccessFlag /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
|
||||
{
|
||||
if(!u) return false;
|
||||
return true;
|
||||
@@ -355,15 +355,16 @@ void Mat::create(int d, const int* _sizes, int _type)
|
||||
#endif
|
||||
if(!a)
|
||||
a = a0;
|
||||
CV_TRY
|
||||
try
|
||||
{
|
||||
u = a->allocate(dims, size, _type, 0, step.p, 0, USAGE_DEFAULT);
|
||||
u = a->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
|
||||
CV_Assert(u != 0);
|
||||
}
|
||||
CV_CATCH_ALL
|
||||
catch (...)
|
||||
{
|
||||
if(a != a0)
|
||||
u = a0->allocate(dims, size, _type, 0, step.p, 0, USAGE_DEFAULT);
|
||||
if (a == a0)
|
||||
throw;
|
||||
u = a0->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
|
||||
CV_Assert(u != 0);
|
||||
}
|
||||
CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
|
||||
|
||||
@@ -892,7 +892,7 @@ static bool ocl_reduce(InputArray _src, OutputArray _dst,
|
||||
tileHeight = min(tileHeight, defDev.localMemSize() / buf_cols / CV_ELEM_SIZE(CV_MAKETYPE(wdepth, cn)) / maxItemInGroupCount);
|
||||
}
|
||||
char cvt[3][40];
|
||||
cv::String build_opt = format("-D OP_REDUCE_PRE -D BUF_COLS=%d -D TILE_HEIGHT=%d -D %s -D dim=1"
|
||||
cv::String build_opt = format("-D OP_REDUCE_PRE -D BUF_COLS=%d -D TILE_HEIGHT=%zu -D %s -D dim=1"
|
||||
" -D cn=%d -D ddepth=%d"
|
||||
" -D srcT=%s -D bufT=%s -D dstT=%s"
|
||||
" -D convertToWT=%s -D convertToBufT=%s -D convertToDT=%s%s",
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace cv {
|
||||
|
||||
Mat _InputArray::getMat_(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
int accessFlags = flags & ACCESS_MASK;
|
||||
_InputArray::KindFlag k = kind();
|
||||
AccessFlag accessFlags = flags & ACCESS_MASK;
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -132,8 +132,8 @@ Mat _InputArray::getMat_(int i) const
|
||||
|
||||
UMat _InputArray::getUMat(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
int accessFlags = flags & ACCESS_MASK;
|
||||
_InputArray::KindFlag k = kind();
|
||||
AccessFlag accessFlags = flags & ACCESS_MASK;
|
||||
|
||||
if( k == UMAT )
|
||||
{
|
||||
@@ -164,8 +164,8 @@ UMat _InputArray::getUMat(int i) const
|
||||
|
||||
void _InputArray::getMatVector(std::vector<Mat>& mv) const
|
||||
{
|
||||
int k = kind();
|
||||
int accessFlags = flags & ACCESS_MASK;
|
||||
_InputArray::KindFlag k = kind();
|
||||
AccessFlag accessFlags = flags & ACCESS_MASK;
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -272,8 +272,8 @@ void _InputArray::getMatVector(std::vector<Mat>& mv) const
|
||||
|
||||
void _InputArray::getUMatVector(std::vector<UMat>& umv) const
|
||||
{
|
||||
int k = kind();
|
||||
int accessFlags = flags & ACCESS_MASK;
|
||||
_InputArray::KindFlag k = kind();
|
||||
AccessFlag accessFlags = flags & ACCESS_MASK;
|
||||
|
||||
if( k == NONE )
|
||||
{
|
||||
@@ -334,7 +334,7 @@ void _InputArray::getUMatVector(std::vector<UMat>& umv) const
|
||||
|
||||
cuda::GpuMat _InputArray::getGpuMat() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if (k == CUDA_GPU_MAT)
|
||||
{
|
||||
@@ -360,7 +360,7 @@ cuda::GpuMat _InputArray::getGpuMat() const
|
||||
}
|
||||
void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if (k == STD_VECTOR_CUDA_GPU_MAT)
|
||||
{
|
||||
gpumv = *(std::vector<cuda::GpuMat>*)obj;
|
||||
@@ -368,7 +368,7 @@ void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
|
||||
}
|
||||
ogl::Buffer _InputArray::getOGlBuffer() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
CV_Assert(k == OPENGL_BUFFER);
|
||||
|
||||
@@ -376,7 +376,7 @@ ogl::Buffer _InputArray::getOGlBuffer() const
|
||||
return *gl_buf;
|
||||
}
|
||||
|
||||
int _InputArray::kind() const
|
||||
_InputArray::KindFlag _InputArray::kind() const
|
||||
{
|
||||
return flags & KIND_MASK;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ int _InputArray::cols(int i) const
|
||||
|
||||
Size _InputArray::size(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -515,7 +515,8 @@ Size _InputArray::size(int i) const
|
||||
|
||||
int _InputArray::sizend(int* arrsz, int i) const
|
||||
{
|
||||
int j, d=0, k = kind();
|
||||
int j, d = 0;
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == NONE )
|
||||
;
|
||||
@@ -583,7 +584,7 @@ int _InputArray::sizend(int* arrsz, int i) const
|
||||
|
||||
bool _InputArray::sameSize(const _InputArray& arr) const
|
||||
{
|
||||
int k1 = kind(), k2 = arr.kind();
|
||||
_InputArray::KindFlag k1 = kind(), k2 = arr.kind();
|
||||
Size sz1;
|
||||
|
||||
if( k1 == MAT )
|
||||
@@ -617,7 +618,7 @@ bool _InputArray::sameSize(const _InputArray& arr) const
|
||||
|
||||
int _InputArray::dims(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -714,7 +715,7 @@ int _InputArray::dims(int i) const
|
||||
|
||||
size_t _InputArray::total(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -763,7 +764,7 @@ size_t _InputArray::total(int i) const
|
||||
|
||||
int _InputArray::type(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
return ((const Mat*)obj)->type();
|
||||
@@ -852,7 +853,7 @@ int _InputArray::channels(int i) const
|
||||
|
||||
bool _InputArray::empty() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
return ((const Mat*)obj)->empty();
|
||||
@@ -924,7 +925,7 @@ bool _InputArray::empty() const
|
||||
|
||||
bool _InputArray::isContinuous(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
return i < 0 ? ((const Mat*)obj)->isContinuous() : true;
|
||||
@@ -965,7 +966,7 @@ bool _InputArray::isContinuous(int i) const
|
||||
|
||||
bool _InputArray::isSubmatrix(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
return i < 0 ? ((const Mat*)obj)->isSubmatrix() : false;
|
||||
@@ -1003,7 +1004,7 @@ bool _InputArray::isSubmatrix(int i) const
|
||||
|
||||
size_t _InputArray::offset(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -1067,7 +1068,7 @@ size_t _InputArray::offset(int i) const
|
||||
|
||||
size_t _InputArray::step(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -1127,7 +1128,7 @@ size_t _InputArray::step(int i) const
|
||||
|
||||
void _InputArray::copyTo(const _OutputArray& arr) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == NONE )
|
||||
arr.release();
|
||||
@@ -1156,7 +1157,7 @@ void _InputArray::copyTo(const _OutputArray& arr) const
|
||||
|
||||
void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == NONE )
|
||||
arr.release();
|
||||
@@ -1185,9 +1186,9 @@ bool _OutputArray::fixedType() const
|
||||
return (flags & FIXED_TYPE) == FIXED_TYPE;
|
||||
}
|
||||
|
||||
void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
|
||||
void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
|
||||
{
|
||||
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz);
|
||||
@@ -1227,9 +1228,9 @@ void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int
|
||||
create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
|
||||
}
|
||||
|
||||
void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
|
||||
void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
|
||||
{
|
||||
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows));
|
||||
@@ -1270,7 +1271,7 @@ void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTran
|
||||
}
|
||||
|
||||
void _OutputArray::create(int d, const int* sizes, int mtype, int i,
|
||||
bool allowTransposed, int fixedDepthMask) const
|
||||
bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
|
||||
{
|
||||
int sizebuf[2];
|
||||
if(d == 1)
|
||||
@@ -1280,7 +1281,7 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
|
||||
sizebuf[1] = 1;
|
||||
sizes = sizebuf;
|
||||
}
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
mtype = CV_MAT_TYPE(mtype);
|
||||
|
||||
if( k == MAT )
|
||||
@@ -1667,7 +1668,7 @@ void _OutputArray::release() const
|
||||
{
|
||||
CV_Assert(!fixedSize());
|
||||
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -1735,7 +1736,7 @@ void _OutputArray::release() const
|
||||
|
||||
void _OutputArray::clear() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == MAT )
|
||||
{
|
||||
@@ -1754,7 +1755,7 @@ bool _OutputArray::needed() const
|
||||
|
||||
Mat& _OutputArray::getMatRef(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if( i < 0 )
|
||||
{
|
||||
CV_Assert( k == MAT );
|
||||
@@ -1779,7 +1780,7 @@ Mat& _OutputArray::getMatRef(int i) const
|
||||
|
||||
UMat& _OutputArray::getUMatRef(int i) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if( i < 0 )
|
||||
{
|
||||
CV_Assert( k == UMAT );
|
||||
@@ -1796,34 +1797,34 @@ UMat& _OutputArray::getUMatRef(int i) const
|
||||
|
||||
cuda::GpuMat& _OutputArray::getGpuMatRef() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
CV_Assert( k == CUDA_GPU_MAT );
|
||||
return *(cuda::GpuMat*)obj;
|
||||
}
|
||||
std::vector<cuda::GpuMat>& _OutputArray::getGpuMatVecRef() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
CV_Assert(k == STD_VECTOR_CUDA_GPU_MAT);
|
||||
return *(std::vector<cuda::GpuMat>*)obj;
|
||||
}
|
||||
|
||||
ogl::Buffer& _OutputArray::getOGlBufferRef() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
CV_Assert( k == OPENGL_BUFFER );
|
||||
return *(ogl::Buffer*)obj;
|
||||
}
|
||||
|
||||
cuda::HostMem& _OutputArray::getHostMemRef() const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
CV_Assert( k == CUDA_HOST_MEM );
|
||||
return *(cuda::HostMem*)obj;
|
||||
}
|
||||
|
||||
void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
|
||||
if( k == NONE )
|
||||
;
|
||||
@@ -1847,7 +1848,7 @@ void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
|
||||
|
||||
void _OutputArray::assign(const UMat& u) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if (k == UMAT)
|
||||
{
|
||||
*(UMat*)obj = u;
|
||||
@@ -1869,7 +1870,7 @@ void _OutputArray::assign(const UMat& u) const
|
||||
|
||||
void _OutputArray::assign(const Mat& m) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if (k == UMAT)
|
||||
{
|
||||
m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
|
||||
@@ -1891,7 +1892,7 @@ void _OutputArray::assign(const Mat& m) const
|
||||
|
||||
void _OutputArray::assign(const std::vector<UMat>& v) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if (k == STD_VECTOR_UMAT)
|
||||
{
|
||||
std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
|
||||
@@ -1929,7 +1930,7 @@ void _OutputArray::assign(const std::vector<UMat>& v) const
|
||||
|
||||
void _OutputArray::assign(const std::vector<Mat>& v) const
|
||||
{
|
||||
int k = kind();
|
||||
_InputArray::KindFlag k = kind();
|
||||
if (k == STD_VECTOR_UMAT)
|
||||
{
|
||||
std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
|
||||
|
||||
+48
-22
@@ -238,6 +238,20 @@ static const bool CV_OPENCL_DISABLE_BUFFER_RECT_OPERATIONS = utils::getConfigura
|
||||
#endif
|
||||
);
|
||||
|
||||
static const String getBuildExtraOptions()
|
||||
{
|
||||
static String param_buildExtraOptions;
|
||||
static bool initialized = false;
|
||||
if (!initialized)
|
||||
{
|
||||
param_buildExtraOptions = utils::getConfigurationParameterString("OPENCV_OPENCL_BUILD_EXTRA_OPTIONS", "");
|
||||
initialized = true;
|
||||
if (!param_buildExtraOptions.empty())
|
||||
CV_LOG_WARNING(NULL, "OpenCL: using extra build options: '" << param_buildExtraOptions << "'");
|
||||
}
|
||||
return param_buildExtraOptions;
|
||||
}
|
||||
|
||||
#endif // HAVE_OPENCL
|
||||
|
||||
struct UMat2D
|
||||
@@ -2972,8 +2986,8 @@ int Kernel::set(int i, const KernelArg& arg)
|
||||
cl_int status = 0;
|
||||
if( arg.m )
|
||||
{
|
||||
int accessFlags = ((arg.flags & KernelArg::READ_ONLY) ? ACCESS_READ : 0) +
|
||||
((arg.flags & KernelArg::WRITE_ONLY) ? ACCESS_WRITE : 0);
|
||||
AccessFlag accessFlags = ((arg.flags & KernelArg::READ_ONLY) ? ACCESS_READ : static_cast<AccessFlag>(0)) |
|
||||
((arg.flags & KernelArg::WRITE_ONLY) ? ACCESS_WRITE : static_cast<AccessFlag>(0));
|
||||
bool ptronly = (arg.flags & KernelArg::PTR_ONLY) != 0;
|
||||
cl_mem h = (cl_mem)arg.m->handle(accessFlags);
|
||||
|
||||
@@ -3050,7 +3064,7 @@ int Kernel::set(int i, const KernelArg& arg)
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
p->addUMat(*arg.m, (accessFlags & ACCESS_WRITE) != 0);
|
||||
p->addUMat(*arg.m, !!(accessFlags & ACCESS_WRITE));
|
||||
return i;
|
||||
}
|
||||
status = clSetKernelArg(p->handle, (cl_uint)i, arg.sz, arg.obj);
|
||||
@@ -3073,7 +3087,7 @@ bool Kernel::run(int dims, size_t _globalsize[], size_t _localsize[],
|
||||
dims == 1 ? 64 : dims == 2 ? (i == 0 ? 256 : 8) : dims == 3 ? (8>>(int)(i>0)) : 1;
|
||||
CV_Assert( val > 0 );
|
||||
total *= _globalsize[i];
|
||||
if (_globalsize[i] == 1)
|
||||
if (_globalsize[i] == 1 && !_localsize)
|
||||
val = 1;
|
||||
globalsize[i] = divUp(_globalsize[i], (unsigned int)val) * val;
|
||||
}
|
||||
@@ -3086,7 +3100,7 @@ bool Kernel::run(int dims, size_t _globalsize[], size_t _localsize[],
|
||||
bool Kernel::Impl::run(int dims, size_t globalsize[], size_t localsize[],
|
||||
bool sync, int64* timeNS, const Queue& q)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_OPENCL_RUN(name.c_str(););
|
||||
CV_INSTRUMENT_REGION_OPENCL_RUN(name.c_str());
|
||||
|
||||
if (!handle || isInProgress)
|
||||
return false;
|
||||
@@ -3104,9 +3118,9 @@ bool Kernel::Impl::run(int dims, size_t globalsize[], size_t localsize[],
|
||||
if (retval != CL_SUCCESS)
|
||||
#endif
|
||||
{
|
||||
cv::String msg = cv::format("clEnqueueNDRangeKernel('%s', dims=%d, globalsize=%dx%dx%d, localsize=%s) sync=%s", name.c_str(), (int)dims,
|
||||
cv::String msg = cv::format("clEnqueueNDRangeKernel('%s', dims=%d, globalsize=%zux%zux%zu, localsize=%s) sync=%s", name.c_str(), (int)dims,
|
||||
globalsize[0], (dims > 1 ? globalsize[1] : 1), (dims > 2 ? globalsize[2] : 1),
|
||||
(localsize ? cv::format("%dx%dx%d", localsize[0], (dims > 1 ? localsize[1] : 1), (dims > 2 ? localsize[2] : 1)) : cv::String("NULL")).c_str(),
|
||||
(localsize ? cv::format("%zux%zux%zu", localsize[0], (dims > 1 ? localsize[1] : 1), (dims > 2 ? localsize[2] : 1)) : cv::String("NULL")).c_str(),
|
||||
sync ? "true" : "false"
|
||||
);
|
||||
if (retval != CL_SUCCESS)
|
||||
@@ -3317,7 +3331,7 @@ struct ProgramSource::Impl
|
||||
default:
|
||||
CV_Error(Error::StsInternal, "Internal error");
|
||||
}
|
||||
sourceHash_ = cv::format("%08llx", hash);
|
||||
sourceHash_ = cv::format("%08jx", (uintmax_t)hash);
|
||||
isHashUpdated = true;
|
||||
}
|
||||
|
||||
@@ -3517,6 +3531,9 @@ struct Program::Impl
|
||||
buildflags = joinBuildOptions(buildflags, " -D AMD_DEVICE");
|
||||
else if (device.isIntel())
|
||||
buildflags = joinBuildOptions(buildflags, " -D INTEL_DEVICE");
|
||||
const String param_buildExtraOptions = getBuildExtraOptions();
|
||||
if (!param_buildExtraOptions.empty())
|
||||
buildflags = joinBuildOptions(buildflags, param_buildExtraOptions);
|
||||
}
|
||||
compile(ctx, src_, errmsg);
|
||||
}
|
||||
@@ -4516,13 +4533,13 @@ public:
|
||||
}
|
||||
|
||||
UMatData* defaultAllocate(int dims, const int* sizes, int type, void* data, size_t* step,
|
||||
int flags, UMatUsageFlags usageFlags) const
|
||||
AccessFlag flags, UMatUsageFlags usageFlags) const
|
||||
{
|
||||
UMatData* u = matStdAllocator->allocate(dims, sizes, type, data, step, flags, usageFlags);
|
||||
return u;
|
||||
}
|
||||
|
||||
void getBestFlags(const Context& ctx, int /*flags*/, UMatUsageFlags usageFlags, int& createFlags, int& flags0) const
|
||||
void getBestFlags(const Context& ctx, AccessFlag /*flags*/, UMatUsageFlags usageFlags, int& createFlags, UMatData::MemoryFlag& flags0) const
|
||||
{
|
||||
const Device& dev = ctx.device(0);
|
||||
createFlags = 0;
|
||||
@@ -4530,13 +4547,13 @@ public:
|
||||
createFlags |= CL_MEM_ALLOC_HOST_PTR;
|
||||
|
||||
if( dev.hostUnifiedMemory() )
|
||||
flags0 = 0;
|
||||
flags0 = static_cast<UMatData::MemoryFlag>(0);
|
||||
else
|
||||
flags0 = UMatData::COPY_ON_MAP;
|
||||
}
|
||||
|
||||
UMatData* allocate(int dims, const int* sizes, int type,
|
||||
void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const CV_OVERRIDE
|
||||
void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const CV_OVERRIDE
|
||||
{
|
||||
if(!useOpenCL())
|
||||
return defaultAllocate(dims, sizes, type, data, step, flags, usageFlags);
|
||||
@@ -4552,7 +4569,8 @@ public:
|
||||
Context& ctx = Context::getDefault();
|
||||
flushCleanupQueue();
|
||||
|
||||
int createFlags = 0, flags0 = 0;
|
||||
int createFlags = 0;
|
||||
UMatData::MemoryFlag flags0 = static_cast<UMatData::MemoryFlag>(0);
|
||||
getBestFlags(ctx, flags, usageFlags, createFlags, flags0);
|
||||
|
||||
void* handle = NULL;
|
||||
@@ -4600,7 +4618,7 @@ public:
|
||||
return u;
|
||||
}
|
||||
|
||||
bool allocate(UMatData* u, int accessFlags, UMatUsageFlags usageFlags) const CV_OVERRIDE
|
||||
bool allocate(UMatData* u, AccessFlag accessFlags, UMatUsageFlags usageFlags) const CV_OVERRIDE
|
||||
{
|
||||
if(!u)
|
||||
return false;
|
||||
@@ -4613,12 +4631,13 @@ public:
|
||||
{
|
||||
CV_Assert(u->origdata != 0);
|
||||
Context& ctx = Context::getDefault();
|
||||
int createFlags = 0, flags0 = 0;
|
||||
int createFlags = 0;
|
||||
UMatData::MemoryFlag flags0 = static_cast<UMatData::MemoryFlag>(0);
|
||||
getBestFlags(ctx, accessFlags, usageFlags, createFlags, flags0);
|
||||
|
||||
cl_context ctx_handle = (cl_context)ctx.ptr();
|
||||
int allocatorFlags = 0;
|
||||
int tempUMatFlags = 0;
|
||||
UMatData::MemoryFlag tempUMatFlags = static_cast<UMatData::MemoryFlag>(0);
|
||||
void* handle = NULL;
|
||||
cl_int retval = CL_SUCCESS;
|
||||
|
||||
@@ -4703,7 +4722,7 @@ public:
|
||||
u->flags |= tempUMatFlags;
|
||||
u->allocatorFlags_ = allocatorFlags;
|
||||
}
|
||||
if(accessFlags & ACCESS_WRITE)
|
||||
if (!!(accessFlags & ACCESS_WRITE))
|
||||
u->markHostCopyObsolete(true);
|
||||
return true;
|
||||
}
|
||||
@@ -4749,7 +4768,7 @@ public:
|
||||
CV_Assert(u->handle != 0);
|
||||
CV_Assert(u->mapcount == 0);
|
||||
|
||||
if (u->flags & UMatData::ASYNC_CLEANUP)
|
||||
if (!!(u->flags & UMatData::ASYNC_CLEANUP))
|
||||
addToCleanupQueue(u);
|
||||
else
|
||||
deallocate_(u);
|
||||
@@ -4757,6 +4776,10 @@ public:
|
||||
|
||||
void deallocate_(UMatData* u) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (cv::__termination) // process is not in consistent state (after ExitProcess call) and terminating
|
||||
return; // avoid any OpenCL calls
|
||||
#endif
|
||||
if(u->tempUMat())
|
||||
{
|
||||
CV_Assert(u->origdata);
|
||||
@@ -4924,11 +4947,11 @@ public:
|
||||
}
|
||||
|
||||
// synchronized call (external UMatDataAutoLock, see UMat::getMat)
|
||||
void map(UMatData* u, int accessFlags) const CV_OVERRIDE
|
||||
void map(UMatData* u, AccessFlag accessFlags) const CV_OVERRIDE
|
||||
{
|
||||
CV_Assert(u && u->handle);
|
||||
|
||||
if(accessFlags & ACCESS_WRITE)
|
||||
if (!!(accessFlags & ACCESS_WRITE))
|
||||
u->markDeviceCopyObsolete(true);
|
||||
|
||||
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
|
||||
@@ -4995,7 +5018,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if( (accessFlags & ACCESS_READ) != 0 && u->hostCopyObsolete() )
|
||||
if (!!(accessFlags & ACCESS_READ) && u->hostCopyObsolete())
|
||||
{
|
||||
AlignedDataPtr<false, true> alignedPtr(u->data, u->size, CV_OPENCL_DATA_PTR_ALIGNMENT);
|
||||
#ifdef HAVE_OPENCL_SVM
|
||||
@@ -5735,7 +5758,7 @@ void convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, int
|
||||
dst.u = new UMatData(getOpenCLAllocator());
|
||||
dst.u->data = 0;
|
||||
dst.u->allocatorFlags_ = 0; // not allocated from any OpenCV buffer pool
|
||||
dst.u->flags = 0;
|
||||
dst.u->flags = static_cast<UMatData::MemoryFlag>(0);
|
||||
dst.u->handle = cl_mem_buffer;
|
||||
dst.u->origdata = 0;
|
||||
dst.u->prevAllocator = 0;
|
||||
@@ -5982,6 +6005,7 @@ const char* typeToStr(int type)
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
|
||||
};
|
||||
int cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
|
||||
CV_Assert(depth != CV_16F); // Workaround for: https://github.com/opencv/opencv/issues/12824
|
||||
return cn > 16 ? "?" : tab[depth*16 + cn-1];
|
||||
}
|
||||
|
||||
@@ -5999,6 +6023,7 @@ const char* memopTypeToStr(int type)
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
|
||||
};
|
||||
int cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
|
||||
CV_Assert(depth != CV_16F); // Workaround for: https://github.com/opencv/opencv/issues/12824
|
||||
return cn > 16 ? "?" : tab[depth*16 + cn-1];
|
||||
}
|
||||
|
||||
@@ -6016,6 +6041,7 @@ const char* vecopTypeToStr(int type)
|
||||
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
|
||||
};
|
||||
int cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
|
||||
CV_Assert(depth != CV_16F); // Workaround for: https://github.com/opencv/opencv/issues/12824
|
||||
return cn > 16 ? "?" : tab[depth*16 + cn-1];
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,30 @@
|
||||
#pragma OPENCL FP_FAST_FMA ON
|
||||
#endif
|
||||
|
||||
#if depth <= 5
|
||||
#if !defined(DEPTH_dst)
|
||||
#error "Kernel configuration error: DEPTH_dst value is required"
|
||||
#elif !(DEPTH_dst >= 0 && DEPTH_dst <= 7)
|
||||
#error "Kernel configuration error: invalid DEPTH_dst value"
|
||||
#endif
|
||||
#if defined(depth)
|
||||
#error "Kernel configuration error: ambiguous 'depth' value is defined, use 'DEPTH_dst' instead"
|
||||
#endif
|
||||
|
||||
|
||||
#if DEPTH_dst < 5 /* CV_32F */
|
||||
#define CV_DST_TYPE_IS_INTEGER
|
||||
#else
|
||||
#define CV_DST_TYPE_IS_FP
|
||||
#endif
|
||||
|
||||
#if DEPTH_dst != 6 /* CV_64F */
|
||||
#define CV_DST_TYPE_FIT_32F 1
|
||||
#else
|
||||
#define CV_DST_TYPE_FIT_32F 0
|
||||
#endif
|
||||
|
||||
|
||||
#if CV_DST_TYPE_FIT_32F
|
||||
#define CV_PI M_PI_F
|
||||
#else
|
||||
#define CV_PI M_PI
|
||||
@@ -204,9 +227,15 @@
|
||||
#define PROCESS_ELEM storedst(convertToDT(srcelem1 * scale * srcelem2))
|
||||
|
||||
#elif defined OP_DIV
|
||||
#ifdef CV_DST_TYPE_IS_INTEGER
|
||||
#define PROCESS_ELEM \
|
||||
workT e2 = srcelem2, zero = (workT)(0); \
|
||||
storedst(convertToDT(e2 != zero ? srcelem1 / e2 : zero))
|
||||
#else
|
||||
#define PROCESS_ELEM \
|
||||
workT e2 = srcelem2; \
|
||||
storedst(convertToDT(srcelem1 / e2))
|
||||
#endif
|
||||
|
||||
#elif defined OP_DIV_SCALE
|
||||
#undef EXTRA_PARAMS
|
||||
@@ -217,9 +246,15 @@
|
||||
#else
|
||||
#define EXTRA_PARAMS , scaleT scale
|
||||
#endif
|
||||
#ifdef CV_DST_TYPE_IS_INTEGER
|
||||
#define PROCESS_ELEM \
|
||||
workT e2 = srcelem2, zero = (workT)(0); \
|
||||
storedst(convertToDT(e2 == zero ? zero : (srcelem1 * (workT)(scale) / e2)))
|
||||
#else
|
||||
#define PROCESS_ELEM \
|
||||
workT e2 = srcelem2; \
|
||||
storedst(convertToDT(srcelem1 * (workT)(scale) / e2))
|
||||
#endif
|
||||
|
||||
#elif defined OP_RDIV_SCALE
|
||||
#undef EXTRA_PARAMS
|
||||
@@ -230,16 +265,28 @@
|
||||
#else
|
||||
#define EXTRA_PARAMS , scaleT scale
|
||||
#endif
|
||||
#ifdef CV_DST_TYPE_IS_INTEGER
|
||||
#define PROCESS_ELEM \
|
||||
workT e1 = srcelem1, zero = (workT)(0); \
|
||||
storedst(convertToDT(e1 == zero ? zero : (srcelem2 * (workT)(scale) / e1)))
|
||||
#else
|
||||
#define PROCESS_ELEM \
|
||||
workT e1 = srcelem1; \
|
||||
storedst(convertToDT(srcelem2 * (workT)(scale) / e1))
|
||||
#endif
|
||||
|
||||
#elif defined OP_RECIP_SCALE
|
||||
#undef EXTRA_PARAMS
|
||||
#define EXTRA_PARAMS , scaleT scale
|
||||
#ifdef CV_DST_TYPE_IS_INTEGER
|
||||
#define PROCESS_ELEM \
|
||||
workT e1 = srcelem1, zero = (workT)(0); \
|
||||
storedst(convertToDT(e1 != zero ? scale / e1 : zero))
|
||||
#else
|
||||
#define PROCESS_ELEM \
|
||||
workT e1 = srcelem1; \
|
||||
storedst(convertToDT(scale / e1))
|
||||
#endif
|
||||
|
||||
#elif defined OP_ADDW
|
||||
#undef EXTRA_PARAMS
|
||||
@@ -283,7 +330,7 @@
|
||||
#define PROCESS_ELEM storedst(pown(srcelem1, srcelem2))
|
||||
|
||||
#elif defined OP_SQRT
|
||||
#if depth <= 5
|
||||
#if CV_DST_TYPE_FIT_32F
|
||||
#define PROCESS_ELEM storedst(native_sqrt(srcelem1))
|
||||
#else
|
||||
#define PROCESS_ELEM storedst(sqrt(srcelem1))
|
||||
@@ -324,7 +371,7 @@
|
||||
#endif
|
||||
|
||||
#elif defined OP_CTP_AD || defined OP_CTP_AR
|
||||
#if depth <= 5
|
||||
#if CV_DST_TYPE_FIT_32F
|
||||
#define CV_EPSILON FLT_EPSILON
|
||||
#else
|
||||
#define CV_EPSILON DBL_EPSILON
|
||||
|
||||
+11
-11
@@ -1434,14 +1434,14 @@ void cv::ogl::render(const ogl::Texture2D& tex, Rect_<double> wndRect, Rect_<dou
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);
|
||||
CV_CheckGlError();
|
||||
|
||||
const float vertex[] =
|
||||
const double vertex[] =
|
||||
{
|
||||
wndRect.x, wndRect.y, 0.0f,
|
||||
wndRect.x, (wndRect.y + wndRect.height), 0.0f,
|
||||
wndRect.x + wndRect.width, (wndRect.y + wndRect.height), 0.0f,
|
||||
wndRect.x + wndRect.width, wndRect.y, 0.0f
|
||||
wndRect.x, wndRect.y, 0.0,
|
||||
wndRect.x, (wndRect.y + wndRect.height), 0.0,
|
||||
wndRect.x + wndRect.width, (wndRect.y + wndRect.height), 0.0,
|
||||
wndRect.x + wndRect.width, wndRect.y, 0.0
|
||||
};
|
||||
const float texCoords[] =
|
||||
const double texCoords[] =
|
||||
{
|
||||
texRect.x, texRect.y,
|
||||
texRect.x, texRect.y + texRect.height,
|
||||
@@ -1454,7 +1454,7 @@ void cv::ogl::render(const ogl::Texture2D& tex, Rect_<double> wndRect, Rect_<dou
|
||||
gl::EnableClientState(gl::TEXTURE_COORD_ARRAY);
|
||||
CV_CheckGlError();
|
||||
|
||||
gl::TexCoordPointer(2, gl::FLOAT, 0, texCoords);
|
||||
gl::TexCoordPointer(2, gl::DOUBLE, 0, texCoords);
|
||||
CV_CheckGlError();
|
||||
|
||||
gl::DisableClientState(gl::NORMAL_ARRAY);
|
||||
@@ -1464,7 +1464,7 @@ void cv::ogl::render(const ogl::Texture2D& tex, Rect_<double> wndRect, Rect_<dou
|
||||
gl::EnableClientState(gl::VERTEX_ARRAY);
|
||||
CV_CheckGlError();
|
||||
|
||||
gl::VertexPointer(3, gl::FLOAT, 0, vertex);
|
||||
gl::VertexPointer(3, gl::DOUBLE, 0, vertex);
|
||||
CV_CheckGlError();
|
||||
|
||||
gl::DrawArrays(gl::QUADS, 0, 4);
|
||||
@@ -1804,8 +1804,8 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
|
||||
#endif
|
||||
}
|
||||
|
||||
//void mapGLBuffer(const Buffer& buffer, UMat& dst, int accessFlags)
|
||||
UMat mapGLBuffer(const Buffer& buffer, int accessFlags)
|
||||
//void mapGLBuffer(const Buffer& buffer, UMat& dst, AccessFlag accessFlags)
|
||||
UMat mapGLBuffer(const Buffer& buffer, AccessFlag accessFlags)
|
||||
{
|
||||
CV_UNUSED(buffer); CV_UNUSED(accessFlags);
|
||||
#if !defined(HAVE_OPENGL)
|
||||
@@ -1824,7 +1824,7 @@ UMat mapGLBuffer(const Buffer& buffer, int accessFlags)
|
||||
switch (accessFlags & (ACCESS_READ|ACCESS_WRITE))
|
||||
{
|
||||
default:
|
||||
case ACCESS_READ|ACCESS_WRITE:
|
||||
case ACCESS_READ+ACCESS_WRITE:
|
||||
clAccessFlags = CL_MEM_READ_WRITE;
|
||||
break;
|
||||
case ACCESS_READ:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user