1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2025-11-17 12:30:39 +03:00
64 changed files with 988 additions and 384 deletions
+25 -9
View File
@@ -1,18 +1,34 @@
ocv_update(ORBBEC_SDK_VERSION "2")
ocv_update(ORBBEC_SDK_DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/3rdparty/orbbecsdk")
function(download_orbbec_sdk root_var)
set(ORBBECSDK_DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/3rdparty/orbbecsdk")
set(ORBBECSDK_FILE_HASH_CMAKE "e7566fa915a1b0c02640df41891916fe")
ocv_download(FILENAME "v1.9.4.tar.gz"
HASH ${ORBBECSDK_FILE_HASH_CMAKE}
URL "https://github.com/orbbec/OrbbecSDK/archive/refs/tags/v1.9.4/"
DESTINATION_DIR ${ORBBECSDK_DOWNLOAD_DIR}
if(ORBBEC_SDK_VERSION STREQUAL "1")
set(ORBBEC_SDK_FILE_HASH_CMAKE "e7566fa915a1b0c02640df41891916fe")
set(ORBBEC_SDK_GIT_TAG "1.9.4")
add_definitions(-DORBBEC_SDK_VERSION_MAJOR=1)
elseif(ORBBEC_SDK_VERSION STREQUAL "2")
set(ORBBEC_SDK_FILE_HASH_CMAKE "d828ac15618a56b9ae325bada8676e28")
set(ORBBEC_SDK_GIT_TAG "2.5.5")
add_definitions(-DORBBEC_SDK_VERSION_MAJOR=2)
else()
message(STATUS "Unsupported OrbbecSDK version: ${ORBBEC_SDK_VERSION}, use default version 2")
set(ORBBEC_SDK_FILE_HASH_CMAKE "d828ac15618a56b9ae325bada8676e28")
set(ORBBEC_SDK_GIT_TAG "2.5.5")
add_definitions(-DORBBEC_SDK_VERSION_MAJOR=2)
endif()
ocv_download(FILENAME "v${ORBBEC_SDK_GIT_TAG}.tar.gz"
HASH ${ORBBEC_SDK_FILE_HASH_CMAKE}
URL "https://github.com/orbbec/OrbbecSDK/archive/refs/tags/v${ORBBEC_SDK_GIT_TAG}/"
DESTINATION_DIR ${ORBBEC_SDK_DOWNLOAD_DIR}
ID OrbbecSDK
STATUS res
UNPACK RELATIVE_URL
)
if(${res})
message(STATUS "orbbec sdk downloaded to: ${ORBBECSDK_DOWNLOAD_DIR}")
set(${root_var} "${ORBBECSDK_DOWNLOAD_DIR}/OrbbecSDK-1.9.4" PARENT_SCOPE)
message(STATUS "OrbbecSDK downloaded to: ${ORBBEC_SDK_DOWNLOAD_DIR}")
set(${root_var} "${ORBBEC_SDK_DOWNLOAD_DIR}/OrbbecSDK-${ORBBEC_SDK_GIT_TAG}" PARENT_SCOPE)
else()
message(FATAL_ERROR "Failed to download orbbec sdk")
message(FATAL_ERROR "Failed to download OrbbecSDK")
endif()
endfunction()
+5
View File
@@ -106,6 +106,11 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS
set(TBB_SOURCE_FILES ${lib_srcs} ${lib_hdrs})
set(tbb_version_file "version_string.ver")
if(NOT BUILD_INFO_SKIP_SYSTEM_VERSION)
set(TBB_HOST_VERSION " ${CMAKE_HOST_SYSTEM_VERSION}")
else()
set(TBB_HOST_VERSION "")
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}.cmakein" "${CMAKE_CURRENT_BINARY_DIR}/${tbb_version_file}" @ONLY)
list(APPEND TBB_SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/${tbb_version_file}")
+1 -1
View File
@@ -1,6 +1,6 @@
#define __TBB_VERSION_STRINGS(N) \
#N": BUILD_PACKAGE OpenCV @OPENCV_VERSION@" ENDL \
#N": BUILD_HOST @CMAKE_HOST_SYSTEM_NAME@ @CMAKE_HOST_SYSTEM_VERSION@ @CMAKE_HOST_SYSTEM_PROCESSOR@" ENDL \
#N": BUILD_HOST @CMAKE_HOST_SYSTEM_NAME@@TBB_HOST_VERSION@ @CMAKE_HOST_SYSTEM_PROCESSOR@" ENDL \
#N": BUILD_TARGET @CMAKE_SYSTEM_NAME@ @CMAKE_SYSTEM_VERSION@ @CMAKE_SYSTEM_PROCESSOR@" ENDL \
#N": BUILD_COMPILER @CMAKE_CXX_COMPILER@ (ver @CMAKE_CXX_COMPILER_VERSION@)" ENDL \
#N": BUILD_COMMAND use cv::getBuildInformation() for details" ENDL
+6 -2
View File
@@ -1152,7 +1152,11 @@ endif()
if(OPENCV_TIMESTAMP)
status(" Timestamp:" ${OPENCV_TIMESTAMP})
endif()
status(" Host:" ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_VERSION} ${CMAKE_HOST_SYSTEM_PROCESSOR})
if(NOT BUILD_INFO_SKIP_SYSTEM_VERSION)
status(" Host:" ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_VERSION} ${CMAKE_HOST_SYSTEM_PROCESSOR})
else()
status(" Host:" ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_PROCESSOR})
endif()
if(CMAKE_CROSSCOMPILING)
status(" Target:" ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR})
endif()
@@ -1543,7 +1547,7 @@ endif()
if(WITH_FFMPEG OR HAVE_FFMPEG)
if(OPENCV_FFMPEG_USE_FIND_PACKAGE)
status(" FFMPEG:" HAVE_FFMPEG THEN "YES (find_package)" ELSE "NO (find_package)")
elseif(WIN32)
elseif(WIN32 AND NOT ARM AND NOT AARCH64)
status(" FFMPEG:" HAVE_FFMPEG THEN "YES (prebuilt binaries)" ELSE NO)
else()
status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO)
+2
View File
@@ -184,6 +184,8 @@ elseif(MSVC)
set(OpenCV_RUNTIME vc16)
elseif(MSVC_VERSION MATCHES "^19[34][0-9]$")
set(OpenCV_RUNTIME vc17)
elseif(MSVC_VERSION MATCHES "^195[0-9]$")
set(OpenCV_RUNTIME vc18)
else()
message(WARNING "OpenCV does not recognize MSVC_VERSION \"${MSVC_VERSION}\". Cannot set OpenCV_RUNTIME")
endif()
@@ -141,15 +141,33 @@ elseif(MSVC)
set(OpenCV_RUNTIME vc17)
check_one_config(has_VS2022)
if(NOT has_VS2022)
set(OpenCV_RUNTIME vc16)
check_one_config(has_VS2019)
if(NOT has_VS2019)
set(OpenCV_RUNTIME vc15) # selecting previous compatible runtime version
check_one_config(has_VS2017)
if(NOT has_VS2017)
set(OpenCV_RUNTIME vc14) # selecting previous compatible runtime version
endif()
endif()
set(OpenCV_RUNTIME vc16) # selecting previous compatible runtime version
check_one_config(has_VS2019)
if(NOT has_VS2019)
set(OpenCV_RUNTIME vc15) # selecting previous compatible runtime version
check_one_config(has_VS2017)
if(NOT has_VS2017)
set(OpenCV_RUNTIME vc14) # selecting previous compatible runtime version
endif()
endif()
endif()
elseif(MSVC_VERSION MATCHES "^195[0-9]$")
set(OpenCV_RUNTIME vc18)
check_one_config(has_VS2026)
if(NOT has_VS2026)
set(OpenCV_RUNTIME vc17) # selecting previous compatible runtime version
check_one_config(has_VS2022)
if(NOT has_VS2022)
set(OpenCV_RUNTIME vc16) # selecting previous compatible runtime version
check_one_config(has_VS2019)
if(NOT has_VS2019)
set(OpenCV_RUNTIME vc15) # selecting previous compatible runtime version
check_one_config(has_VS2017)
if(NOT has_VS2017)
set(OpenCV_RUNTIME vc14) # selecting previous compatible runtime version
endif()
endif()
endif()
endif()
endif()
elseif(MINGW)
@@ -82,7 +82,7 @@ cv.bitwise_and(logo, logo, imgFg, mask);
// Put logo in ROI and modify the main image
cv.add(imgBg, imgFg, sum);
dst = src.clone();
dst = src.mat_clone();
for (let i = 0; i < logo.rows; i++) {
for (let j = 0; j < logo.cols; j++) {
dst.ucharPtr(i, j)[0] = sum.ucharPtr(i, j)[0];
@@ -248,7 +248,7 @@ function backprojection(src) {
if (base instanceof cv.Mat) {
base.delete();
}
base = src.clone();
base = src.mat_clone();
cv.cvtColor(base, base, cv.COLOR_RGB2HSV, 0);
}
cv.cvtColor(src, dstC3, cv.COLOR_RGB2HSV, 0);
@@ -53,7 +53,7 @@ canvas.addEventListener('click', e => {
});
canvas.addEventListener('mousemove', e => {
let x = e.offsetX, y = e.offsetY; //console.log(x, y);
let dst = src.clone();
let dst = src.mat_clone();
if (hasMap && x >= 0 && x < src.cols && y >= 0 && y < src.rows)
{
let contour = new cv.Mat();
@@ -77,12 +77,14 @@ How to copy Mat
There are 2 ways to copy a Mat:
@code{.js}
// 1. Clone
let dst = src.clone();
// 1. Clone (deep copy)
let dst = src.mat_clone();
// 2. CopyTo(only entries indicated in the mask are copied)
src.copyTo(dst, mask);
@endcode
@note In OpenCV.js, use `mat_clone()` instead of `clone()` to ensure deep copy behavior. The `clone()` method may perform shallow copy due to Emscripten embind limitations.
How to convert the type of Mat
------------------------------
@@ -0,0 +1,116 @@
# Install OpenCV for Python with pip {#tutorial_py_pip_install}
This quick-start shows the **recommended** way for most users to get OpenCV in Python: install from
**PyPI** with `pip`. It also explains virtual environments, platform notes, and common troubleshooting.
If you need OSspecific alternatives (system packages or source builds), see the OS pages linked
below, but those are **not required** for typical Python use.
@note: OpenCV team maintains **PyPI** packages only. Conda distributions and platform specific builds
are community builds and hardware vendor builds and may differ from the official one.
## Quick start
```bash
# 1) Create and activate a virtual environment (recommended)
python -m venv .venv
# Windows:
.venv\Scripts\activate
# Linux/macOS:
source .venv/bin/activate
# 2) Upgrade pip tooling
python -m pip install --upgrade pip setuptools wheel
# 3) Install OpenCV from PyPI (choose ONE)
pip install opencv-python # main package (most users)
# or
pip install opencv-contrib-python # + extra modules (contrib)
# or
pip install opencv-python-headless # no GUI/backends (servers/CI)
# or
pip install opencv-contrib-python-headless # no GUI/backends with extra modules (servers/CI)
```
### Tiny helloworld
```python
import cv2 as cv
import numpy as np
print("OpenCV:", cv.__version__)
img = np.zeros((120, 400, 3), dtype=np.uint8)
cv.putText(img, "OpenCV OK", (10, 80), cv.FONT_HERSHEY_SIMPLEX, 2, (255,255,255), 3)
# If you installed a non-headless build, you can display a window:
# cv.imshow("hello", img); cv.waitKey(0)
# Always safe (headless or not): save to file
cv.imwrite("hello.png", img)
```
## Virtual environments and IDEs
Using a virtual environment keeps project dependencies isolated. Tools that create or activate envs include:
- `venv` (built-in) and `virtualenv`
- Conda environments
- IDEs (VS Code, PyCharm) that may **auto-create and auto-activate** an env per workspace
If imports fail inside an IDE, verify the interpreter selected by the IDE matches the environment
where you installed OpenCV.
## OS notes
- **Linux:** Your default Python may be `python3`. Use `python3 -m venv .venv` and `python3 -m pip ...`.
If you cannot use a virtual env, `pip --user` installs to your home directory: `python3 -m pip install --user opencv-python`.
- **Windows:** Install Python from [python.org] or via `winget install Python.Python.3`. Make sure
**“Add python to PATH”** is enabled or use the **“Open in terminal”** from your IDE, which selects
the right interpreter automatically.
- **macOS:** Use the system `python3` or a managed one (Homebrew or Python.org).
Always prefer a virtual environment.
- **Raspberry Pi / ARM boards:** Prebuilt wheels may not exist for some Pi OS / Python combinations.
See **Troubleshooting** below.
## Choosing a PyPI variant
- `opencv-python`: core OpenCV modules with GUI/backends
- `opencv-contrib-python`: includes **contrib** modules in addition to the core
- `opencv-python-headless`: no GUI/backends (ideal for servers/containers/CI)
- `opencv-contrib-python-headless`: contrib + headless
Install exactly **one** of these per environment.
## Troubleshooting
Please start with opencv-python project [README](https://github.com/opencv/opencv-python/blob/4.x/README.md)
**Pip is trying to build from source**
Symptoms: very long build step, CMake errors, compiler errors.
Fixes:
- Upgrade build tooling: `python -m pip install --upgrade pip setuptools wheel`
- Ensure your Python version is supported by the chosen package.
- If you are on an uncommon platform or Python build, switch to a supported Python or try a different
variant (headless vs nonheadless).
**“No matching distribution found” or “Unsupported wheel”**
- Confirm your Python version (e.g., `python -V`). Choose a wheel that supports that version
(manylinux/macOS/Windows wheels on PyPI target specific Python versions).
- Create a fresh virtual environment with a mainstream Python (e.g., 3.103.12 for now) and reinstall.
**Raspberry Pi / ARM**
- Wheels may lag behind new Python/Pi OS releases. Try `opencv-python-headless` first. If
unavailable, consider system packages for camera/GUI pieces, or build from source following
the OS page linked below.
**Import works in terminal but fails in IDE**
- The IDE is using a different interpreter. Select the **same** environment inside your
IDEs interpreter settings.
## What about system packages or building from source?
For beginners using Python, **PyPI is recommended**. Native distribution packages and full source
builds are better suited to advanced users with platformspecific needs. You can still find them on
the OSspecific pages, moved under “Alternatives.”
## See also
- @ref tutorial_py_root
- OS pages: @ref tutorial_py_setup_in_windows, @ref tutorial_py_setup_in_ubuntu, @ref tutorial_py_setup_in_fedora
@@ -1,6 +1,8 @@
Install OpenCV-Python in Ubuntu {#tutorial_py_setup_in_ubuntu}
===============================
@note: Please prefer binaries distributed with PyPI, if possible. See @ref tutorial_py_pip_install for details.
Goals
-----
@@ -18,13 +18,13 @@ Installing OpenCV from prebuilt binaries
-# Below Python packages are to be downloaded and installed to their default locations.
-# Python 3.x (3.4+) or Python 2.7.x from [here](https://www.python.org/downloads/).
-# Python 3.x (3.4+) from [here](https://www.python.org/downloads/).
-# Numpy package (for example, using `pip install numpy` command).
-# Matplotlib (`pip install matplotlib`) (*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
-# Install all packages into their default locations. Python will be installed to `C:/Python27/` in case of Python 2.7.
-# Install all packages into their default locations. Python will be installed to `C:/Python34/` in case of Python 3.4.
-# After installation, open Python IDLE. Enter **import numpy** and make sure Numpy is working fine.
@@ -32,11 +32,11 @@ Installing OpenCV from prebuilt binaries
[SourceForge site](https://sourceforge.net/projects/opencvlibrary/files/)
and double-click to extract it.
-# Goto **opencv/build/python/2.7** folder.
-# Goto **opencv/build/python/3.4** folder.
-# Copy **cv2.pyd** to **C:/Python27/lib/site-packages**.
-# Copy **cv2.pyd** to **C:/Python34/lib/site-packages**.
-# Copy the **opencv_world.dll** file to **C:/Python27/lib/site-packages**
-# Copy the **opencv_world.dll** file to **C:/Python34/lib/site-packages**
-# Open Python IDLE and type following codes in Python terminal.
@code
@@ -6,6 +6,11 @@ Introduction to OpenCV {#tutorial_py_table_of_contents_setup}
Getting Started with
OpenCV-Python
- @subpage tutorial_py_pip_install
Install OpenCV for
Python with pip
- @subpage tutorial_py_setup_in_windows
Set Up
+9
View File
@@ -34,6 +34,15 @@ make
sudo make install
```
By default, when `-DOBSENSOR_USE_ORBBEC_SDK=ON` is enabled, OrbbecSDK v2 is used (i.e., `ORBBEC_SDK_VERSION` defaults to `2`); it supports the entire Orbbec Gemini 330 series.
If you need legacy cameras such as Orbbec Femto, Gemini2XL, or Astra+, switch to OrbbecSDK v1 with the flag `-DORBBEC_SDK_VERSION=1`:
```bash
cmake -DOBSENSOR_USE_ORBBEC_SDK=ON -DORBBEC_SDK_VERSION=1 ..
make -j
sudo make install
```
Code
----
@@ -1,7 +1,7 @@
Using OpenCV with gdb-powered IDEs {#tutorial_linux_gdb_pretty_printer}
=====================
@prev_tutorial{tutorial_linux_install}
@prev_tutorial{tutorial_oneapi_install}
@next_tutorial{tutorial_linux_gcc_cmake}
| | |
@@ -2,7 +2,7 @@ Installation in Linux {#tutorial_linux_install}
=====================
@prev_tutorial{tutorial_env_reference}
@next_tutorial{tutorial_linux_gdb_pretty_printer}
@next_tutorial{tutorial_oneapi_install}
| | |
| -: | :- |
@@ -0,0 +1,106 @@
Building OpenCV with oneAPI {#tutorial_oneapi_install}
===========================
@prev_tutorial{tutorial_linux_install}
@next_tutorial{tutorial_linux_gcc_cmake}
| | |
| -: | :- |
| Original author | Alessandro de Oliveira Faria |
| Compatibility | OpenCV >= 4.11.0 |
@tableofcontents
# Quick start {#tutorial_oneapi_install_quick_start}
**oneAPI** is Intel's open initiative (now also maintained by the UXL Foundation) that combines a specification and a set of toolkits for programming CPUs, GPUs, FPGAs and NPUs with a single code base. The core is the SYCL standard (single-source C++ for parallelism), complemented by high-performance libraries — oneTBB (parallelism), oneMKL (linear algebra), oneDNN (neural networks), oneVPL (video), etc. Thus, when you compile with oneAPI's DPC++ (icpx) compiler, the binary gains optimized execution paths that choose, at runtime, the best vector instructions or the available device, without changing the source code.
## Why compile OpenCV with the oneAPI ecosystem when targeting the CPU:
* Simple, because by enabling the CMake options -DWITH_SYCL=ON -DWITH_TBB=ON -DWITH_ONEDNN=ON -DWITH_IPP=ON and using the icpx compiler, the OpenCV core starts to directly invoke oneAPI libraries.
* oneDNN replaces the generic kernels of the cv::dnn layer with implementations that exploit AVX2, AVX-512, AMX and VNNI, accelerating convolutions, matmul and network post-processing by up to 3-5× on modern CPUs.
* oneTBB takes over the thread pool, scheduling filters like cv::resize, cv::GaussianBlur or the G-API pipeline across all cores without busy-wait.
* IPP (now distributed via oneAPI Base Toolkit) provides optimized intrinsic routines for elementary operations (SAD, DFT, median blur), which OpenCV calls when it encounters the HAVE_IPP macro.
* All this happens transparently: the source code that uses cv::Mat remains the same, but the linked symbols point to vectorized versions, and the internal dispatcher selects the appropriate vector width at runtime.
## CPU Processor Requirements
Systems based on Intel® 64 architectures below are supported both as host and target platforms.
* Intel® Core™ processor family or higher
* Intel® Xeon® processor family
* Intel® Xeon® Scalable processor family
### Requirements for Accelerators
* Integrated GEN9 (and higher) GPUs. See source in Intel® Graphics Compiler for OpenCL™
* FPGA Card: see Intel(R) DPC++ Compiler System Requirements.
### Disk Space Requirements
* 3.3 GB of disk space (minimum) on a standard installation.
@note: During the installation process, the installer may need up to 6 GB of additional temporary disk storage to manage the download and intermediate installation files.
### Memory Requirements
* 8 GB RAM recommended
## How To install oneAPI
Installing oneAPI: To quickly set up the oneAPI ecosystem on openSUSE, simply follow the official guide https://www.intel.com/content/www/us/en/developer/articles/guide/installation-guide-for-oneapi-toolkits.html, which shows you how to enable the distributions dedicated repository (zypper ar … oneAPI) and install the metapackages ― for example, intel-basekit (DPC++, TBB, oneDNN, IPP compilers) and, optionally, intel-hpckit or intel-renderkit if you need HPC or graphics tools. The guide also explains post-installation tweaks, such as loading the environment with source /opt/intel/oneapi/setvars.sh , ensuring that the binaries (icpx, dpcpp) and libraries are immediately available in your shell for compiling and running accelerated applications.
## Download, Github Instruction, Build and Install
1. Below are the commands to download last version (latest release on the date of publication of this text):
```
git clone https://github.com/opencv/opencv.git
```
2. and make sure you are using branch 4.*:
```
git status
On branch 4.x
```
3. Navigate to OpenCV repository and prepare the build folder:
```
cd opencv
mkdir build
cd build
```
4. Set up Intel oneAPI environment variables. For default installation:
```
source /opt/intel/oneapi/setvars.sh
```
5. Run CMake * with Intel® oneAPI DPC++/C++ Compiler to configure the project:
```
cmake -DCMAKE_C_COMPILER=icx \
-DCMAKE_CXX_COMPILER=icpx
-DCMAKE_CXX_FLAGS="-march=native -mavx -mfma -msse -msse2" ..
cmake --build .
```
6. Now Make sure openCV* is compiled with Intel® oneAPI DPC++/C++ Compiler and install:
```
readelf -p .comment bin/opencv_annotation
String dump of section '.comment':
[ 0] GCC: (SUSE Linux) 13.3.1 20250313 [revision 4ef1d8c84faeebffeb0cc01ee22e891b41e5c4e0]
[ 56] GCC: (SUSE Linux) 12.3.0
[ 6f] Intel(R) oneAPI DPC++/C++ Compiler 2025.1.1 (2025.1.1.20250418)
make install
```
Have fun...
@@ -9,6 +9,7 @@ Introduction to OpenCV {#tutorial_table_of_content_introduction}
##### Linux
- @subpage tutorial_linux_install
- @subpage tutorial_oneapi_install
- @subpage tutorial_linux_gdb_pretty_printer
- @subpage tutorial_linux_gcc_cmake
- @subpage tutorial_linux_eclipse
@@ -379,6 +379,9 @@ our OpenCV library that we use in our projects. Start up a command window and en
setx OpenCV_DIR D:\OpenCV\build\x64\vc17 (suggested for Visual Studio 2022 - 64 bit Windows)
setx OpenCV_DIR D:\OpenCV\build\x86\vc17 (suggested for Visual Studio 2022 - 32 bit Windows)
setx OpenCV_DIR D:\OpenCV\build\x64\vc18 (suggested for Visual Studio 2026 - 64 bit Windows)
setx OpenCV_DIR D:\OpenCV\build\x86\vc18 (suggested for Visual Studio 2026 - 32 bit Windows)
@endcode
Here the directory is where you have your OpenCV binaries (*extracted* or *built*). You can have
different platform (e.g. x64 instead of x86) or compiler type, so substitute appropriate value.
+6 -1
View File
@@ -21,7 +21,7 @@ add_library(ipphal STATIC
#TODO: HAVE_IPP_ICV and HAVE_IPP_IW added as private macro till OpenCV itself is
# source of IPP and public definitions lead to redefinition warning
# The macro should be redefined as PUBLIC when IPP part is removed from core
# to make HAL the source of IPP integration
# to make HAL the source of IPP integration. The same is true for WITH_IPP_CALLS_ENFORCED
if(HAVE_IPP_ICV)
target_compile_definitions(ipphal PRIVATE HAVE_IPP_ICV)
endif()
@@ -30,6 +30,11 @@ if(HAVE_IPP_IW)
target_compile_definitions(ipphal PRIVATE HAVE_IPP_IW)
endif()
if(WITH_IPP_CALLS_ENFORCED)
target_compile_definitions(ipphal PRIVATE IPP_CALLS_ENFORCED)
message("WITH_IPP_CALLS_ENFORCED=${WITH_IPP_CALLS_ENFORCED}: enforced IPP calls are enabled in IPP HAL")
endif()
target_include_directories(ipphal PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-suggest-override)
-124
View File
@@ -1,124 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
// (3-clause BSD License)
//
// Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the names of the copyright holders nor the names of the contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall copyright holders or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "perf_precomp.hpp"
#include <algorithm>
#include <functional>
namespace opencv_test
{
using namespace perf;
CV_ENUM(Method, RANSAC, LMEDS)
typedef tuple<int, double, Method, size_t> TranslationParams;
typedef TestBaseWithParam<TranslationParams> EstimateTranslation2DPerf;
#define ESTIMATE_PARAMS Combine(Values(1000), Values(0.95), Method::all(), Values(10, 0))
static float rngIn(float from, float to) { return from + (to - from) * (float)theRNG(); }
static cv::Mat rngTranslationMat()
{
double tx = rngIn(-2.f, 2.f);
double ty = rngIn(-2.f, 2.f);
double t[2*3] = { 1.0, 0.0, tx,
0.0, 1.0, ty };
return cv::Mat(2, 3, CV_64F, t).clone();
}
PERF_TEST_P(EstimateTranslation2DPerf, EstimateTranslation2D, ESTIMATE_PARAMS)
{
TranslationParams params = GetParam();
const int n = get<0>(params);
const double confidence = get<1>(params);
const int method = get<2>(params);
const size_t refining = get<3>(params);
//fixed seed so the generated data are deterministic
cv::theRNG().state = 0x12345678;
// ground-truth pure translation
cv::Mat T = rngTranslationMat();
// LMEDS can't handle more than 50% outliers (by design)
int m;
if (method == LMEDS)
m = 3*n/5;
else
m = 2*n/5;
const float shift_outl = 15.f;
const float noise_level = 20.f;
cv::Mat fpts(1, n, CV_32FC2);
cv::Mat tpts(1, n, CV_32FC2);
randu(fpts, 0.f, 100.f);
transform(fpts, tpts, T);
// add outliers to the tail [m, n)
cv::Mat outliers = tpts.colRange(m, n);
outliers.reshape(1) += shift_outl;
cv::Mat noise(outliers.size(), outliers.type());
randu(noise, 0.f, noise_level);
outliers += noise;
cv::Vec2d T_est;
std::vector<uchar> inliers(n);
warmup(inliers, WARMUP_WRITE);
warmup(fpts, WARMUP_READ);
warmup(tpts, WARMUP_READ);
TEST_CYCLE()
{
T_est = estimateTranslation2D(fpts, tpts, inliers, method,
/*ransacReprojThreshold=*/3.0,
/*maxIters=*/2000,
/*confidence=*/confidence,
/*refineIters=*/refining);
}
// Convert to Mat for SANITY_CHECK consistency
cv::Mat T_est_mat = (cv::Mat_<double>(2,1) << T_est[0], T_est[1]);
SANITY_CHECK(T_est_mat, 1e-6);
}
} // namespace opencv_test
+1 -1
View File
@@ -177,7 +177,7 @@ void p3p::calibrateAndNormalizePointsPnP(const Mat &opoints_, const Mat &ipoints
Mat ipoints;
convertPoints(ipoints_, ipoints, 2);
for (int i = 0; i < ipoints.rows; i++) {
for (int i = 0; i < 3; i++) {
const double k_inv_u = ipoints.at<double>(i, 0);
const double k_inv_v = ipoints.at<double>(i, 1);
double x_norm = 1.0 / sqrt(k_inv_u*k_inv_u + k_inv_v*k_inv_v + 1);
+2
View File
@@ -1241,6 +1241,8 @@ Vec2d estimateTranslation2D(InputArray _from, InputArray _to,
size_t maxIters, double confidence,
size_t refineIters)
{
CV_INSTRUMENT_REGION();
using std::numeric_limits;
const double NaN = numeric_limits<double>::quiet_NaN();
Vec2d tvec(NaN, NaN);
+76 -3
View File
@@ -1059,7 +1059,8 @@ More information about Perspective-n-Points is described in @ref calib3d_solvePn
of the P3P problem, the last one is used to retain the best solution that minimizes the reprojection error).
- With @ref SOLVEPNP_ITERATIVE method and `useExtrinsicGuess=true`, the minimum number of points is 3 (3 points
are sufficient to compute a pose but there are up to 4 solutions). The initial solution should be close to the
global solution to converge.
global solution to converge. The function returns true if some solution is found. User code is responsible for
solution quality assessment.
- With @ref SOLVEPNP_IPPE input points must be >= 4 and object points must be coplanar.
- With @ref SOLVEPNP_IPPE_SQUARE this is a special case suitable for marker pose estimation.
Number of input points must be 4. Object points must be defined in the following order:
@@ -3362,6 +3363,78 @@ CV_EXPORTS_W cv::Mat estimateAffinePartial2D(InputArray from, InputArray to, Out
size_t maxIters = 2000, double confidence = 0.99,
size_t refineIters = 10);
/** @brief Computes a pure 2D translation between two 2D point sets.
It computes
\f[
\begin{bmatrix}
x\\
y
\end{bmatrix}
=
\begin{bmatrix}
1 & 0\\
0 & 1
\end{bmatrix}
\begin{bmatrix}
X\\
Y
\end{bmatrix}
+
\begin{bmatrix}
t_x\\
t_y
\end{bmatrix}.
\f]
@param from First input 2D point set containing \f$(X,Y)\f$.
@param to Second input 2D point set containing \f$(x,y)\f$.
@param inliers Output vector indicating which points are inliers (1-inlier, 0-outlier).
@param method Robust method used to compute the transformation. The following methods are possible:
- @ref RANSAC - RANSAC-based robust method
- @ref LMEDS - Least-Median robust method
RANSAC is the default method.
@param ransacReprojThreshold Maximum reprojection error in the RANSAC algorithm to consider
a point as an inlier. Applies only to RANSAC.
@param maxIters The maximum number of robust method iterations.
@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything
between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation
significantly. Values lower than 0.80.9 can result in an incorrectly estimated transformation.
@param refineIters Maximum number of iterations of the refining algorithm. For pure translation
the least-squares solution on inliers is closed-form, so passing 0 is recommended (no additional refine).
@return A 2D translation vector \f$[t_x, t_y]^T\f$ as `cv::Vec2d`. If the translation could not be
estimated, both components are set to NaN and, if @p inliers is provided, the mask is filled with zeros.
\par Converting to a 2x3 transformation matrix:
\f[
\begin{bmatrix}
1 & 0 & t_x\\
0 & 1 & t_y
\end{bmatrix}
\f]
@code{.cpp}
cv::Vec2d t = cv::estimateTranslation2D(from, to, inliers);
cv::Mat T = (cv::Mat_<double>(2,3) << 1,0,t[0], 0,1,t[1]);
@endcode
The function estimates a pure 2D translation between two 2D point sets using the selected robust
algorithm. Inliers are determined by the reprojection error threshold.
@note
The RANSAC method can handle practically any ratio of outliers but needs a threshold to
distinguish inliers from outliers. The method LMeDS does not need any threshold but works
correctly only when there are more than 50% inliers.
@sa estimateAffine2D, estimateAffinePartial2D, getAffineTransform
*/
CV_EXPORTS_W cv::Vec2d estimateTranslation2D(InputArray from, InputArray to, OutputArray inliers = noArray(),
int method = RANSAC,
double ransacReprojThreshold = 3,
size_t maxIters = 2000, double confidence = 0.99,
size_t refineIters = 0);
/** @example samples/cpp/tutorial_code/features2D/Homography/decompose_homography.cpp
An example program with homography decomposition.
@@ -4259,7 +4332,7 @@ optimization. It is the \f$max(width,height)/\pi\f$ or the provided \f$f_x\f$, \
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
/**
@brief Finds an object pose from 3D-2D point correspondences for fisheye camera moodel.
@brief Finds an object pose from 3D-2D point correspondences for fisheye camera model.
@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or
1xN/Nx1 3-channel, where N is the number of points. vector\<Point3d\> can also be passed here.
@@ -4275,7 +4348,7 @@ optimization. It is the \f$max(width,height)/\pi\f$ or the provided \f$f_x\f$, \
vectors, respectively, and further optimizes them.
@param flags Method for solving a PnP problem: see @ref calib3d_solvePnP_flags
@param criteria Termination criteria for internal undistortPoints call.
The function interally undistorts points with @ref undistortPoints and call @ref cv::solvePnP,
The function internally undistorts points with @ref undistortPoints and call @ref cv::solvePnP,
thus the input are very similar. More information about Perspective-n-Points is described in @ref calib3d_solvePnP
for more information.
*/
+29
View File
@@ -1406,8 +1406,13 @@ public:
When the operation mask is specified, if the Mat::create call shown above reallocates the matrix,
the newly allocated matrix is initialized with all zeros before copying the data.
If (re)allocation of destination memory is not necessary (e.g. updating ROI), use copyAt() .
@param m Destination matrix. If it does not have a proper size or type before the operation, it is
reallocated.
@sa copyAt
*/
void copyTo( OutputArray m ) const;
@@ -1420,6 +1425,30 @@ public:
*/
void copyTo( OutputArray m, InputArray mask ) const;
/** @brief Overwrites the existing matrix
This method writes existing matrix data, just like copyTo().
But if it does not have a proper size or type before the operation, an exception is thrown.
This function is helpful to update ROI in an existing matrix.
If (re)allocation of destination memory is necessary, use copyTo() .
@param m Destination matrix.
If it does not have a proper size or type before the operation, an exception is thrown.
@sa copyTo
*/
void copyAt( OutputArray m ) const;
/** @overload
@param m Destination matrix.
If it does not have a proper size or type before the operation, an exception is thrown.
@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix
elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels.
*/
void copyAt( OutputArray m, InputArray mask ) const;
/** @brief Converts an array to another data type with optional scaling.
The method converts source pixel values to the target data type. saturate_cast\<\> is applied at
@@ -257,8 +257,27 @@ VSX_IMPL_1VRG(vec_udword2, vec_udword2, vpopcntd, vec_popcntu)
VSX_IMPL_1VRG(vec_udword2, vec_dword2, vpopcntd, vec_popcntu)
// converts between single and double-precision
VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, vec_floate)
VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, vec_doubleo)
// vec_floate and vec_doubleo are available since Power10 and z14
#if defined(__POWER10__) || (defined(__powerpc64__) && defined(__ARCH_PWR10__)
// Use VSX double<->float conversion instructions (if supported by the architecture)
VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, vec_floate)
VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, vec_doubleo)
#else
// Fallback: implement vec_cvfo using scalar operations (to ensure successful linking)
static inline vec_float4 vec_cvfo(const vec_double2& a)
{
float r0 = static_cast<float>(reinterpret_cast<const double*>(&a)[0]);
float r1 = static_cast<float>(reinterpret_cast<const double*>(&a)[1]);
return (vec_float4){r0, 0.f, r1, 0.f};
}
static inline vec_double2 vec_cvfo(const vec_float4& a)
{
double r0 = static_cast<double>(reinterpret_cast<const float*>(&a)[0]);
double r1 = static_cast<double>(reinterpret_cast<const float*>(&a)[2]);
return (vec_double2){r0, r1};
}
#endif
// converts word and doubleword to double-precision
#undef vec_ctd
+12
View File
@@ -1165,6 +1165,10 @@ void cv::add( InputArray src1, InputArray src2, OutputArray dst,
if (src1.empty() && src2.empty())
{
dst.release();
if (dtype >= 0)
{
dst.create(0, 0, dtype);
}
return;
}
@@ -1192,6 +1196,10 @@ void cv::subtract( InputArray _src1, InputArray _src2, OutputArray _dst,
if (_src1.empty() && _src2.empty())
{
_dst.release();
if (dtype >= 0)
{
_dst.create(0, 0, dtype);
}
return;
}
@@ -1409,6 +1417,10 @@ void cv::addWeighted( InputArray src1, double alpha, InputArray src2,
if (src1.empty() && src2.empty())
{
dst.release();
if (dtype >= 0)
{
dst.create(0, 0, dtype);
}
return;
}
+2
View File
@@ -135,6 +135,7 @@ void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const
if (empty())
{
dst.release();
dst.create(size(), type_ >= 0 ? type_ : type());
return;
}
@@ -204,6 +205,7 @@ void UMat::convertTo(OutputArray dst, int type_, double alpha, double beta) cons
if (empty())
{
dst.release();
dst.create(size(), type_ >= 0 ? type_ : type());
return;
}
+22
View File
@@ -642,6 +642,28 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
}
/* dst = src */
void Mat::copyAt( OutputArray _dst ) const
{
CV_INSTRUMENT_REGION();
Mat dst = _dst.getMat();
CV_CheckTrue( !dst.empty(), "dst must not be empty" );
CV_CheckTypeEQ(type(), dst.type(), "Make the type of dst the same as src");
CV_CheckEQ(size(), dst.size(), "Make the size of dst the same as src");
copyTo(_dst);
}
void Mat::copyAt( OutputArray _dst, InputArray _mask ) const
{
CV_INSTRUMENT_REGION();
Mat dst = _dst.getMat();
CV_CheckTrue( !dst.empty(), "dst must not be empty" );
CV_CheckTypeEQ(type(), dst.type(), "Make the type of dst the same as src");
CV_CheckEQ(size(), dst.size(), "Make the size of dst the same as src");
copyTo(_dst, _mask);
}
static bool can_apply_memset(const Mat &mat, const Scalar &s, int &fill_value)
{
+4 -4
View File
@@ -1216,6 +1216,10 @@ void UMat::copyTo(OutputArray _dst) const
return;
}
_dst.create( dims, size.p, stype );
if (empty())
return;
size_t sz[CV_MAX_DIM] = {1}, srcofs[CV_MAX_DIM]={0}, dstofs[CV_MAX_DIM]={0};
size_t esz = CV_ELEM_SIZE(stype);
int i, d = std::max(dims, 1);
@@ -1225,10 +1229,6 @@ void UMat::copyTo(OutputArray _dst) const
ndoffset(srcofs);
srcofs[d-1] *= esz;
_dst.create( dims, size.p, stype );
if (empty())
return;
if( _dst.isUMat() )
{
UMat dst = _dst.getUMat();
+74
View File
@@ -1290,6 +1290,15 @@ TEST(Core_Mat, push_back)
}
}
TEST(Core_Mat, copyToConvertTo_Empty)
{
cv::Mat A(0, 0, CV_16SC2), B, C;
A.copyTo(B);
ASSERT_EQ(A.type(), B.type());
A.convertTo(C, CV_32SC2);
ASSERT_EQ(C.type(), CV_32SC2);
}
TEST(Core_Mat, copyNx1ToVector)
{
cv::Mat_<uchar> src(5, 1);
@@ -2857,4 +2866,69 @@ TEST(UMat, reshape_empty)
EXPECT_EQ(m4d.total(), (size_t)0);
}
// see https://github.com/opencv/opencv/issues/27298
TEST(Mat, copyAt_regression27298)
{
cv::Mat src(40/*height*/, 30/*width*/, CV_8UC1, Scalar(255));
// Normal
{
cv::Mat dst(100, 100, CV_8UC1, Scalar(0));
cv::Mat roi(dst, cv::Rect(0, 0, 30/*width*/, 40/*height*/));
void* roiData = roi.data;
EXPECT_NO_THROW(src.copyTo(roi));
EXPECT_EQ(roi.data, roiData);
EXPECT_EQ(countNonZero(roi), roi.size().width * roi.size().height) << roi;
}
{
cv::Mat dst(100, 100, CV_8UC1, Scalar(0));
cv::Mat roi(dst, cv::Rect(0, 0, 30/*width*/, 40/*height*/));
void* roiData = roi.data;
EXPECT_NO_THROW(src.copyAt(roi));
EXPECT_EQ(roi.data, roiData);
EXPECT_EQ(countNonZero(roi), roi.size().width * roi.size().height) << roi;
}
// Empty
{
cv::Mat roi; // empty
EXPECT_NO_THROW(src.copyTo(roi));
EXPECT_NE(roi.data, nullptr); // Allocated
EXPECT_EQ(countNonZero(roi), roi.size().width * roi.size().height) << roi;
}
{
cv::Mat roi; // empty
EXPECT_ANY_THROW(src.copyAt(roi));
}
// Different Type
{
cv::Mat dst(100, 100, CV_16UC1, Scalar(0));
cv::Mat roi(dst, cv::Rect(0, 0, 30/*width*/, 40/*height*/));
void* roiData = roi.data;
EXPECT_NO_THROW(src.copyTo(roi));
EXPECT_NE(roi.data, roiData); // Reallocated
EXPECT_EQ(countNonZero(roi), roi.size().width * roi.size().height) << roi;
}
{
cv::Mat dst(100, 100, CV_16UC1, Scalar(0));
cv::Mat roi(dst, cv::Rect(0, 0, 30/*width*/, 40/*height*/));
EXPECT_ANY_THROW(src.copyAt(roi));
}
// Different Size
{
cv::Mat dst(100, 100, CV_8UC1, Scalar(0));
cv::Mat roi(dst, cv::Rect(0, 0, 40/*width*/, 30/*height*/));
void* roiData = roi.data;
EXPECT_NO_THROW(src.copyTo(roi));
EXPECT_NE(roi.data, roiData); // Reallocated
EXPECT_EQ(countNonZero(roi), roi.size().width * roi.size().height) << roi;
}
{
cv::Mat dst(100, 100, CV_8UC1, Scalar(0));
cv::Mat roi(dst, cv::Rect(0, 0, 40/*width*/, 30/*height*/));
EXPECT_ANY_THROW(src.copyAt(roi));
}
}
}} // namespace
+8
View File
@@ -1177,6 +1177,14 @@ TEST(UMat, async_cleanup_without_call_chain_warning)
}
}
TEST(UMat, copyToConvertTo_Empty)
{
cv::UMat A(0, 0, CV_16SC2), B, C;
A.copyTo(B);
ASSERT_EQ(A.type(), B.type());
A.convertTo(C, CV_32SC2);
ASSERT_EQ(C.type(), CV_32SC2);
}
///////////// oclCleanupCallback threadsafe check (#5062) /////////////////////
+24 -3
View File
@@ -47,6 +47,7 @@
#include <fstream>
#include <sstream>
#include <algorithm>
#include <type_traits>
#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -57,7 +58,6 @@
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/fp_control_utils.hpp>
namespace cv {
namespace dnn {
CV__DNN_INLINE_NS_BEGIN
@@ -206,7 +206,9 @@ public:
return (str.size() >= _param.size()) && str.compare(str.size() - _param.size(), _param.size(), _param) == 0;
}
void extractLayerParams(const Message &msg, cv::dnn::LayerParams &params, bool isInternal = false)
template<class MSG>
typename std::enable_if<std::is_base_of<Message, MSG>::value, void>::type
extractLayerParams(const MSG &msg, cv::dnn::LayerParams &params, bool isInternal = false)
{
const Descriptor *msgDesc = msg.GetDescriptor();
const Reflection *msgRefl = msg.GetReflection();
@@ -241,6 +243,13 @@ public:
}
}
template<class MSG>
typename std::enable_if<!std::is_base_of<Message, MSG>::value, void>::type
extractLayerParams(const MSG &msg, cv::dnn::LayerParams &params, bool isInternal = false)
{
CV_Error(Error::StsError, "DNN/CAFFE: do not have your message be a MessageLite");
}
void blobShapeFromProto(const caffe::BlobProto &pbBlob, MatShape& shape)
{
shape.clear();
@@ -259,6 +268,18 @@ public:
shape.resize(1, 1); // Is a scalar.
}
template<class BLOB_PROTO>
typename std::enable_if<std::is_base_of<Message, BLOB_PROTO>::value, void>::type
AssertBlobProtoIsFloat(const BLOB_PROTO &pbBlob) {
CV_DbgAssert(pbBlob.GetDescriptor()->FindFieldByLowercaseName("data")->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT);
}
template<class BLOB_PROTO>
typename std::enable_if<!std::is_base_of<Message, BLOB_PROTO>::value, void>::type
AssertBlobProtoIsFloat(const BLOB_PROTO &pbBlob) {
CV_Error(Error::StsError, "DNN/CAFFE: do not have your message be a MessageLite");
}
void blobFromProto(const caffe::BlobProto &pbBlob, cv::Mat &dstBlob)
{
MatShape shape;
@@ -270,7 +291,7 @@ public:
// Single precision floats.
CV_Assert(pbBlob.data_size() == (int)dstBlob.total());
CV_DbgAssert(pbBlob.GetDescriptor()->FindFieldByLowercaseName("data")->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT);
AssertBlobProtoIsFloat(pbBlob);
Mat(dstBlob.size, CV_32F, (void*)pbBlob.data().data()).copyTo(dstBlob);
}
else
+39 -7
View File
@@ -101,6 +101,7 @@
#include <string>
#include <fstream>
#include <vector>
#include <type_traits>
#include "caffe_io.hpp"
#include "glog_emulator.hpp"
@@ -1110,7 +1111,7 @@ const char* UpgradeV1LayerType(const V1LayerParameter_LayerType type) {
static const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.
bool ReadProtoFromBinary(ZeroCopyInputStream* input, Message *proto) {
bool ReadProtoFromBinary(ZeroCopyInputStream* input, MessageLite *proto) {
CodedInputStream coded_input(input);
#if GOOGLE_PROTOBUF_VERSION >= 3006000
coded_input.SetTotalBytesLimit(kProtoReadBytesLimit);
@@ -1133,7 +1134,12 @@ bool ReadProtoFromTextFile(const char* filename, Message* proto) {
return parser.Parse(&input, proto);
}
bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {
bool ReadProtoFromTextFile(const char* filename, MessageLite* proto) {
CV_Error(Error::StsError, "DNN/CAFFE: do not have your message be a MessageLite");
return false;
}
bool ReadProtoFromBinaryFile(const char* filename, MessageLite* proto) {
std::ifstream fs(filename, std::ifstream::in | std::ifstream::binary);
CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";
IstreamInputStream raw_input(&fs);
@@ -1151,26 +1157,52 @@ bool ReadProtoFromTextBuffer(const char* data, size_t len, Message* proto) {
return parser.Parse(&input, proto);
}
bool ReadProtoFromTextBuffer(const char* data, size_t len, MessageLite* proto) {
CV_Error(Error::StsError, "DNN/CAFFE: do not have your message be a MessageLite");
return false;
}
bool ReadProtoFromBinaryBuffer(const char* data, size_t len, Message* proto) {
bool ReadProtoFromBinaryBuffer(const char* data, size_t len, MessageLite* proto) {
ArrayInputStream raw_input(data, len);
return ReadProtoFromBinary(&raw_input, proto);
}
void ReadNetParamsFromTextFileOrDie(const char* param_file,
NetParameter* param) {
template<class MESSAGE>
typename std::enable_if<std::is_base_of<Message, MESSAGE>::value, void>::type
ReadNetParamsFromTextFileOrDieImpl(const char* param_file, MESSAGE* param) {
CHECK(ReadProtoFromTextFile(param_file, param))
<< "Failed to parse NetParameter file: " << param_file;
UpgradeNetAsNeeded(param_file, param);
}
void ReadNetParamsFromTextBufferOrDie(const char* data, size_t len,
NetParameter* param) {
template<class MESSAGE>
typename std::enable_if<!std::is_base_of<Message, MESSAGE>::value, void>::type
ReadNetParamsFromTextFileOrDieImpl(const char* param_file, MESSAGE* param) {
CV_Error(Error::StsError, "DNN/CAFFE: do not have your message be a MessageLite");
}
void ReadNetParamsFromTextFileOrDie(const char* param_file, NetParameter* param) {
ReadNetParamsFromTextFileOrDieImpl(param_file, param);
}
template<class MESSAGE>
typename std::enable_if<std::is_base_of<Message, MESSAGE>::value, void>::type
ReadNetParamsFromTextBufferOrDieImpl(const char* data, size_t len, MESSAGE* param) {
CHECK(ReadProtoFromTextBuffer(data, len, param))
<< "Failed to parse NetParameter buffer";
UpgradeNetAsNeeded("memory buffer", param);
}
template<class MESSAGE>
typename std::enable_if<!std::is_base_of<Message, MESSAGE>::value, void>::type
ReadNetParamsFromTextBufferOrDieImpl(const char* data, size_t len, MESSAGE* param) {
CV_Error(Error::StsError, "DNN/CAFFE: do not have your message be a MessageLite");
}
void ReadNetParamsFromTextBufferOrDie(const char* data, size_t len, NetParameter* param) {
ReadNetParamsFromTextBufferOrDieImpl(data, len, param);
}
void ReadNetParamsFromBinaryFileOrDie(const char* param_file,
NetParameter* param) {
CHECK(ReadProtoFromBinaryFile(param_file, param))
+4 -2
View File
@@ -119,9 +119,11 @@ void ReadNetParamsFromTextBufferOrDie(const char* data, size_t len,
// Utility functions used internally by Caffe and TensorFlow loaders
bool ReadProtoFromTextFile(const char* filename, ::google::protobuf::Message* proto);
bool ReadProtoFromBinaryFile(const char* filename, ::google::protobuf::Message* proto);
bool ReadProtoFromTextFile(const char* filename, ::google::protobuf::MessageLite* proto);
bool ReadProtoFromBinaryFile(const char* filename, ::google::protobuf::MessageLite* proto);
bool ReadProtoFromTextBuffer(const char* data, size_t len, ::google::protobuf::Message* proto);
bool ReadProtoFromBinaryBuffer(const char* data, size_t len, ::google::protobuf::Message* proto);
bool ReadProtoFromTextBuffer(const char* data, size_t len, ::google::protobuf::MessageLite* proto);
bool ReadProtoFromBinaryBuffer(const char* data, size_t len, ::google::protobuf::MessageLite* proto);
}
}
+8 -3
View File
@@ -207,6 +207,7 @@ public:
Ptr<ActivationLayer> activ;
Ptr<FastConv> fastConvImpl;
bool canUseWinograd = false;
#ifdef HAVE_OPENCL
Ptr<OCL4DNNConvSpatial<float> > convolutionOp;
@@ -400,6 +401,13 @@ public:
#ifdef HAVE_OPENCL
convolutionOp.release();
#endif
// Winograd only works when input h and w >= 12.
canUseWinograd = useWinograd && inputs[0].dims == 4 && inputs[0].size[2] >= 12 && inputs[0].size[3] >= 12;
if (fastConvImpl && (fastConvImpl->conv_type == CONV_TYPE_WINOGRAD3X3) ^ canUseWinograd)
{
fastConvImpl.reset();
}
}
bool setActivation(const Ptr<ActivationLayer>& layer) CV_OVERRIDE
@@ -1195,9 +1203,6 @@ public:
int K = outputs[0].size[1];
int C = inputs[0].size[1];
// Winograd only works when input h and w >= 12.
bool canUseWinograd = useWinograd && conv_dim == CONV_2D && inputs[0].size[2] >= 12 && inputs[0].size[3] >= 12;
CV_Assert(outputs[0].size[1] % ngroups == 0);
fastConvImpl = initFastConv(weightsMat, &biasvec[0], ngroups, K, C, kernel_size, strides,
dilations, pads_begin, pads_end, conv_dim,
+15 -1
View File
@@ -31,6 +31,7 @@ Implementation of Tensorflow models parser
#include <set>
#include <string>
#include <queue>
#include <type_traits>
#include "tf_graph_simplifier.hpp"
#endif
@@ -3326,6 +3327,19 @@ Net readNetFromTensorflow(const std::vector<uchar>& bufferModel, const std::vect
engine, extraOutputs);
}
template<class GRAPH_DEF>
typename std::enable_if<std::is_base_of<Message, GRAPH_DEF>::value, void>::type
PrintToStringImpl(const GRAPH_DEF& net, std::string* content) {
google::protobuf::TextFormat::PrintToString(net, content);
}
template<class GRAPH_DEF>
typename std::enable_if<!std::is_base_of<Message, GRAPH_DEF>::value, void>::type
PrintToStringImpl(const GRAPH_DEF& net, std::string* content) {
CV_Error(Error::StsError, "DNN/TF: do not have your message be a MessageLite");
}
void writeTextGraph(const String& _model, const String& output)
{
String model = _model;
@@ -3348,7 +3362,7 @@ void writeTextGraph(const String& _model, const String& output)
}
std::string content;
google::protobuf::TextFormat::PrintToString(net, &content);
PrintToStringImpl(net, &content);
std::ofstream ofs(output.c_str());
ofs << content;
+43
View File
@@ -2906,4 +2906,47 @@ TEST(Layer_Size, onnx_0d_scalar)
EXPECT_EQ(outs[0].at<int64_t>(0), 1);
}
TEST(ConvolutionWinograd, Accuracy)
{
Mat weights({2, 1, 3, 3}, CV_32F);
randn(weights, 0, 1);
// Check convolution can switch between implementations on changed shape.
auto getNet = [&]() {
Net net;
LayerParams lp;
lp.name = "conv";
lp.type = "Convolution";
lp.set("kernel_size", 3);
lp.set("num_output", 2);
lp.set("pad", 0);
lp.set("stride", 1);
lp.set("bias_term", false);
lp.blobs.push_back(weights);
net.addLayerToPrev(lp.name, lp.type, lp);
return net;
};
Mat inpSmall({1, 1, 5, 5}, CV_32F);
Mat inpLarge({1, 1, 64, 64}, CV_32F);
randn(inpSmall, 0, 1);
randn(inpLarge, 0, 1);
Net net1 = getNet();
Net net2 = getNet();
net1.setInput(inpSmall);
net2.setInput(inpLarge);
Mat refSmall = net1.forward();
Mat refLarge = net2.forward();
net1.setInput(inpLarge);
net2.setInput(inpSmall);
Mat outLarge = net1.forward();
Mat outSmall = net2.forward();
normAssert(outSmall, refSmall, "Small input after large", 0.0, 0.0);
normAssert(outLarge, refLarge, "Large input after small", 0.0, 0.0);
}
}} // namespace
+1 -1
View File
@@ -153,7 +153,7 @@ void RBaseStream::setPos( int64_t pos )
int64_t RBaseStream::getPos()
{
CV_Assert(isOpened());
int64_t pos = validateToInt64((m_current - m_start) + m_block_pos);
int64_t pos = static_cast<int64_t>((m_current - m_start) + m_block_pos);
CV_Assert(pos >= m_block_pos); // overflow check
CV_Assert(pos >= 0); // overflow check
return pos;
+1
View File
@@ -79,6 +79,7 @@ Mat BaseImageDecoder::getMetadata(ImageMetadataType type) const
case IMAGE_METADATA_XMP:
case IMAGE_METADATA_ICCP:
case IMAGE_METADATA_CICP:
return makeMat(m_metadata[type]);
default:
+1 -1
View File
@@ -212,7 +212,7 @@ bool GifDecoder::readData(Mat &img) {
if(!restore.empty())
{
Mat roi = Mat(lastImage, cv::Rect(left,top,width,height));
restore.copyTo(roi);
restore.copyAt(roi);
}
return hasRead;
+2 -2
View File
@@ -715,7 +715,7 @@ void PngDecoder::compose_frame(std::vector<png_bytep>& rows_dst, const std::vect
// Blending mode
for (unsigned int i = 0; i < w; i++, sp += channels, dp += channels) {
uint16_t alpha = sp[3];
uint16_t alpha = channels < 4 ? 0 : sp[3];
if (channels < 4 || alpha == 65535 || dp[3] == 0) {
// Fully opaque OR destination fully transparent: direct copy
@@ -745,7 +745,7 @@ void PngDecoder::compose_frame(std::vector<png_bytep>& rows_dst, const std::vect
// Blending mode
for (unsigned int i = 0; i < w; i++, sp += channels, dp += channels) {
uint8_t alpha = sp[3];
uint8_t alpha = channels < 4 ? 0 : sp[3];
if (channels < 4 || alpha == 255 || dp[3] == 0) {
// Fully opaque OR destination fully transparent: direct copy
+2 -1
View File
@@ -476,7 +476,8 @@ static const char* metadataTypeToString(ImageMetadataType type)
{
return type == IMAGE_METADATA_EXIF ? "Exif" :
type == IMAGE_METADATA_XMP ? "XMP" :
type == IMAGE_METADATA_ICCP ? "ICC Profile" : "???";
type == IMAGE_METADATA_ICCP ? "ICC Profile" :
type == IMAGE_METADATA_CICP ? "cICP" : "???";
}
static void addMetadata(ImageEncoder& encoder,
-7
View File
@@ -51,13 +51,6 @@ int validateToInt(size_t sz)
return valueInt;
}
int64_t validateToInt64(ptrdiff_t sz)
{
int64_t valueInt = static_cast<int64_t>(sz);
CV_Assert((ptrdiff_t)valueInt == sz);
return valueInt;
}
#define SCALE 14
#define cR (int)(0.299*(1 << SCALE) + 0.5)
#define cG (int)(0.587*(1 << SCALE) + 0.5)
-1
View File
@@ -45,7 +45,6 @@
namespace cv {
int validateToInt(size_t step);
int64_t validateToInt64(ptrdiff_t step);
template <typename _Tp> static inline
size_t safeCastToSizeT(const _Tp v_origin, const char* msg)
@@ -1065,6 +1065,18 @@ public:
//!@brief Returns Size defines the number of tiles in row and column.
CV_WRAP virtual Size getTilesGridSize() const = 0;
/** @brief Sets bit shift parameter for histogram bins.
@param bitShift bit shift value (default is 0).
*/
CV_WRAP virtual void setBitShift(int bitShift) = 0;
/** @brief Returns the bit shift parameter for histogram bins.
@return current bit shift value.
*/
CV_WRAP virtual int getBitShift() const = 0;
CV_WRAP virtual void collectGarbage() = 0;
};
+57 -32
View File
@@ -118,12 +118,12 @@ namespace clahe
namespace
{
template <class T, int histSize, int shift>
template <class T>
class CLAHE_CalcLut_Body : public cv::ParallelLoopBody
{
public:
CLAHE_CalcLut_Body(const cv::Mat& src, const cv::Mat& lut, const cv::Size& tileSize, const int& tilesX, const int& clipLimit, const float& lutScale) :
src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), clipLimit_(clipLimit), lutScale_(lutScale)
CLAHE_CalcLut_Body(const cv::Mat& src, const cv::Mat& lut, const cv::Size& tileSize, const int& tilesX, const int& clipLimit, const float& lutScale, const int& histSize, const int& shift) :
src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), clipLimit_(clipLimit), lutScale_(lutScale), histSize_(histSize), shift_(shift)
{
}
@@ -137,10 +137,12 @@ namespace
int tilesX_;
int clipLimit_;
float lutScale_;
int histSize_;
int shift_;
};
template <class T, int histSize, int shift>
void CLAHE_CalcLut_Body<T,histSize,shift>::operator ()(const cv::Range& range) const
template <class T>
void CLAHE_CalcLut_Body<T>::operator ()(const cv::Range& range) const
{
T* tileLut = lut_.ptr<T>(range.start);
const size_t lut_step = lut_.step / sizeof(T);
@@ -162,9 +164,9 @@ namespace
// calc histogram
cv::AutoBuffer<int> _tileHist(histSize);
cv::AutoBuffer<int> _tileHist(histSize_);
int* tileHist = _tileHist.data();
std::fill(tileHist, tileHist + histSize, 0);
std::fill(tileHist, tileHist + histSize_, 0);
int height = tileROI.height;
const size_t sstep = src_.step / sizeof(T);
@@ -174,13 +176,13 @@ namespace
for (; x <= tileROI.width - 4; x += 4)
{
int t0 = ptr[x], t1 = ptr[x+1];
tileHist[t0 >> shift]++; tileHist[t1 >> shift]++;
tileHist[t0 >> shift_]++; tileHist[t1 >> shift_]++;
t0 = ptr[x+2]; t1 = ptr[x+3];
tileHist[t0 >> shift]++; tileHist[t1 >> shift]++;
tileHist[t0 >> shift_]++; tileHist[t1 >> shift_]++;
}
for (; x < tileROI.width; ++x)
tileHist[ptr[x] >> shift]++;
tileHist[ptr[x] >> shift_]++;
}
// clip histogram
@@ -189,7 +191,7 @@ namespace
{
// how many pixels were clipped
int clipped = 0;
for (int i = 0; i < histSize; ++i)
for (int i = 0; i < histSize_; ++i)
{
if (tileHist[i] > clipLimit_)
{
@@ -199,16 +201,16 @@ namespace
}
// redistribute clipped pixels
int redistBatch = clipped / histSize;
int residual = clipped - redistBatch * histSize;
int redistBatch = clipped / histSize_;
int residual = clipped - redistBatch * histSize_;
for (int i = 0; i < histSize; ++i)
for (int i = 0; i < histSize_; ++i)
tileHist[i] += redistBatch;
if (residual != 0)
{
int residualStep = MAX(histSize / residual, 1);
for (int i = 0; i < histSize && residual > 0; i += residualStep, residual--)
int residualStep = MAX(histSize_ / residual, 1);
for (int i = 0; i < histSize_ && residual > 0; i += residualStep, residual--)
tileHist[i]++;
}
}
@@ -216,7 +218,7 @@ namespace
// calc Lut
int sum = 0;
for (int i = 0; i < histSize; ++i)
for (int i = 0; i < histSize_; ++i)
{
sum += tileHist[i];
tileLut[i] = cv::saturate_cast<T>(sum * lutScale_);
@@ -224,12 +226,12 @@ namespace
}
}
template <class T, int shift>
template <class T>
class CLAHE_Interpolation_Body : public cv::ParallelLoopBody
{
public:
CLAHE_Interpolation_Body(const cv::Mat& src, const cv::Mat& dst, const cv::Mat& lut, const cv::Size& tileSize, const int& tilesX, const int& tilesY) :
src_(src), dst_(dst), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY)
CLAHE_Interpolation_Body(const cv::Mat& src, const cv::Mat& dst, const cv::Mat& lut, const cv::Size& tileSize, const int& tilesX, const int& tilesY, const int& shift) :
src_(src), dst_(dst), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY), shift_(shift)
{
buf.allocate(src.cols << 2);
ind1_p = buf.data();
@@ -268,14 +270,15 @@ namespace
cv::Size tileSize_;
int tilesX_;
int tilesY_;
int shift_;
cv::AutoBuffer<int> buf;
int * ind1_p, * ind2_p;
float * xa_p, * xa1_p;
};
template <class T, int shift>
void CLAHE_Interpolation_Body<T, shift>::operator ()(const cv::Range& range) const
template <class T>
void CLAHE_Interpolation_Body<T>::operator ()(const cv::Range& range) const
{
float inv_th = 1.0f / tileSize_.height;
@@ -299,7 +302,7 @@ namespace
for (int x = 0; x < src_.cols; ++x)
{
int srcVal = srcRow[x] >> shift;
int srcVal = srcRow[x] >> shift_;
int ind1 = ind1_p[x] + srcVal;
int ind2 = ind2_p[x] + srcVal;
@@ -307,7 +310,7 @@ namespace
float res = (lutPlane1[ind1] * xa1_p[x] + lutPlane1[ind2] * xa_p[x]) * ya1 +
(lutPlane2[ind1] * xa1_p[x] + lutPlane2[ind2] * xa_p[x]) * ya;
dstRow[x] = cv::saturate_cast<T>(res) << shift;
dstRow[x] = cv::saturate_cast<T>(res) << shift_;
}
}
}
@@ -315,7 +318,7 @@ namespace
class CLAHE_Impl CV_FINAL : public cv::CLAHE
{
public:
CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8);
CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8, int bitShift = 0);
void apply(cv::InputArray src, cv::OutputArray dst) CV_OVERRIDE;
@@ -325,12 +328,16 @@ namespace
void setTilesGridSize(cv::Size tileGridSize) CV_OVERRIDE;
cv::Size getTilesGridSize() const CV_OVERRIDE;
void setBitShift(int bitShift) CV_OVERRIDE;
int getBitShift() const CV_OVERRIDE;
void collectGarbage() CV_OVERRIDE;
private:
double clipLimit_;
int tilesX_;
int tilesY_;
int bitShift_;
cv::Mat srcExt_;
cv::Mat lut_;
@@ -341,8 +348,8 @@ namespace
#endif
};
CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) :
clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY)
CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY, int bitShift) :
clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY), bitShift_(bitShift)
{
}
@@ -356,7 +363,7 @@ namespace
bool useOpenCL = cv::ocl::isOpenCLActivated() && _src.isUMat() && _src.dims()<=2 && _src.type() == CV_8UC1;
#endif
int histSize = _src.type() == CV_8UC1 ? 256 : 65536;
int histSize = _src.type() == CV_8UC1 ? (256 >> bitShift_) : (65536 >> bitShift_);
cv::Size tileSize;
cv::_InputArray _srcForLut;
@@ -411,9 +418,13 @@ namespace
cv::Ptr<cv::ParallelLoopBody> calcLutBody;
if (_src.type() == CV_8UC1)
calcLutBody = cv::makePtr<CLAHE_CalcLut_Body<uchar, 256, 0> >(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale);
{
calcLutBody = cv::makePtr<CLAHE_CalcLut_Body<uchar> >(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale, histSize, bitShift_);
}
else if (_src.type() == CV_16UC1)
calcLutBody = cv::makePtr<CLAHE_CalcLut_Body<ushort, 65536, 0> >(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale);
{
calcLutBody = cv::makePtr<CLAHE_CalcLut_Body<ushort> >(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale, histSize, bitShift_);
}
else
CV_Error( cv::Error::StsBadArg, "Unsupported type" );
@@ -421,9 +432,13 @@ namespace
cv::Ptr<cv::ParallelLoopBody> interpolationBody;
if (_src.type() == CV_8UC1)
interpolationBody = cv::makePtr<CLAHE_Interpolation_Body<uchar, 0> >(src, dst, lut_, tileSize, tilesX_, tilesY_);
{
interpolationBody = cv::makePtr<CLAHE_Interpolation_Body<uchar> >(src, dst, lut_, tileSize, tilesX_, tilesY_, bitShift_);
}
else if (_src.type() == CV_16UC1)
interpolationBody = cv::makePtr<CLAHE_Interpolation_Body<ushort, 0> >(src, dst, lut_, tileSize, tilesX_, tilesY_);
{
interpolationBody = cv::makePtr<CLAHE_Interpolation_Body<ushort> >(src, dst, lut_, tileSize, tilesX_, tilesY_, bitShift_);
}
cv::parallel_for_(cv::Range(0, src.rows), *interpolationBody);
}
@@ -449,6 +464,16 @@ namespace
return cv::Size(tilesX_, tilesY_);
}
void CLAHE_Impl::setBitShift(int bitShift)
{
bitShift_ = bitShift;
}
int CLAHE_Impl::getBitShift() const
{
return bitShift_;
}
void CLAHE_Impl::collectGarbage()
{
srcExt_.release();
+12
View File
@@ -1647,6 +1647,18 @@ ThickLine( Mat& img, Point2l p0, Point2l p1, const void* color,
{
static const double INV_XY_ONE = 1./static_cast<double>(XY_ONE);
Rect_<int64> boundingRect(Point2l(0, 0), (Size2l)img.size());
if( (thickness > 1) && (shift == 0) && ( !boundingRect.contains(p0) || !boundingRect.contains(p1) ) )
{
const int margin = thickness;
const Point2l offset(margin, margin);
p0 += offset;
p1 += offset;
clipLine(Size2l(boundingRect.width+2*margin, boundingRect.height+2*margin), p0, p1);
p0 -= offset;
p1 -= offset;
}
p0.x <<= XY_SHIFT - shift;
p0.y <<= XY_SHIFT - shift;
p1.x <<= XY_SHIFT - shift;
+61 -124
View File
@@ -651,171 +651,108 @@ static Rect pointSetBoundingRect( const Mat& points )
int depth = points.depth();
CV_Assert(npoints >= 0 && (depth == CV_32F || depth == CV_32S));
int xmin = 0, ymin = 0, xmax = -1, ymax = -1, i;
int xmin = 0, ymin = 0, xmax = -1, ymax = -1, i = 0;
bool is_float = depth == CV_32F;
if( npoints == 0 )
return Rect();
#if CV_SIMD // TODO: enable for CV_SIMD_SCALABLE, loop tail related.
if( !is_float )
{
const int32_t* pts = points.ptr<int32_t>();
int64_t firstval = 0;
std::memcpy(&firstval, pts, sizeof(pts[0]) * 2);
xmin = xmax = pts[0];
ymin = ymax = pts[1];
#if CV_SIMD || CV_SIMD_SCALABLE
v_int32 minval, maxval;
minval = maxval = v_reinterpret_as_s32(vx_setall_s64(firstval)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
for( i = 1; i <= npoints - VTraits<v_int32>::vlanes()/2; i+= VTraits<v_int32>::vlanes()/2 )
const int nlanes = VTraits<v_int32>::vlanes()/2;
for (; i < npoints; i += nlanes)
{
if (i > npoints - nlanes)
{
if (i == 0)
break;
i = npoints - nlanes;
}
v_int32 ptXY2 = vx_load(pts + 2 * i);
minval = v_min(ptXY2, minval);
maxval = v_max(ptXY2, maxval);
}
minval = v_min(v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(minval))), v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(minval))));
maxval = v_max(v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(maxval))), v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(maxval))));
if( i <= npoints - VTraits<v_int32>::vlanes()/4 )
constexpr int max_nlanes = VTraits<v_int32>::max_nlanes;
int arr_minval[max_nlanes], arr_maxval[max_nlanes];
vx_store(arr_minval, minval);
vx_store(arr_maxval, maxval);
for (int j = 0; j < nlanes; j++)
{
v_int32 ptXY = v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(vx_load_low(pts + 2 * i))));
minval = v_min(ptXY, minval);
maxval = v_max(ptXY, maxval);
i += VTraits<v_int64>::vlanes()/2;
xmin = std::min(xmin, arr_minval[2*j]);
ymin = std::min(ymin, arr_minval[2*j+1]);
xmax = std::max(xmax, arr_maxval[2*j]);
ymax = std::max(ymax, arr_maxval[2*j+1]);
}
for(int j = 16; j < VTraits<v_uint8>::vlanes(); j*=2)
#endif
for( ; i < npoints; i++ )
{
minval = v_min(v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(minval))), v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(minval))));
maxval = v_max(v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(maxval))), v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(maxval))));
int pt_x = pts[2*i];
int pt_y = pts[2*i+1];
xmin = std::min(xmin, pt_x);
xmax = std::max(xmax, pt_x);
ymin = std::min(ymin, pt_y);
ymax = std::max(ymax, pt_y);
}
xmin = v_get0(minval);
xmax = v_get0(maxval);
ymin = v_get0(v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(minval))));
ymax = v_get0(v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(maxval))));
#if CV_SIMD_WIDTH > 16
if( i < npoints )
{
v_int32x4 minval2, maxval2;
minval2 = maxval2 = v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(v_load_low(pts + 2 * i))));
for( i++; i < npoints; i++ )
{
v_int32x4 ptXY = v_reinterpret_as_s32(v_expand_low(v_reinterpret_as_u32(v_load_low(pts + 2 * i))));
minval2 = v_min(ptXY, minval2);
maxval2 = v_max(ptXY, maxval2);
}
xmin = min(xmin, v_get0(minval2));
xmax = max(xmax, v_get0(maxval2));
ymin = min(ymin, v_get0(v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(minval2)))));
ymax = max(ymax, v_get0(v_reinterpret_as_s32(v_expand_high(v_reinterpret_as_u32(maxval2)))));
}
#endif // CV_SIMD
}
else
{
const float* pts = points.ptr<float>();
int64_t firstval = 0;
std::memcpy(&firstval, pts, sizeof(pts[0]) * 2);
xmin = xmax = cvFloor(pts[0]);
ymin = ymax = cvFloor(pts[1]);
#if CV_SIMD || CV_SIMD_SCALABLE
v_float32 minval, maxval;
minval = maxval = v_reinterpret_as_f32(vx_setall_s64(firstval)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
for( i = 1; i <= npoints - VTraits<v_float32>::vlanes()/2; i+= VTraits<v_float32>::vlanes()/2 )
const int nlanes = VTraits<v_float32>::vlanes()/2;
for (; i < npoints; i += nlanes)
{
if (i > npoints - nlanes)
{
if (i == 0)
break;
i = npoints - nlanes;
}
v_float32 ptXY2 = vx_load(pts + 2 * i);
minval = v_min(ptXY2, minval);
maxval = v_max(ptXY2, maxval);
}
minval = v_min(v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(minval))), v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(minval))));
maxval = v_max(v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(maxval))), v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(maxval))));
if( i <= npoints - VTraits<v_float32>::vlanes()/4 )
constexpr int max_nlanes = VTraits<v_int32>::max_nlanes;
float arr_minval[max_nlanes], arr_maxval[max_nlanes];
vx_store(arr_minval, minval);
vx_store(arr_maxval, maxval);
for (int j = 0; j < nlanes; j++)
{
v_float32 ptXY = v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(vx_load_low(pts + 2 * i))));
minval = v_min(ptXY, minval);
maxval = v_max(ptXY, maxval);
i += VTraits<v_float32>::vlanes()/4;
}
for(int j = 16; j < VTraits<v_uint8>::vlanes(); j*=2)
{
minval = v_min(v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(minval))), v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(minval))));
maxval = v_max(v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(maxval))), v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(maxval))));
}
xmin = cvFloor(v_get0(minval));
xmax = cvFloor(v_get0(maxval));
ymin = cvFloor(v_get0(v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(minval)))));
ymax = cvFloor(v_get0(v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(maxval)))));
#if CV_SIMD_WIDTH > 16
if( i < npoints )
{
v_float32x4 minval2, maxval2;
minval2 = maxval2 = v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(v_load_low(pts + 2 * i))));
for( i++; i < npoints; i++ )
{
v_float32x4 ptXY = v_reinterpret_as_f32(v_expand_low(v_reinterpret_as_u32(v_load_low(pts + 2 * i))));
minval2 = v_min(ptXY, minval2);
maxval2 = v_max(ptXY, maxval2);
}
xmin = min(xmin, cvFloor(v_get0(minval2)));
xmax = max(xmax, cvFloor(v_get0(maxval2)));
ymin = min(ymin, cvFloor(v_get0(v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(minval2))))));
ymax = max(ymax, cvFloor(v_get0(v_reinterpret_as_f32(v_expand_high(v_reinterpret_as_u32(maxval2))))));
int _xmin = cvFloor(arr_minval[2*j]), _ymin = cvFloor(arr_minval[2*j+1]);
int _xmax = cvFloor(arr_maxval[2*j]), _ymax = cvFloor(arr_maxval[2*j+1]);
xmin = std::min(xmin, _xmin);
ymin = std::min(ymin, _ymin);
xmax = std::max(xmax, _xmax);
ymax = std::max(ymax, _ymax);
}
#endif
}
#else
const Point* pts = points.ptr<Point>();
Point pt = pts[0];
if( !is_float )
{
xmin = xmax = pt.x;
ymin = ymax = pt.y;
for( i = 1; i < npoints; i++ )
for( ; i < npoints; i++ )
{
pt = pts[i];
// because right and bottom sides of the bounding rectangle are not inclusive
// (note +1 in width and height calculation below), cvFloor is used here instead of cvCeil
int pt_x = cvFloor(pts[2*i]);
int pt_y = cvFloor(pts[2*i+1]);
if( xmin > pt.x )
xmin = pt.x;
if( xmax < pt.x )
xmax = pt.x;
if( ymin > pt.y )
ymin = pt.y;
if( ymax < pt.y )
ymax = pt.y;
xmin = std::min(xmin, pt_x);
xmax = std::max(xmax, pt_x);
ymin = std::min(ymin, pt_y);
ymax = std::max(ymax, pt_y);
}
}
else
{
Cv32suf v;
// init values
xmin = xmax = CV_TOGGLE_FLT(pt.x);
ymin = ymax = CV_TOGGLE_FLT(pt.y);
for( i = 1; i < npoints; i++ )
{
pt = pts[i];
pt.x = CV_TOGGLE_FLT(pt.x);
pt.y = CV_TOGGLE_FLT(pt.y);
if( xmin > pt.x )
xmin = pt.x;
if( xmax < pt.x )
xmax = pt.x;
if( ymin > pt.y )
ymin = pt.y;
if( ymax < pt.y )
ymax = pt.y;
}
v.i = CV_TOGGLE_FLT(xmin); xmin = cvFloor(v.f);
v.i = CV_TOGGLE_FLT(ymin); ymin = cvFloor(v.f);
// because right and bottom sides of the bounding rectangle are not inclusive
// (note +1 in width and height calculation below), cvFloor is used here instead of cvCeil
v.i = CV_TOGGLE_FLT(xmax); xmax = cvFloor(v.f);
v.i = CV_TOGGLE_FLT(ymax); ymax = cvFloor(v.f);
}
#endif
return Rect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
}
+9 -7
View File
@@ -371,28 +371,30 @@ static void initGMMs( const Mat& img, const Mat& mask, GMM& bgdGMM, GMM& fgdGMM
const int kMeansType = KMEANS_PP_CENTERS;
Mat bgdLabels, fgdLabels;
std::vector<Vec3f> bgdSamples, fgdSamples;
std::vector<Vec3b> bgdSamples, fgdSamples;
Point p;
for( p.y = 0; p.y < img.rows; p.y++ )
{
for( p.x = 0; p.x < img.cols; p.x++ )
{
if( mask.at<uchar>(p) == GC_BGD || mask.at<uchar>(p) == GC_PR_BGD )
bgdSamples.push_back( (Vec3f)img.at<Vec3b>(p) );
bgdSamples.push_back( img.at<Vec3b>(p) );
else // GC_FGD | GC_PR_FGD
fgdSamples.push_back( (Vec3f)img.at<Vec3b>(p) );
fgdSamples.push_back( img.at<Vec3b>(p) );
}
}
CV_Assert( !bgdSamples.empty() && !fgdSamples.empty() );
{
Mat _bgdSamples( (int)bgdSamples.size(), 3, CV_32FC1, &bgdSamples[0][0] );
Mat _bgdSamples( (int)bgdSamples.size(), 3, CV_8UC1, &bgdSamples[0][0] );
_bgdSamples.convertTo(_bgdSamples, CV_32FC1);
int num_clusters = GMM::componentsCount;
num_clusters = std::min(num_clusters, (int)bgdSamples.size());
kmeans( _bgdSamples, num_clusters, bgdLabels,
TermCriteria( TermCriteria::MAX_ITER, kMeansItCount, 0.0), 0, kMeansType );
}
{
Mat _fgdSamples( (int)fgdSamples.size(), 3, CV_32FC1, &fgdSamples[0][0] );
Mat _fgdSamples( (int)fgdSamples.size(), 3, CV_8UC1, &fgdSamples[0][0] );
_fgdSamples.convertTo(_fgdSamples, CV_32FC1);
int num_clusters = GMM::componentsCount;
num_clusters = std::min(num_clusters, (int)fgdSamples.size());
kmeans( _fgdSamples, num_clusters, fgdLabels,
@@ -401,12 +403,12 @@ static void initGMMs( const Mat& img, const Mat& mask, GMM& bgdGMM, GMM& fgdGMM
bgdGMM.initLearning();
for( int i = 0; i < (int)bgdSamples.size(); i++ )
bgdGMM.addSample( bgdLabels.at<int>(i,0), bgdSamples[i] );
bgdGMM.addSample( bgdLabels.at<int>(i,0), Vec3d(bgdSamples[i]) );
bgdGMM.endLearning();
fgdGMM.initLearning();
for( int i = 0; i < (int)fgdSamples.size(); i++ )
fgdGMM.addSample( fgdLabels.at<int>(i,0), fgdSamples[i] );
fgdGMM.addSample( fgdLabels.at<int>(i,0), Vec3d(fgdSamples[i]) );
fgdGMM.endLearning();
}
+1 -1
View File
@@ -228,7 +228,7 @@ HoughLinesStandard( InputArray src, OutputArray lines, int type,
int idx = _sort_buf[i];
int n = cvFloor(idx*scale) - 1;
int r = idx - (n+1)*(numrho+2) - 1;
line.rho = (r - (numrho - 1)*0.5f) * rho;
line.rho = (r - (numrho - 1)/2) * rho;
line.angle = static_cast<float>(min_theta) + n * theta;
if (type == CV_32FC2)
{
+1 -1
View File
@@ -401,7 +401,7 @@ static bool ocl_moments( InputArray _src, Moments& m, bool binary)
const int TILE_SIZE = 32;
const int K = 10;
Size sz = _src.getSz();
Size sz = _src.size();
int xtiles = divUp(sz.width, TILE_SIZE);
int ytiles = divUp(sz.height, TILE_SIZE);
int ntiles = xtiles*ytiles;
+1 -1
View File
@@ -162,7 +162,7 @@ __kernel void get_lines(__global uchar * accum_ptr, int accum_step, int accum_of
if (index < linesMax)
{
float radius = (x - (accum_cols - 3) * 0.5f) * rho;
float radius = (x - (accum_cols - 3) / 2) * rho;
float angle = y * theta;
lines[index] = (float2)(radius, angle);
+1 -1
View File
@@ -592,7 +592,7 @@ TEST(Drawing, longline)
Mat mat = Mat::zeros(256, 256, CV_8UC1);
line(mat, cv::Point(34, 204), cv::Point(46400, 47400), cv::Scalar(255), 3);
EXPECT_EQ(310, cv::countNonZero(mat));
EXPECT_EQ(264, cv::countNonZero(mat));
Point pt[6];
pt[0].x = 32;
+63
View File
@@ -340,6 +340,69 @@ TEST(HoughLines, regression_21983)
EXPECT_NEAR(lines[0][1], 1.57179642, 1e-4);
}
TEST(HoughLines, regression_25038_vertical)
{
cv::Mat img = cv::Mat::zeros(8, 8, CV_8UC1);
img.col(3).setTo(255);
cv::Mat lines;
cv::HoughLines(img, lines, 0.5, CV_PI/4., 2);
EXPECT_EQ(1, lines.cols);
EXPECT_EQ(1, lines.rows);
EXPECT_EQ(2, lines.channels());
EXPECT_NEAR(3, lines.at<cv::Vec2f>(0)[0], 1e-5);
EXPECT_NEAR(0, lines.at<cv::Vec2f>(0)[1], 1e-5);
cv::HoughLines(img, lines, 0.05, CV_PI/4., 2);
EXPECT_EQ(1, lines.cols);
EXPECT_EQ(1, lines.rows);
EXPECT_EQ(2, lines.channels());
EXPECT_NEAR(3, lines.at<cv::Vec2f>(0)[0], 1e-5);
EXPECT_NEAR(0, lines.at<cv::Vec2f>(0)[1], 1e-5);
}
TEST(HoughLines, regression_25038_even)
{
cv::Mat img = cv::Mat::zeros(8, 8, CV_8UC1);
img.col(4).setTo(255);
cv::Mat lines;
cv::HoughLines(img, lines, 0.5, CV_PI/4., 2);
EXPECT_EQ(1, lines.cols);
EXPECT_EQ(1, lines.rows);
EXPECT_EQ(2, lines.channels());
EXPECT_NEAR(4, lines.at<cv::Vec2f>(0)[0], 1e-5);
EXPECT_NEAR(0, lines.at<cv::Vec2f>(0)[1], 1e-5);
cv::HoughLines(img, lines, 0.05, CV_PI/4., 2);
EXPECT_EQ(1, lines.cols);
EXPECT_EQ(1, lines.rows);
EXPECT_EQ(2, lines.channels());
EXPECT_NEAR(4, lines.at<cv::Vec2f>(0)[0], 1e-5);
EXPECT_NEAR(0, lines.at<cv::Vec2f>(0)[1], 1e-5);
}
TEST(HoughLines, regression_25038_horizontal)
{
cv::Mat img = cv::Mat::zeros(8, 8, CV_8UC1);
img.row(3).setTo(255);
cv::Mat lines;
cv::HoughLines(img, lines, 0.5, CV_PI/4., 2);
EXPECT_EQ(1, lines.cols);
EXPECT_EQ(1, lines.rows);
EXPECT_EQ(2, lines.channels());
EXPECT_NEAR(3, lines.at<cv::Vec2f>(0)[0], 1e-5);
EXPECT_NEAR(CV_PI/2., lines.at<cv::Vec2f>(0)[1], 1e-5);
cv::HoughLines(img, lines, 0.05, CV_PI/4., 2);
EXPECT_EQ(1, lines.cols);
EXPECT_EQ(1, lines.rows);
EXPECT_EQ(2, lines.channels());
EXPECT_NEAR(3, lines.at<cv::Vec2f>(0)[0], 1e-5);
EXPECT_NEAR(CV_PI/2., lines.at<cv::Vec2f>(0)[1], 1e-5);
}
TEST(WeightedHoughLines, horizontal)
{
Mat img(25, 25, CV_8UC1, Scalar(0));
+6 -6
View File
@@ -26,7 +26,7 @@ QUnit.test('Detectors', function(assert) {
let orb = new cv.ORB();
orb.detect(image, kp);
assert.equal(kp.size(), 67, 'ORB');
assert.equal(kp.size(), 68, 'ORB');
/* TODO: Fix test failure Expected: 7 Result: 0
bug: https://github.com/opencv/opencv/issues/25862
@@ -62,14 +62,14 @@ QUnit.test('BFMatcher', function(assert) {
let orb = new cv.ORB();
orb.detectAndCompute(image, new cv.Mat(), kp, descriptors);
assert.equal(kp.size(), 67);
assert.equal(kp.size(), 68);
// Run a matcher.
let dm = new cv.DMatchVector();
let matcher = new cv.BFMatcher();
matcher.match(descriptors, descriptors, dm);
assert.equal(dm.size(), 67);
assert.equal(dm.size(), 68);
});
QUnit.test('Drawing', function(assert) {
@@ -80,7 +80,7 @@ QUnit.test('Drawing', function(assert) {
let descriptors = new cv.Mat();
let orb = new cv.ORB();
orb.detectAndCompute(image, new cv.Mat(), kp, descriptors);
assert.equal(kp.size(), 67);
assert.equal(kp.size(), 68);
let dst = new cv.Mat();
cv.drawKeypoints(image, kp, dst);
@@ -91,7 +91,7 @@ QUnit.test('Drawing', function(assert) {
let dm = new cv.DMatchVector();
let matcher = new cv.BFMatcher();
matcher.match(descriptors, descriptors, dm);
assert.equal(dm.size(), 67);
assert.equal(dm.size(), 68);
cv.drawMatches(image, kp, image, kp, dm, dst);
assert.equal(dst.rows, image.rows);
@@ -99,7 +99,7 @@ QUnit.test('Drawing', function(assert) {
dm = new cv.DMatchVectorVector();
matcher.knnMatch(descriptors, descriptors, dm, 2);
assert.equal(dm.size(), 67);
assert.equal(dm.size(), 68);
cv.drawMatchesKnn(image, kp, image, kp, dm, dst);
assert.equal(dst.rows, image.rows);
assert.equal(dst.cols, 2 * image.cols);
@@ -274,14 +274,21 @@ class AliasTypeNode(TypeNode):
required_modules: Tuple[str, ...] = ()) -> None:
super().__init__(ctype_name, required_modules)
self.value = value
self._export_name = export_name
# If alias is exported as is - use its ctype_name
if export_name is None:
forbidden_symbols = (":", "*", "&")
assert all(symbol not in ctype_name for symbol in forbidden_symbols), (
"Failed to create AliasTypeNode without export_name. "
f"'{ctype_name}' should not contain any of {forbidden_symbols}"
)
self._export_name = ctype_name
else:
self._export_name = export_name
self.doc = doc
@property
def typename(self) -> str:
if self._export_name is not None:
return self._export_name
return self.ctype_name
return self._export_name
@property
def full_typename(self) -> str:
+1 -1
View File
@@ -12,7 +12,7 @@ if(NOT HAVE_FFMPEG AND OPENCV_FFMPEG_USE_FIND_PACKAGE)
endif()
endif()
if(NOT HAVE_FFMPEG AND WIN32 AND NOT ARM AND NOT OPENCV_FFMPEG_SKIP_DOWNLOAD)
if(NOT HAVE_FFMPEG AND WIN32 AND NOT ARM AND NOT AARCH64 AND NOT OPENCV_FFMPEG_SKIP_DOWNLOAD)
include("${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/ffmpeg.cmake")
download_win_ffmpeg(FFMPEG_CMAKE_SCRIPT)
if(FFMPEG_CMAKE_SCRIPT)
+5 -1
View File
@@ -13,8 +13,12 @@ if(NOT HAVE_OBSENSOR)
set(HAVE_OBSENSOR TRUE)
set(HAVE_OBSENSOR_ORBBEC_SDK TRUE)
ocv_add_external_target(obsensor "${OrbbecSDK_INCLUDE_DIRS}" "${OrbbecSDK_LIBRARY}" "HAVE_OBSENSOR;HAVE_OBSENSOR_ORBBEC_SDK")
file(COPY ${OrbbecSDK_DLL_FILES} DESTINATION ${CMAKE_BINARY_DIR}/bin)
file(COPY ${OrbbecSDK_DLL_FILES} DESTINATION ${CMAKE_BINARY_DIR}/lib)
if(NOT ORBBEC_SDK_VERSION STREQUAL "1")
# OrbbecSDK v2 loads some libraries at runtime.
file(COPY ${OrbbecSDK_RUNTIME_RESOURCE_FILES} DESTINATION ${CMAKE_BINARY_DIR}/lib)
install(DIRECTORY ${OrbbecSDK_RUNTIME_RESOURCE_FILES} DESTINATION ${OPENCV_LIB_INSTALL_PATH})
endif()
install(FILES ${OrbbecSDK_DLL_FILES} DESTINATION ${OPENCV_LIB_INSTALL_PATH})
ocv_install_3rdparty_licenses(OrbbecSDK ${OrbbecSDK_DIR}/LICENSE.txt)
endif()
+8 -7
View File
@@ -1569,6 +1569,7 @@ bool CvCapture_MSMF::configureAudioFrame()
{
if (!audioSamples.empty() || !bufferAudioData.empty() && aEOS)
{
const int bytesPerSample = (captureAudioFormat.bit_per_sample/8) * captureAudioFormat.nChannels;
_ComPtr<IMFMediaBuffer> buf = NULL;
std::vector<BYTE> audioDataInUse;
BYTE* ptr = NULL;
@@ -1601,20 +1602,19 @@ bool CvCapture_MSMF::configureAudioFrame()
}
audioSamples.clear();
audioSamplePos += chunkLengthOfBytes/((captureAudioFormat.bit_per_sample/8)*captureAudioFormat.nChannels);
chunkLengthOfBytes = (videoStream != -1) ? (LONGLONG)((requiredAudioTime*captureAudioFormat.nSamplesPerSec*captureAudioFormat.nChannels*(captureAudioFormat.bit_per_sample)/8)/1e7) : cursize;
if ((videoStream != -1) && (chunkLengthOfBytes % ((int)(captureAudioFormat.bit_per_sample)/8* (int)captureAudioFormat.nChannels) != 0))
audioSamplePos += chunkLengthOfBytes/bytesPerSample;
chunkLengthOfBytes = (videoStream != -1) ? (LONGLONG)((requiredAudioTime*captureAudioFormat.nSamplesPerSec*bytesPerSample)/1e7) : cursize;
if ((videoStream != -1) && (chunkLengthOfBytes % bytesPerSample != 0))
{
if ( (double)audioSamplePos/captureAudioFormat.nSamplesPerSec + audioStartOffset * 1e-7 - usedVideoSampleTime * 1e-7 >= 0 )
chunkLengthOfBytes -= numberOfAdditionalAudioBytes;
numberOfAdditionalAudioBytes = ((int)(captureAudioFormat.bit_per_sample)/8* (int)captureAudioFormat.nChannels)
- chunkLengthOfBytes % ((int)(captureAudioFormat.bit_per_sample)/8* (int)captureAudioFormat.nChannels);
numberOfAdditionalAudioBytes = bytesPerSample - chunkLengthOfBytes % bytesPerSample;
chunkLengthOfBytes += numberOfAdditionalAudioBytes;
}
if (lastFrame && !syncLastFrame || aEOS && !vEOS)
{
chunkLengthOfBytes = bufferAudioData.size();
audioSamplePos += chunkLengthOfBytes/((captureAudioFormat.bit_per_sample/8)*captureAudioFormat.nChannels);
audioSamplePos += chunkLengthOfBytes/bytesPerSample;
}
CV_Check((double)chunkLengthOfBytes, chunkLengthOfBytes >= INT_MIN || chunkLengthOfBytes <= INT_MAX, "MSMF: The chunkLengthOfBytes is out of the allowed range");
copy(bufferAudioData.begin(), bufferAudioData.begin() + (int)chunkLengthOfBytes, std::back_inserter(audioDataInUse));
@@ -1825,7 +1825,8 @@ bool CvCapture_MSMF::grabFrame()
if (audioStream != -1)
{
bufferedAudioDuration = (double)(bufferAudioData.size()/((captureAudioFormat.bit_per_sample/8)*captureAudioFormat.nChannels))/captureAudioFormat.nSamplesPerSec;
const int bytesPerSample = (captureAudioFormat.bit_per_sample/8) * captureAudioFormat.nChannels;
bufferedAudioDuration = (double)(bufferAudioData.size()/bytesPerSample)/captureAudioFormat.nSamplesPerSec;
audioFrame.release();
if (!aEOS)
returnFlag &= grabAudioFrame();
@@ -38,6 +38,9 @@ VideoCapture_obsensor::VideoCapture_obsensor(int, const cv::VideoCaptureParamete
ob::Context::setLoggerToFile(OB_LOG_SEVERITY_OFF, "");
config = std::make_shared<ob::Config>();
pipe = std::make_shared<ob::Pipeline>();
#if ORBBEC_SDK_VERSION_MAJOR != 1
alignFilter = std::make_shared<ob::Align>(OB_STREAM_COLOR);
#endif
int color_width = params.get<double>(CAP_PROP_FRAME_WIDTH, OB_WIDTH_ANY);
int color_height = params.get<double>(CAP_PROP_FRAME_HEIGHT, OB_HEIGHT_ANY);
@@ -75,12 +78,25 @@ VideoCapture_obsensor::VideoCapture_obsensor(int, const cv::VideoCaptureParamete
config->enableStream(depthProfile->as<ob::VideoStreamProfile>());
}
#if ORBBEC_SDK_VERSION_MAJOR == 1
config->setAlignMode(ALIGN_D2C_SW_MODE);
#else
config->setFrameAggregateOutputMode(OB_FRAME_AGGREGATE_OUTPUT_ALL_TYPE_FRAME_REQUIRE);
pipe->enableFrameSync();
#endif
pipe->start(config, [&](std::shared_ptr<ob::FrameSet> frameset) {
std::unique_lock<std::mutex> lk(videoFrameMutex);
#if ORBBEC_SDK_VERSION_MAJOR == 1
colorFrame = frameset->colorFrame();
depthFrame = frameset->depthFrame();
#else
auto alignFrameSet = alignFilter->process(frameset);
if (alignFrameSet) {
colorFrame = alignFrameSet->as<ob::FrameSet>()->colorFrame();
depthFrame = alignFrameSet->as<ob::FrameSet>()->depthFrame();
}
#endif
});
auto param = pipe->getCameraParam();
@@ -59,6 +59,9 @@ protected:
std::shared_ptr<ob::VideoFrame> grabbedDepthFrame;
std::shared_ptr<ob::Pipeline> pipe;
std::shared_ptr<ob::Config> config;
#if ORBBEC_SDK_VERSION_MAJOR != 1
std::shared_ptr<ob::Align> alignFilter;
#endif
CameraParam camParam;
};
+1 -1
View File
@@ -132,7 +132,7 @@ function main() {
var cell = document.getElementById("targetNames").insertCell(0);
cell.innerHTML = name;
persons[name] = face2vec(face).clone();
persons[name] = face2vec(face).mat_clone();
var canvas = document.createElement("canvas");
canvas.setAttribute("width", 112);