diff --git a/.github/workflows/linux-cuda-gnu.yml b/.github/workflows/linux-cuda-gnu.yml index efe10b21..7d2a37e7 100644 --- a/.github/workflows/linux-cuda-gnu.yml +++ b/.github/workflows/linux-cuda-gnu.yml @@ -75,7 +75,7 @@ jobs: DEBIAN_FRONTEND: noninteractive # evision related env vars MIX_ENV: test - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" OTP_VERSION: "25.3" ELIXIR_VERSION: "1.16.1" EVISION_PREFER_PRECOMPILED: "false" diff --git a/.github/workflows/linux-precompile-cuda-gnu.yml b/.github/workflows/linux-precompile-cuda-gnu.yml index c9948762..9b9d4e82 100644 --- a/.github/workflows/linux-precompile-cuda-gnu.yml +++ b/.github/workflows/linux-precompile-cuda-gnu.yml @@ -38,7 +38,7 @@ jobs: DEBIAN_FRONTEND: noninteractive # evision related env vars MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" ELIXIR_VERSION: "1.15.2" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" diff --git a/.github/workflows/linux-precompile-gnu.yml b/.github/workflows/linux-precompile-gnu.yml index 62c2e489..7c9a1b2f 100644 --- a/.github/workflows/linux-precompile-gnu.yml +++ b/.github/workflows/linux-precompile-gnu.yml @@ -13,7 +13,7 @@ jobs: mix_compile: runs-on: ubuntu-20.04 env: - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" MIX_ENV: prod ELIXIR_VERSION: "1.16.1" EVISION_PREFER_PRECOMPILED: "false" diff --git a/.github/workflows/linux-precompile-manylinux2014-gnu.yml b/.github/workflows/linux-precompile-manylinux2014-gnu.yml index ea5ea8e3..728b2e79 100644 --- a/.github/workflows/linux-precompile-manylinux2014-gnu.yml +++ b/.github/workflows/linux-precompile-manylinux2014-gnu.yml @@ -14,7 +14,7 @@ jobs: mix_compile: runs-on: ubuntu-latest env: - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" MIX_ENV: prod EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" diff --git a/.github/workflows/linux-precompile-musl.yml b/.github/workflows/linux-precompile-musl.yml index f670fa9b..60b13db1 100644 --- a/.github/workflows/linux-precompile-musl.yml +++ b/.github/workflows/linux-precompile-musl.yml @@ -15,7 +15,7 @@ jobs: container: alpine:latest env: MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" strategy: @@ -167,7 +167,7 @@ jobs: zig_build: runs-on: ubuntu-20.04 env: - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" MIX_ENV: prod ZIG_VERSION: "0.8.0" EVISION_PREFER_PRECOMPILED: "false" diff --git a/.github/workflows/linux-x86_64.yml b/.github/workflows/linux-x86_64.yml index 6e7ba734..c7f89790 100644 --- a/.github/workflows/linux-x86_64.yml +++ b/.github/workflows/linux-x86_64.yml @@ -66,7 +66,7 @@ jobs: container: alpine:latest env: MIX_ENV: test - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" OTP_VERSION: "26.2.2" ELIXIR_VERSION: "1.16.1" EVISION_PREFER_PRECOMPILED: "false" @@ -162,7 +162,7 @@ jobs: runs-on: ubuntu-20.04 env: MIX_ENV: test - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" OTP_VERSION: "25.2" ELIXIR_VERSION: "1.14.3" EVISION_PREFER_PRECOMPILED: "false" diff --git a/.github/workflows/macos-apple-device-precompile.yml b/.github/workflows/macos-apple-device-precompile.yml index 018ee51b..fd8940d1 100644 --- a/.github/workflows/macos-apple-device-precompile.yml +++ b/.github/workflows/macos-apple-device-precompile.yml @@ -18,7 +18,7 @@ jobs: runs-on: macos-14 env: MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" strategy: diff --git a/.github/workflows/macos-precompile.yml b/.github/workflows/macos-precompile.yml index 4d56628a..4b0818f0 100644 --- a/.github/workflows/macos-precompile.yml +++ b/.github/workflows/macos-precompile.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.pair.os }} env: MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" strategy: diff --git a/.github/workflows/macos-x86_64.yml b/.github/workflows/macos-x86_64.yml index 3d51bc3a..f7d29ff9 100644 --- a/.github/workflows/macos-x86_64.yml +++ b/.github/workflows/macos-x86_64.yml @@ -53,7 +53,7 @@ jobs: mix_test: runs-on: macos-12 env: - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" MIX_ENV: "test" EVISION_PREFER_PRECOMPILED: "false" FFMPEG_VER: "5" diff --git a/.github/workflows/nerves-build.yml b/.github/workflows/nerves-build.yml index ce1dee7f..637c93a6 100644 --- a/.github/workflows/nerves-build.yml +++ b/.github/workflows/nerves-build.yml @@ -54,7 +54,7 @@ jobs: env: MIX_ENV: prod NERVES_PROJ_NAME: nerves_evision - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" NERVES_LIVEBOOK_VER: "v0.12.1" ELIXIR_VERSION: "1.16.1" EVISION_PREFER_PRECOMPILED: "false" diff --git a/.github/workflows/windows-precompile-cuda.yml b/.github/workflows/windows-precompile-cuda.yml index 1cbf7076..bbb468fe 100644 --- a/.github/workflows/windows-precompile-cuda.yml +++ b/.github/workflows/windows-precompile-cuda.yml @@ -15,7 +15,7 @@ jobs: runs-on: windows-2019 env: MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" ELIXIR_VERSION: "1.16.0" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" @@ -113,7 +113,7 @@ jobs: runs-on: windows-2019 env: MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" ELIXIR_VERSION: "1.16.0" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" diff --git a/.github/workflows/windows-precompile.yml b/.github/workflows/windows-precompile.yml index f047d8ea..e0637861 100644 --- a/.github/workflows/windows-precompile.yml +++ b/.github/workflows/windows-precompile.yml @@ -14,7 +14,7 @@ jobs: runs-on: windows-latest env: MIX_ENV: prod - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" ELIXIR_VERSION: "1.15.4" EVISION_PREFER_PRECOMPILED: "false" EVISION_GENERATE_LANG: "erlang,elixir" diff --git a/.github/workflows/windows-x86_64.yml b/.github/workflows/windows-x86_64.yml index 49378ce9..c2ae61ef 100644 --- a/.github/workflows/windows-x86_64.yml +++ b/.github/workflows/windows-x86_64.yml @@ -52,7 +52,7 @@ jobs: runs-on: windows-latest env: MIX_ENV: test - OPENCV_VER: "4.9.0" + OPENCV_VER: "4.10.0" OTP_VERSION: "25.2" ELIXIR_VERSION: "1.14.3" EVISION_PREFER_PRECOMPILED: "false" diff --git a/Makefile b/Makefile index 4e73c547..adf51d3f 100644 --- a/Makefile +++ b/Makefile @@ -19,13 +19,13 @@ CMAKE_BUILD_TYPE ?= Release # OpenCV OPENCV_USE_GIT_HEAD ?= false OPENCV_GIT_REPO ?= "https://github.com/opencv/opencv.git" -OPENCV_VER ?= 4.9.0 +OPENCV_VER ?= 4.10.0 ifneq ($(OPENCV_USE_GIT_HEAD), false) OPENCV_VER=$(OPENCV_USE_GIT_BRANCH) endif OPENCV_CONTRIB_USE_GIT_HEAD ?= false OPENCV_CONTRIB_GIT_REPO ?= "https://github.com/opencv/opencv_contrib.git" -OPENCV_CONTRIB_VER ?= 4.9.0 +OPENCV_CONTRIB_VER ?= 4.10.0 ifneq ($(OPENCV_CONTRIB_USE_GIT_HEAD), false) OPENCV_CONTRIB_VER=$(OPENCV_CONTRIB_USE_GIT_BRANCH) endif diff --git a/Makefile.win b/Makefile.win index a2d7a5e0..6c89b089 100644 --- a/Makefile.win +++ b/Makefile.win @@ -22,10 +22,10 @@ OPENCV_USE_GIT_HEAD=false OPENCV_GIT_REPO="https://github.com/opencv/opencv.git" !ENDIF !IFNDEF OPENCV_VER -OPENCV_VER=4.9.0 +OPENCV_VER=4.10.0 !ENDIF !IFNDEF OPENCV_CONTRIB_VER -OPENCV_CONTRIB_VER=4.9.0 +OPENCV_CONTRIB_VER=4.10.0 !ENDIF !IF "$(OPENCV_USE_GIT_HEAD)" == "true" OPENCV_VER=$(OPENCV_USE_GIT_BRANCH) diff --git a/README.md b/README.md index 3bd33b68..66b427eb 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ Compatible OpenCV versions: - 4.7.0 - 4.8.0 - 4.9.0 +- 4.10.0 by compatible, it means these versions can compile successfully, and I tested a small range of functions. Tons of tests should be written, and then we can have a list for tested OpenCV versions. diff --git a/c_src/evision.cpp b/c_src/evision.cpp index fe0908e2..1e174dc0 100644 --- a/c_src/evision.cpp +++ b/c_src/evision.cpp @@ -1377,6 +1377,26 @@ ERL_NIF_TERM evision_from(ErlNifEnv *env, const Rect& r) ); } +template<> +bool evision_to(ErlNifEnv *env, ERL_NIF_TERM obj, Rect2f& r, const ArgInfo& info) +{ + RefWrapper values[] = { + RefWrapper(r.x), RefWrapper(r.y), + RefWrapper(r.width), RefWrapper(r.height)}; + return parseSequence(env, obj, values, info); +} + +template<> +ERL_NIF_TERM evision_from(ErlNifEnv *env, const Rect2f& r) +{ + return enif_make_tuple4(env, + evision_from(env, r.x), + evision_from(env, r.y), + evision_from(env, r.width), + evision_from(env, r.height) + ); +} + template<> bool evision_to(ErlNifEnv *env, ERL_NIF_TERM obj, Rect2d& r, const ArgInfo& info) { diff --git a/mix.exs b/mix.exs index 31b52728..f3f1b495 100644 --- a/mix.exs +++ b/mix.exs @@ -2,12 +2,12 @@ defmodule Evision.MixProject.Metadata do @moduledoc false def app, do: :evision - def version, do: "0.1.39" + def version, do: "0.1.40-dev" def github_url, do: "https://github.com/cocoa-xu/evision" - def opencv_version, do: "4.9.0" + def opencv_version, do: "4.10.0" # only means compatible. need to write more tests def compatible_opencv_versions, - do: ["4.5.3", "4.5.4", "4.5.5", "4.6.0", "4.7.0", "4.8.0", "4.9.0"] + do: ["4.5.3", "4.5.4", "4.5.5", "4.6.0", "4.7.0", "4.8.0", "4.9.0", "4.10.0"] def default_cuda_version, do: "118" def all_cuda_version, do: ["118", "121"] diff --git a/patches/apply_patch.py b/patches/apply_patch.py index 8fb88efd..c48874c2 100644 --- a/patches/apply_patch.py +++ b/patches/apply_patch.py @@ -9,8 +9,30 @@ from cStringIO import StringIO +def patch_imread(opencv_version: str, opencv_src_root: str): + if opencv_version not in ['4.10.0']: + print(f"warning: applying `patch_imread` to opencv version `{opencv_version}`") + + # modules/imgcodecs/src/loadsave.cpp + loadsave_cpp = Path(opencv_src_root) / 'modules' / 'imgcodecs' / 'src' / 'loadsave.cpp' + fixed = StringIO() + patched_1 = False + with open(loadsave_cpp, 'r') as source: + for line in source: + if not patched_1 and line.strip() == 'Mat img = dst.getMat();': + fixed.write(" Mat& img = dst.getMatRef(); // patched\n") + patched_1 = True + else: + fixed.write(line) + + if patched_1: + with open(loadsave_cpp, 'w') as dst: + dst.truncate(0) + dst.write(fixed.getvalue()) + + def patch_fix_getLayerShapes(opencv_version: str, opencv_src_root: str): - if opencv_version not in ['4.5.4', '4.5.5', '4.6.0', '4.7.0', '4.8.0', '4.9.0']: + if opencv_version not in ['4.5.4', '4.5.5', '4.6.0', '4.7.0', '4.8.0', '4.9.0', '4.10.0']: print(f"warning: applying `patch_fix_getLayerShapes` to opencv version `{opencv_version}`") # modules/dnn/include/opencv2/dnn/dnn.hpp @@ -140,7 +162,8 @@ def patch_intrin_rvv(opencv_version: str, opencv_src_root: str): patch_winograd, patch_rpath_linux, patch_python_bindings_generator, - patch_intrin_rvv + patch_intrin_rvv, + patch_imread ] diff --git a/py_src/hdr_parser.py b/py_src/hdr_parser.py index a8990305..fa2d0077 100755 --- a/py_src/hdr_parser.py +++ b/py_src/hdr_parser.py @@ -90,6 +90,10 @@ def parse_arg(self, arg_str, argno): modlist.append("/IO") arg_str = arg_str.replace("CV_IN_OUT", "") + if "CV_WRAP_FILE_PATH" in arg_str: + modlist.append("/PATH") + arg_str = arg_str.replace("CV_WRAP_FILE_PATH", "") + isarray = False npos = arg_str.find("CV_CARRAY") if npos >= 0: @@ -451,8 +455,7 @@ def parse_func_decl(self, decl_str, mat="Mat", docstring=""): ("CV_INLINE", ""), ("CV_DEPRECATED", ""), ("CV_DEPRECATED_EXTERNAL", ""), - ("CV_NODISCARD_STD", ""), - ("CV_NODISCARD", "")]).strip() + ("CV_NODISCARD_STD", "")]).strip() if decl_str.strip().startswith('virtual'): virtual_method = True @@ -535,6 +538,13 @@ def parse_func_decl(self, decl_str, mat="Mat", docstring=""): funcname = self.get_dotted_name(funcname) + # see https://github.com/opencv/opencv/issues/24057 + is_arithm_op_func = funcname in {"cv.add", + "cv.subtract", + "cv.absdiff", + "cv.multiply", + "cv.divide"} + if not self.wrap_mode: decl = self.parse_func_decl_no_wrap(decl_str, static_method, docstring) decl[0] = funcname @@ -595,6 +605,8 @@ def parse_func_decl(self, decl_str, mat="Mat", docstring=""): if arg_type == "InputArray": arg_type = mat + if is_arithm_op_func: + modlist.append("/AOS") # Arithm Ope Source elif arg_type == "InputOutputArray": arg_type = mat modlist.append("/IO") @@ -618,6 +630,8 @@ def parse_func_decl(self, decl_str, mat="Mat", docstring=""): ("noArray", arg_type)]).strip() if '/IO' in modlist and '/O' in modlist: modlist.remove('/O') + if (arg_name.lower() == 'filename' or arg_name.lower() == 'filepath') and '/PATH' not in modlist: + modlist.append('/PATH') args.append([arg_type, arg_name, defval, modlist]) npos = arg_start-1 diff --git a/test/evision_test.exs b/test/evision_test.exs index 6f42e2f5..33d2e7d3 100644 --- a/test/evision_test.exs +++ b/test/evision_test.exs @@ -138,7 +138,7 @@ defmodule Evision.Test do bin = Evision.Mat.to_binary(mat) avg = Enum.sum(:binary.bin_to_list(bin)) / byte_size(bin) - {avg_cv, 0.0, 0.0, 0.0} = Evision.mean(mat) + {avg_cv, +0.0, +0.0, +0.0} = Evision.mean(mat) assert abs(avg - avg_cv) < 0.00000001 end diff --git a/test/ml_svm_test.exs b/test/ml_svm_test.exs index e522d50d..cf30e0a4 100644 --- a/test/ml_svm_test.exs +++ b/test/ml_svm_test.exs @@ -42,10 +42,10 @@ defmodule Evision.ML.SVM.Test do float_bytes = 4 support_vector = - for i <- (rows - 1)..0, reduce: [] do + for i <- Range.new(rows - 1, 0, -1), reduce: [] do support_vector -> current_vector = - for j <- (cols - 1)..0, reduce: [] do + for j <- Range.new(cols - 1, 0, -1), reduce: [] do vec -> <> = :binary.part(sv_binary, (i * cols + j) * float_bytes, 4) @@ -64,7 +64,7 @@ defmodule Evision.ML.SVM.Test do height = 512 response_data = - for x <- (width - 1)..0, y <- (height - 1)..0, reduce: [] do + for x <- Range.new(width - 1, 0, -1), y <- Range.new(height - 1, 0, -1), reduce: [] do acc -> %Mat{} = sample =