From e72922981c3069eb17b95e58b434d84fe649e3e4 Mon Sep 17 00:00:00 2001 From: Michael Platings Date: Wed, 31 Jan 2024 10:36:17 +0000 Subject: [PATCH 1/2] Add patch for OpenCV 4.9 This is very similar to the 5.x patch but adjusted for different surrounding context. --- README.md | 10 +- adapters/opencv/opencv-4.9.patch | 179 +++++++++++++++++++++++++++++++ scripts/ci.sh | 7 ++ 3 files changed, 191 insertions(+), 5 deletions(-) create mode 100644 adapters/opencv/opencv-4.9.patch diff --git a/README.md b/README.md index 09ca99760..facb8280b 100644 --- a/README.md +++ b/README.md @@ -93,18 +93,18 @@ and `./scripts/test_android.sh`. ## Install -This library is compatible with [OpenCV](https://opencv.org) version 5.x. +This library is compatible with [OpenCV](https://opencv.org) version 4.9 & 5.x. Integration consists of the following steps: 1. Download OpenCV sources: ``` -git clone https://github.com/opencv/opencv -cd opencv -git checkout 67a3d35b4ea1b11136042cdf5072a634d6789984 +wget https://github.com/opencv/opencv/archive/refs/tags/4.9.0.tar.gz +tar xf 4.9.0 +cd opencv-4.9.0 ``` 2. Patch OpenCV: ``` -git apply /path/to/intrinsiccv/adapters/opencv/opencv-5.x.patch +patch -p1 +// +// SPDX-License-Identifier: Apache-2.0 + +diff --git a/3rdparty/intrinsiccv/CMakeLists.txt b/3rdparty/intrinsiccv/CMakeLists.txt +new file mode 100644 +index 0000000000..c0ffb73ad7 +--- /dev/null ++++ b/3rdparty/intrinsiccv/CMakeLists.txt +@@ -0,0 +1,3 @@ ++set(INTRINSICCV_SOURCE_PATH "${CMAKE_SOURCE_DIR}/intrinsiccv" CACHE PATH "Directory containing IntrinsicCV sources") ++ ++include("${INTRINSICCV_SOURCE_PATH}/adapters/opencv/CMakeLists.txt") +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 5da9c2a695..0ec03b84b7 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -254,6 +254,8 @@ OCV_OPTION(WITH_CAP_IOS "Enable iOS video capture" ON + VERIFY HAVE_CAP_IOS) + OCV_OPTION(WITH_CAROTENE "Use NVidia carotene acceleration library for ARM platform" (NOT CV_DISABLE_OPTIMIZATION) + VISIBLE_IF (ARM OR AARCH64) AND NOT IOS AND NOT XROS) ++OCV_OPTION(WITH_INTRINSICCV "Use IntrinsicCV library for ARM platforms" OFF ++ VISIBLE_IF (AARCH64)) + OCV_OPTION(WITH_CPUFEATURES "Use cpufeatures Android library" ON + VISIBLE_IF ANDROID + VERIFY HAVE_CPUFEATURES) +@@ -955,6 +957,13 @@ if(HAVE_OPENVX) + endif() + endif() + ++if(WITH_INTRINSICCV) ++ ocv_debug_message(STATUS "Enable IntrinsicCV acceleration") ++ if(NOT ";${OpenCV_HAL};" MATCHES ";intrinsiccv;") ++ set(OpenCV_HAL "intrinsiccv;${OpenCV_HAL}") ++ endif() ++endif() ++ + if(WITH_CAROTENE) + ocv_debug_message(STATUS "Enable carotene acceleration") + if(NOT ";${OpenCV_HAL};" MATCHES ";carotene;") +@@ -979,6 +988,10 @@ foreach(hal ${OpenCV_HAL}) + else() + message(STATUS "Carotene: NEON is not available, disabling carotene...") + endif() ++ elseif(hal STREQUAL "intrinsiccv") ++ add_subdirectory(3rdparty/intrinsiccv) ++ ocv_hal_register(INTRINSICCV_HAL_LIBRARIES INTRINSICCV_HAL_HEADERS INTRINSICCV_HAL_INCLUDE_DIRS) ++ list(APPEND OpenCV_USED_HAL "IntrinsicCV (ver ${INTRINSICCV_HAL_VERSION})") + elseif(hal STREQUAL "openvx") + add_subdirectory(3rdparty/openvx) + ocv_hal_register(OPENVX_HAL_LIBRARIES OPENVX_HAL_HEADERS OPENVX_HAL_INCLUDE_DIRS) +diff --git a/doc/tutorials/introduction/config_reference/config_reference.markdown b/doc/tutorials/introduction/config_reference/config_reference.markdown +index dba280485f..963628ee0d 100644 +--- a/doc/tutorials/introduction/config_reference/config_reference.markdown ++++ b/doc/tutorials/introduction/config_reference/config_reference.markdown +@@ -623,6 +623,7 @@ Following build options are utilized in `opencv_contrib` modules, as stated [pre + `CMAKE_TOOLCHAIN_FILE` + + `WITH_CAROTENE` ++`WITH_INTRINSICCV` + `WITH_CPUFEATURES` + `WITH_EIGEN` + `WITH_OPENVX` +diff --git a/modules/core/include/opencv2/core/hal/interface.h b/modules/core/include/opencv2/core/hal/interface.h +index 6f0a83d359..4c294962ca 100644 +--- a/modules/core/include/opencv2/core/hal/interface.h ++++ b/modules/core/include/opencv2/core/hal/interface.h +@@ -81,6 +81,8 @@ typedef signed char schar; + + #define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) + #define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) ++#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) ++#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) + + #define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) + #define CV_MAKE_TYPE CV_MAKETYPE +diff --git a/modules/core/src/convert.dispatch.cpp b/modules/core/src/convert.dispatch.cpp +index 345b4624cb..1ace8f1d5c 100644 +--- a/modules/core/src/convert.dispatch.cpp ++++ b/modules/core/src/convert.dispatch.cpp +@@ -202,6 +202,9 @@ void Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) cons + _dst.create( dims, size, _type ); + Mat dst = _dst.getMat(); + ++ if( dims <= 2 ) ++ CALL_HAL(convertTo, cv_hal_convertTo, src.data, src.step, src.depth(), dst.data, dst.step, dst.depth(), src.cols, src.rows, alpha, beta); ++ + BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth); + double scale[] = {alpha, beta}; + int cn = channels(); +diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp +index 1f2b259920..b0e5db024d 100644 +--- a/modules/core/src/hal_replacement.hpp ++++ b/modules/core/src/hal_replacement.hpp +@@ -818,6 +818,35 @@ inline int hal_ni_rotate90(int src_type, const uchar* src_data, size_t src_step, + #define cv_hal_rotate90 hal_ni_rotate90 + //! @endcond + ++/** ++ @brief Transpose ++ @param src_data,src_step Source image ++ @param dst_data,dst_step Destination image ++ @param src_width,src_height Source image dimensions ++ @param element_size Size of an element in bytes ++*/ ++inline int hal_ni_transpose(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int src_width, ++ int src_height, int element_size) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } ++ ++//! @cond IGNORED ++#define cv_hal_transpose hal_ni_transpose ++//! @endcond ++ ++/** ++ @brief convertTo ++ @param src_data,src_step,src_depth Source image ++ @param dst_data,dst_step,dst_depth Destination image ++ @param width,height Source image dimensions ++ @param scale,shift Dst values = src_value * scale + shift ++*/ ++inline int hal_ni_convertTo(const uchar *src_data, size_t src_step, int src_depth, ++ uchar *dst_data, size_t dst_step, int dst_depth, int width, ++ int height, double scale, double shift) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } ++ ++//! @cond IGNORED ++#define cv_hal_convertTo hal_ni_convertTo ++//! @endcond ++ + //! @} + + +diff --git a/modules/core/src/matrix_transform.cpp b/modules/core/src/matrix_transform.cpp +index 5a80ac8ca7..2e79f0772a 100644 +--- a/modules/core/src/matrix_transform.cpp ++++ b/modules/core/src/matrix_transform.cpp +@@ -269,6 +269,8 @@ void transpose( InputArray _src, OutputArray _dst ) + return; + } + ++ CALL_HAL(transpose, cv_hal_transpose, src.data, src.step, dst.data, dst.step, src.cols, src.rows, esz); ++ + CV_IPP_RUN_FAST(ipp_transpose(src, dst)) + + if( dst.data == src.data ) +diff --git a/modules/imgproc/src/smooth.dispatch.cpp b/modules/imgproc/src/smooth.dispatch.cpp +index 8a521d6df3..186335b121 100644 +--- a/modules/imgproc/src/smooth.dispatch.cpp ++++ b/modules/imgproc/src/smooth.dispatch.cpp +@@ -654,6 +654,20 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, + ocl_GaussianBlur_8UC1(_src, _dst, ksize, CV_MAT_DEPTH(type), kx, ky, borderType) + ); + ++ { ++ Mat src = _src.getMat(); ++ Mat dst = _dst.getMat(); ++ ++ Point ofs; ++ Size wsz(src.cols, src.rows); ++ if(!(borderType & BORDER_ISOLATED)) ++ src.locateROI( wsz, ofs ); ++ ++ CALL_HAL(gaussianBlur, cv_hal_gaussianBlur, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, cn, ++ ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, ksize.height, ++ sigma1, sigma2, borderType&~BORDER_ISOLATED); ++ } ++ + if(sdepth == CV_8U && ((borderType & BORDER_ISOLATED) || !_src.isSubmatrix())) + { + std::vector fkx, fky; +@@ -742,10 +756,6 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, + if(!(borderType & BORDER_ISOLATED)) + src.locateROI( wsz, ofs ); + +- CALL_HAL(gaussianBlur, cv_hal_gaussianBlur, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, cn, +- ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, ksize.height, +- sigma1, sigma2, borderType&~BORDER_ISOLATED); +- + CV_OVX_RUN(true, + openvx_gaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)) + diff --git a/scripts/ci.sh b/scripts/ci.sh index 684ecfe60..70b8f50ac 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -28,6 +28,13 @@ reuse lint # Generate documentation doxygen +OPENCV_VER="4.9.0" +wget "https://github.com/opencv/opencv/archive/refs/tags/${OPENCV_VER}.tar.gz" -O build/opencv.tar.gz +tar xf build/opencv.tar.gz -C build +rm build/opencv.tar.gz +mv "build/opencv-${OPENCV_VER}/" build/opencv +patch -d build/opencv -p1 Date: Wed, 31 Jan 2024 11:44:37 +0000 Subject: [PATCH 2/2] Add check that OpenCV builds with IntrinsicCV --- scripts/ci-opencv.sh | 32 ++++++++++++++++++++++++++++++++ scripts/ci.sh | 10 +++------- 2 files changed, 35 insertions(+), 7 deletions(-) create mode 100755 scripts/ci-opencv.sh diff --git a/scripts/ci-opencv.sh b/scripts/ci-opencv.sh new file mode 100755 index 000000000..c3b679671 --- /dev/null +++ b/scripts/ci-opencv.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +set -exu + +# Ensure we're at the root of the repo. +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +# Ensure we're doing a clean build +rm -rf build/*opencv* + +# Check building OpenCV with IntrinsicCV +OPENCV_PATCH_VER="4.9" +OPENCV_VER="${OPENCV_PATCH_VER}.0" +wget --no-verbose \ + https://github.com/opencv/opencv/archive/refs/tags/${OPENCV_VER}.tar.gz \ + -O build/opencv.tar.gz +tar xf build/opencv.tar.gz -C build +rm build/opencv.tar.gz +mv build/opencv-${OPENCV_VER} build/opencv +patch -d build/opencv -p1