diff --git a/.gitignore b/.gitignore index 133ffe1..4de4e17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,4 @@ -zig-* -.zigmod -deps.zig -### Generated by gibo (https://github.com/simonwhitaker/gibo) -### https://raw.github.com/github/gitignore/d0b80a469983a7beece8fa1f5c48a8242318b531/Global/macOS.gitignore - -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -mnist_png/* - -docs/ -src/images +/zig-out +/.zig-cache +/gocv_build +/gocv* diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2da2cb9..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "libs/gocv"] - path = libs/gocv - url = https://github.com/ryoppippi/gocv diff --git a/.zigversion b/.zigversion new file mode 100644 index 0000000..867eba6 --- /dev/null +++ b/.zigversion @@ -0,0 +1 @@ +0.14.0-dev.1911+3bf89f55c \ No newline at end of file diff --git a/README.md b/README.md index 46a4950..866e8da 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,110 @@ -# ZIGCV - -[![ci](https://github.com/ryoppippi/zigcv/actions/workflows/ci.yml/badge.svg)](https://github.com/ryoppippi/zigcv/actions/workflows/ci.yml) +# ZigCV
-The ZIGCV library provides Zig language bindings for the [OpenCV 4](http://opencv.org/) computer vision library. +The ZigCV library provides Zig language bindings for the +[OpenCV 4](http://opencv.org/) computer vision library. + +The ZigCV library supports the same nominated version of zig as +[Mach](https://machengine.org/) and the +[zig-gamedev](https://github.com/zig-gamedev/) libraries. -The ZIGCV library supports the head/master of zig and OpenCV (v4.6.0) on Linux, macOS, and Windows. +The ZigCV library currently supports +[OpenCV v4.11.0](https://github.com/opencv/opencv/tree/4.11.0). -## Caution +It uses [GoCV 0.40.0](https://github.com/hybridgroup/gocv/tree/v0.40.0) for its +C bindings to OpenCV. -Still under development, so the zig APIs will be dynamically changed. +**Caution** -You can use `const c_api = @import("zigcv").c_api;` to call c bindings directly. -This C-API is currently fixed. +Under development. The Zig APIs may be missing or change. -## How to execute +## Install -### Use your own package manager -At first, install openCV 4.6. (maybe you can read how to install from [here](https://github.com/hybridgroup/gocv#how-to-install)). -Then: +Add to your project's dependencies: ```sh -git clone --recursive https://github.com/ryoppippi/zigcv -cd zigcv -zig build +zig fetch --save 'git+https://codeberg.org/glitchcake/zigcv' ``` -Currently this repo works with zig 0.11.0, so make sure you have it installed. -We are working on updating to zig 0.12.0. +Add to your `build.zig`: +```zig +const zigcv = b.dependency("zigcv", .{}); +exe.root_module.addImport("zigcv", zigcv.module("root")); +exe.linkLibrary(zigcv.artifact("zigcv")); +``` -### Use devbox -We also provide a devbox config to manage dependencies and build environments. +## Usage -```sh -git clone --recursive https://github.com/zigcv -cd zigcv -devbox init +Once added to your project, you may import and use. +```zig +const cv = @import("zigcv"); ``` -Checkout [devbox.json](./devbox.json) for more details. +You can also call C bindings directly via the `c` struct on the import. -## Demos +```zig +cv.c +``` -you can build some demos. -For example: +### Example -```sh -zig build examples -./zig-out/bin/face_detection 0 +Here is a minimal program: + +```zig +const std = @import("std"); +const cv = @import("zigcv"); + +pub fn main() !void { + std.debug.print("version via zig binding:\t{s}\n", .{cv.openCVVersion()}); + std.debug.print("version via c api directly:\t{s}\n", .{cv.c.openCVVersion()}); +} ``` -Or you can run the demo with the following command: +## More Examples + +There are a handful of sample programs in the `examples/` directory. + +You can build them by running `zig build` there: ```sh -devbox run build examples -./zig-out/bin/face_detection 0 +cd examples && zig build; popd; ./examples/zig-out/bin/hello +``` + +## Demo + +``` +./examples/zig-out/bin/face_detection 0 ```
face detection
-You can see the full demo list by `zig build --help`. - ## Technical restrictions -Due to zig being a relatively new language it does [not have full C ABI support](https://github.com/ziglang/zig/issues/1481) at the moment. -For use that mainly means we can't use any functions that return structs that are less than 16 bytes large on x86, and passing structs to any functions may cause memory error on arm. +Due to zig being a relatively new language it does +[not have full C ABI support](https://github.com/ziglang/zig/issues/1481) at the +moment. For use that mainly means we can't use any functions that return structs +that are less than 16 bytes large on x86, and passing structs to any functions +may cause memory error on arm. + +## Todo + +- [ ] Get all examples working +- [ ] Fix all commented out tests +- [ ] Add cuda and openvino back ## License MIT -## Author +## Authors Ryotaro "Justin" Kimura (a.k.a. ryoppippi) + +[glitchcake](https://codeberg.org/glitchcake/) diff --git a/build.zig b/build.zig index 63ddc4a..18f7332 100644 --- a/build.zig +++ b/build.zig @@ -1,112 +1,244 @@ const std = @import("std"); -const LazyPath = std.build.LazyPath; -const zigcv = @import("libs.zig"); -pub fn build(b: *std.build.Builder) void { + +const c_build_options: []const []const u8 = &.{ + "-Wall", + "-Wextra", + "--std=c++11", +}; + +const zig_src_dir = "src/"; + +pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); - const mode = b.standardOptimizeOption(.{}); + const optimize = b.standardOptimizeOption(.{}); - const examples = [_]Program{ - .{ - .name = "hello", - .path = "examples/hello/main.zig", - .desc = "Show Webcam", - }, - .{ - .name = "version", - .path = "examples/version/main.zig", - .desc = "Print OpenCV Version", - }, - .{ - .name = "show_image", - .path = "examples/showimage/main.zig", - .desc = "Show Image Demo", - }, - .{ - .name = "face_detection", - .path = "examples/facedetect/main.zig", - .desc = "Face Detection Demo", - }, - .{ - .name = "face_blur", - .path = "examples/faceblur/main.zig", - .desc = "Face Detection and Blur Demo", - }, - .{ - .name = "dnn_detection", - .path = "examples/dnndetection/main.zig", - .desc = "DNN Detection Demo", - }, - .{ - .name = "saveimage", - .path = "examples/saveimage/main.zig", - .desc = "Save Image Demo", + const gocv_dep = b.dependency("gocv", .{}); + const gocv_src_dir = gocv_dep.path(""); + const gocv_contrib_dir = gocv_dep.path("contrib"); + + const opencv_libs, const opencv4_headers_dir, const opencv4_libraries_dir = buildOpenCVStep(b); + + var zigcv = b.addModule("root", .{ + .root_source_file = b.path("src/zigcv.zig"), + .link_libcpp = true, + }); + zigcv.addIncludePath(gocv_src_dir); // OpenCV C bindings base + zigcv.addIncludePath(gocv_contrib_dir); // OpenCV contrib C bindings + zigcv.addIncludePath(b.path(zig_src_dir)); // Our glue header + zigcv.addIncludePath(opencv4_headers_dir); // Include the opencv4 headers + zigcv.addLibraryPath(opencv4_libraries_dir); + + const zigcv_lib = b.addSharedLibrary(.{ + .name = "zigcv", + .target = target, + .optimize = optimize, + }); + zigcv_lib.step.dependOn(&opencv_libs.step); + + zigcv_lib.addIncludePath(gocv_src_dir); // OpenCV C bindings base + zigcv_lib.addIncludePath(gocv_contrib_dir); // OpenCV contrib C bindings + zigcv_lib.addIncludePath(b.path(zig_src_dir)); // Our glue header + zigcv_lib.addIncludePath(opencv4_headers_dir); // Include the opencv4 headers + + zigcv_lib.addCSourceFile(.{ + .file = b.path("src/core/zig_core.cpp"), + .flags = c_build_options, + }); + + zigcv_lib.addCSourceFiles(.{ + .files = &.{ + "aruco.cpp", + "asyncarray.cpp", + "calib3d.cpp", + "core.cpp", + "dnn.cpp", + "features2d.cpp", + "highgui.cpp", + "imgcodecs.cpp", + "imgproc.cpp", + "objdetect.cpp", + "persistence_filenode.cpp", + "persistence_filestorage.cpp", + "photo.cpp", + "svd.cpp", + "version.cpp", + "video.cpp", + "videoio.cpp", }, - .{ - .name = "detail_enhance", - .path = "examples/detail_enhance/main.zig", - .desc = "Detail Enhanced Image Demo", + .root = gocv_dep.path(""), + .flags = c_build_options, + }); + + zigcv_lib.addCSourceFiles(.{ + .files = &.{ + "bgsegm.cpp", + "face.cpp", + "freetype.cpp", + "img_hash.cpp", + "tracking.cpp", + "wechat_qrcode.cpp", + "xfeatures2d.cpp", + "ximgproc.cpp", + "xphoto.cpp", }, - }; + .root = gocv_contrib_dir, + .flags = c_build_options, + }); + + zigcv_lib.linkLibCpp(); + zigcv_lib.linkSystemLibrary("z"); + + zigcv_lib.addLibraryPath(opencv4_libraries_dir); + zigcv_lib.linkSystemLibrary("opencv_bioinspired"); + zigcv_lib.linkSystemLibrary("opencv_calib3d"); + zigcv_lib.linkSystemLibrary("opencv_ccalib"); + zigcv_lib.linkSystemLibrary("opencv_core"); + zigcv_lib.linkSystemLibrary("opencv_datasets"); + zigcv_lib.linkSystemLibrary("opencv_dnn"); + zigcv_lib.linkSystemLibrary("opencv_dnn_objdetect"); + zigcv_lib.linkSystemLibrary("opencv_dnn_superres"); + zigcv_lib.linkSystemLibrary("opencv_dpm"); + zigcv_lib.linkSystemLibrary("opencv_features2d"); + zigcv_lib.linkSystemLibrary("opencv_flann"); + zigcv_lib.linkSystemLibrary("opencv_freetype"); + zigcv_lib.linkSystemLibrary("opencv_fuzzy"); + zigcv_lib.linkSystemLibrary("opencv_gapi"); + zigcv_lib.linkSystemLibrary("opencv_hfs"); + zigcv_lib.linkSystemLibrary("opencv_highgui"); + zigcv_lib.linkSystemLibrary("opencv_imgcodecs"); + zigcv_lib.linkSystemLibrary("opencv_imgproc"); + zigcv_lib.linkSystemLibrary("opencv_intensity_transform"); + zigcv_lib.linkSystemLibrary("opencv_line_descriptor"); + zigcv_lib.linkSystemLibrary("opencv_mcc"); + zigcv_lib.linkSystemLibrary("opencv_ml"); + zigcv_lib.linkSystemLibrary("opencv_objdetect"); + zigcv_lib.linkSystemLibrary("opencv_optflow"); + zigcv_lib.linkSystemLibrary("opencv_phase_unwrapping"); + zigcv_lib.linkSystemLibrary("opencv_photo"); + zigcv_lib.linkSystemLibrary("opencv_plot"); + zigcv_lib.linkSystemLibrary("opencv_quality"); + zigcv_lib.linkSystemLibrary("opencv_rapid"); + zigcv_lib.linkSystemLibrary("opencv_reg"); + zigcv_lib.linkSystemLibrary("opencv_rgbd"); + zigcv_lib.linkSystemLibrary("opencv_saliency"); + zigcv_lib.linkSystemLibrary("opencv_shape"); + zigcv_lib.linkSystemLibrary("opencv_signal"); + zigcv_lib.linkSystemLibrary("opencv_stereo"); + zigcv_lib.linkSystemLibrary("opencv_stitching"); + zigcv_lib.linkSystemLibrary("opencv_structured_light"); + zigcv_lib.linkSystemLibrary("opencv_superres"); + zigcv_lib.linkSystemLibrary("opencv_surface_matching"); + zigcv_lib.linkSystemLibrary("opencv_text"); + zigcv_lib.linkSystemLibrary("opencv_video"); + zigcv_lib.linkSystemLibrary("opencv_videoio"); + zigcv_lib.linkSystemLibrary("opencv_videostab"); + zigcv_lib.linkSystemLibrary("opencv_xobjdetect"); + + zigcv_lib.linkSystemLibrary("opencv_aruco"); + zigcv_lib.linkSystemLibrary("opencv_bgsegm"); + zigcv_lib.linkSystemLibrary("opencv_face"); + zigcv_lib.linkSystemLibrary("opencv_img_hash"); + zigcv_lib.linkSystemLibrary("opencv_tracking"); + zigcv_lib.linkSystemLibrary("opencv_wechat_qrcode"); + zigcv_lib.linkSystemLibrary("opencv_xfeatures2d"); + zigcv_lib.linkSystemLibrary("opencv_ximgproc"); + zigcv_lib.linkSystemLibrary("opencv_xphoto"); - const examples_step = b.step("examples", "Builds all the examples"); - - for (examples) |ex| { - const exe = b.addExecutable(.{ - .name = ex.name, - .root_source_file = .{ .path = ex.path }, - .target = target, - .optimize = mode, - }); - const exe_step = &exe.step; - - b.installArtifact(exe); - - zigcv.link(b, exe); - zigcv.addAsPackage(exe); - - const run_cmd = b.addRunArtifact(exe); - const run_step = b.step(ex.name, ex.desc); - const artifact_step = &b.addInstallArtifact(exe, .{}).step; - if (b.args) |args| { - run_cmd.addArgs(args); - } - run_step.dependOn(artifact_step); - run_step.dependOn(&run_cmd.step); - examples_step.dependOn(exe_step); - examples_step.dependOn(artifact_step); - } - - var tmp_dir = std.testing.tmpDir(.{}); - defer tmp_dir.cleanup(); - - const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter") orelse null; + b.installArtifact(zigcv_lib); + + // ---- Unit tests --------------------------------------------------------- const unit_tests = b.addTest(.{ - .root_source_file = .{ .path = "src/main.zig" }, + .root_source_file = b.path("src/zigcv.zig"), .target = target, - .optimize = mode, - .filter = test_filter, + .optimize = optimize, }); - zigcv.link(b, unit_tests); - zigcv.addAsPackage(unit_tests); - - const run_unit_tests = b.addRunArtifact(unit_tests); + unit_tests.addIncludePath(gocv_src_dir); // OpenCV C bindings base + unit_tests.addIncludePath(gocv_contrib_dir); // OpenCV contrib C bindings + unit_tests.addIncludePath(b.path(zig_src_dir)); // Our glue header + unit_tests.addIncludePath(opencv4_headers_dir); // Include the opencv4 headers + unit_tests.addLibraryPath(opencv4_libraries_dir); + unit_tests.linkLibrary(zigcv_lib); + unit_tests.linkLibCpp(); + b.installArtifact(unit_tests); const test_step = b.step("test", "Run unit tests"); - test_step.dependOn(&run_unit_tests.step); - - // const emit_docs = b.option(bool, "docs", "Generate Docs"); - // if (emit_docs) |d| { - // if (d) exe_tests.emit_docs = .emit; - // } + test_step.dependOn(&b.addRunArtifact(unit_tests).step); } -inline fn thisDir() []const u8 { - return comptime std.fs.path.dirname(@src().file) orelse "."; -} +fn buildOpenCVStep(b: *std.Build) struct { + *std.Build.Step.Run, + std.Build.LazyPath, + std.Build.LazyPath, +} { + const opencv_dep = b.dependency("opencv", .{}); + const opencv_contrib_dep = b.dependency("opencv_contrib", .{}); -const Program = struct { - name: []const u8, - path: []const u8, - desc: []const u8, - fstage1: bool = false, -}; + const cmake_bin = b.findProgram(&.{"cmake"}, &.{}) catch @panic("Could not find cmake"); + + const configure_cmd = b.addSystemCommand(&.{ cmake_bin, "-B" }); + configure_cmd.setName("Running OpenCV's cmake --configure"); + const build_work_dir = configure_cmd.addOutputDirectoryArg("build_work"); + configure_cmd.setEnvironmentVariable("CC", "zig cc"); + configure_cmd.setEnvironmentVariable("CXX", "zig c++"); + configure_cmd.addArgs(&.{ + "-D", + "CMAKE_BUILD_TYPE=RELEASE", + "-D", + "WITH_IPP=OFF", + "-D", + }); + const opencv4_build_dir = configure_cmd.addPrefixedOutputDirectoryArg("CMAKE_INSTALL_PREFIX=", "zig_opencv4_build"); + configure_cmd.addArgs(&.{ + "-D", + }); + configure_cmd.addPrefixedDirectoryArg("OPENCV_EXTRA_MODULES_PATH=", opencv_contrib_dep.path("modules")); + configure_cmd.addArgs(&.{ + "-D", + "OPENCV_ENABLE_NONFREE=ON", + "-D", + "WITH_JASPER=OFF", + "-D", + "WITH_TBB=ON", + "-D", + "BUILD_DOCS=OFF", + "-D", + "BUILD_EXAMPLES=OFF", + "-D", + "BUILD_TESTS=OFF", + "-D", + "BUILD_PERF_TESTS=OFF", + "-D", + "BUILD_opencv_java=NO", + "-D", + "BUILD_opencv_python=NO", + "-D", + "BUILD_opencv_python2=NO", + "-D", + "BUILD_opencv_python3=NO", + "-D", + "OPENCV_GENERATE_PKGCONFIG=OFF", + }); + configure_cmd.addDirectoryArg(opencv_dep.path("")); + configure_cmd.expectExitCode(0); + + const nproc_bin = b.findProgram(&.{"nproc"}, &.{}) catch @panic("Couldn't find nproc"); + const num_cores = std.mem.trim(u8, b.run(&.{nproc_bin}), "\n"); + + const build_cmd = b.addSystemCommand(&.{ cmake_bin, "--build" }); + build_cmd.setName("Compiling OpenCV with zig"); + build_cmd.addDirectoryArg(build_work_dir); + build_cmd.addArgs(&.{ "-j", num_cores }); + build_cmd.step.dependOn(&configure_cmd.step); + build_cmd.expectExitCode(0); + + const install_cmd = b.addSystemCommand(&.{ cmake_bin, "--install" }); + install_cmd.addDirectoryArg(build_work_dir); + install_cmd.step.dependOn(&build_cmd.step); + install_cmd.expectExitCode(0); + + return .{ + install_cmd, + opencv4_build_dir.path(b, "include/opencv4"), + opencv4_build_dir.path(b, "lib64"), + }; +} diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..53a3f98 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,46 @@ +.{ + .name = "zigcv", + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.1.0", + + // This field is optional. + // This is currently advisory only; Zig does not yet do anything + // with this value. + //.minimum_zig_version = "0.11.0", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{ + .gocv = .{ + .url = "git+https://github.com/hybridgroup/gocv#v0.40.0", + .hash = "12209e6bc3b59b3d0abd300d0df04b7d8151c8d9d6edf8ea450e3d6589597f9c5d2c", + }, + .opencv = .{ + .url = "https://github.com/opencv/opencv#4.11.0", + .hash = "122020210f81d631695cde9340e357c7e05f617448c404f21fec505ef373f9601784", + }, + .opencv_contrib = .{ + .url = "https://github.com/opencv/opencv_contrib#4.11.0", + .hash = "1220bb9a6f65ce5f0f9b576ca028579231ab333509c9c6d9b865492e54abcfe8c460", + }, + }, + .paths = .{ + // This makes *all* files, recursively, included in this package. It is generally + // "", + // better to explicitly list the files and directories instead, to insure that + // fetching from tarballs, file system paths, and version control all result + // in the same contents hash. + // For example... + "build.zig", + "build.zig.zon", + "src", + "logo", + "scripts", + "LICENSE", + "README.md", + }, +} diff --git a/devbox.json b/devbox.json deleted file mode 100644 index 69e8391..0000000 --- a/devbox.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.10.6/.schema/devbox.schema.json", - "packages": [ - "zig@0.11.0", - "zls@0.11.0", - "opencv@4.6.0", - "pkg-config@latest", - "unzip@latest", - "deno@1.43.1" - ], - "shell": { - "scripts": { - "version": "zig version", - "download-models": "deno run -A ./scripts/download_models.ts", - "build": "zig build --verbose", - "test": "zig build test --verbose", - "fmt": "zig fmt ./**/*.zig", - "fmt-check": "zig fmt --check ./**/*.zig" - } - } -} diff --git a/devbox.lock b/devbox.lock deleted file mode 100644 index 0bea5c9..0000000 --- a/devbox.lock +++ /dev/null @@ -1,345 +0,0 @@ -{ - "lockfile_version": "1", - "packages": { - "deno@1.43.1": { - "last_modified": "2024-05-06T06:27:37Z", - "resolved": "github:NixOS/nixpkgs/dd1290b0f857782a60b251f89651c831cd3eef9d#deno", - "source": "devbox-search", - "version": "1.43.1", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/kc5aglf91zj78jw4837nazlgr6ys33cp-deno-1.43.1", - "default": true - } - ], - "store_path": "/nix/store/kc5aglf91zj78jw4837nazlgr6ys33cp-deno-1.43.1" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/c0bg2vwn4mlx0dvaysl67rn5yf73hi40-deno-1.43.1", - "default": true - } - ], - "store_path": "/nix/store/c0bg2vwn4mlx0dvaysl67rn5yf73hi40-deno-1.43.1" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/jzhp7f068y0ph8vyhrwvy86y4lfh969s-deno-1.43.1", - "default": true - } - ], - "store_path": "/nix/store/jzhp7f068y0ph8vyhrwvy86y4lfh969s-deno-1.43.1" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/vvq3r8xjg85892anwj74n154ail9bfs6-deno-1.43.1", - "default": true - } - ], - "store_path": "/nix/store/vvq3r8xjg85892anwj74n154ail9bfs6-deno-1.43.1" - } - } - }, - "opencv@4.6.0": { - "last_modified": "2022-12-17T09:19:40Z", - "resolved": "github:NixOS/nixpkgs/80c24eeb9ff46aa99617844d0c4168659e35175f#opencv", - "source": "devbox-search", - "version": "4.6.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/6csxf267wbdjfx7liqim3qsf2x8c2m12-opencv-4.6.0", - "default": true - } - ], - "store_path": "/nix/store/6csxf267wbdjfx7liqim3qsf2x8c2m12-opencv-4.6.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/kszqyyic4lixhyvvsh44zikd5wvyalgy-opencv-4.6.0", - "default": true - } - ], - "store_path": "/nix/store/kszqyyic4lixhyvvsh44zikd5wvyalgy-opencv-4.6.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/54922bgl2zh411jrgyk3mifza45ab7wh-opencv-4.6.0", - "default": true - } - ], - "store_path": "/nix/store/54922bgl2zh411jrgyk3mifza45ab7wh-opencv-4.6.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/ncgql223yw95pzqbk366k547hcrgvyfy-opencv-4.6.0", - "default": true - } - ], - "store_path": "/nix/store/ncgql223yw95pzqbk366k547hcrgvyfy-opencv-4.6.0" - } - } - }, - "pkg-config@latest": { - "last_modified": "2024-05-04T07:54:21Z", - "resolved": "github:NixOS/nixpkgs/d32560238207b8e26d88b265207b216ee46b8450#pkg-config", - "source": "devbox-search", - "version": "0.29.2", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/s33ia4rw83qw13825vc89k25cr9nxy0f-pkg-config-wrapper-0.29.2", - "default": true - }, - { - "name": "man", - "path": "/nix/store/rnxc8xzqr3md2vrkjskchxmlazgb3l3i-pkg-config-wrapper-0.29.2-man", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/4svv41yk5fzcp1x6bs7xasv7h0mna7c3-pkg-config-wrapper-0.29.2-doc" - } - ], - "store_path": "/nix/store/s33ia4rw83qw13825vc89k25cr9nxy0f-pkg-config-wrapper-0.29.2" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/v9si32s1fpy731gxyajg3i25j5h3f4rx-pkg-config-wrapper-0.29.2", - "default": true - }, - { - "name": "man", - "path": "/nix/store/hqphl7p5sdv1g79i52yd85hhii4r8859-pkg-config-wrapper-0.29.2-man", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/wrawz739fsziria5w8sdlqd2wamazn14-pkg-config-wrapper-0.29.2-doc" - } - ], - "store_path": "/nix/store/v9si32s1fpy731gxyajg3i25j5h3f4rx-pkg-config-wrapper-0.29.2" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/nk81ai038lb8q78n6bsgkhz8vx9hcn9d-pkg-config-wrapper-0.29.2", - "default": true - }, - { - "name": "man", - "path": "/nix/store/5rkzrb2p6dc44pizmk76fzd7ifmjvh11-pkg-config-wrapper-0.29.2-man", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/bs457hmx9lx99qx0qh6ph003hr1q0i13-pkg-config-wrapper-0.29.2-doc" - } - ], - "store_path": "/nix/store/nk81ai038lb8q78n6bsgkhz8vx9hcn9d-pkg-config-wrapper-0.29.2" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/vbk2n3094zyl9ywijks6a3d7s2i6wnfm-pkg-config-wrapper-0.29.2", - "default": true - }, - { - "name": "man", - "path": "/nix/store/x8kzkbimqw5b1x1fbfwvf8saa5mw19rv-pkg-config-wrapper-0.29.2-man", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/asy5zvhg8qb4dzsh6gdwd9450v7lcpb8-pkg-config-wrapper-0.29.2-doc" - } - ], - "store_path": "/nix/store/vbk2n3094zyl9ywijks6a3d7s2i6wnfm-pkg-config-wrapper-0.29.2" - } - } - }, - "unzip@latest": { - "last_modified": "2024-05-01T20:12:28Z", - "resolved": "github:NixOS/nixpkgs/1c74cc292b61614e74c1cf0d372f79d57fb4936b#unzip", - "source": "devbox-search", - "version": "6.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/15cnd2jl4nkyk82lizkpg5b9hjfznaa3-unzip-6.0", - "default": true - } - ], - "store_path": "/nix/store/15cnd2jl4nkyk82lizkpg5b9hjfznaa3-unzip-6.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/5w8y1jggrx6zwnjahg8ms0x7i5p8xrdh-unzip-6.0", - "default": true - } - ], - "store_path": "/nix/store/5w8y1jggrx6zwnjahg8ms0x7i5p8xrdh-unzip-6.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/ixbd88yizic7kkdfrvvxwnyx2ahr5v9k-unzip-6.0", - "default": true - } - ], - "store_path": "/nix/store/ixbd88yizic7kkdfrvvxwnyx2ahr5v9k-unzip-6.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/awd6bmx4i7z2izj8ri5qjddpbw65lnnq-unzip-6.0", - "default": true - } - ], - "store_path": "/nix/store/awd6bmx4i7z2izj8ri5qjddpbw65lnnq-unzip-6.0" - } - } - }, - "zig@0.11.0": { - "last_modified": "2024-05-01T20:12:28Z", - "resolved": "github:NixOS/nixpkgs/1c74cc292b61614e74c1cf0d372f79d57fb4936b#zig", - "source": "devbox-search", - "version": "0.11.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/divv53p9wjrsqvi3g6v3c0vabvhcb3z3-zig-0.11.0", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/6qw4l2a0swfmj60z31nfqbybic8k1mzn-zig-0.11.0-doc" - } - ], - "store_path": "/nix/store/divv53p9wjrsqvi3g6v3c0vabvhcb3z3-zig-0.11.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/al318f1pzzz068qsc75vadhdpdn6ky94-zig-0.11.0", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/c7lklr7ljizgvgs9yzn8vp19pnqjid01-zig-0.11.0-doc" - } - ], - "store_path": "/nix/store/al318f1pzzz068qsc75vadhdpdn6ky94-zig-0.11.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/ph224d02mxv0vm2x9771sw87j08i9g3h-zig-0.11.0", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/06z33wmvqdvhydfanbwsckcfkisml0c6-zig-0.11.0-doc" - } - ], - "store_path": "/nix/store/ph224d02mxv0vm2x9771sw87j08i9g3h-zig-0.11.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/n55qf67p9ss997aiz2m6xrhi34h9nkpz-zig-0.11.0", - "default": true - }, - { - "name": "doc", - "path": "/nix/store/2iipjnd3izphxpd1v7lbrjyc1pg2b30c-zig-0.11.0-doc" - } - ], - "store_path": "/nix/store/n55qf67p9ss997aiz2m6xrhi34h9nkpz-zig-0.11.0" - } - } - }, - "zls@0.11.0": { - "last_modified": "2024-05-01T20:12:28Z", - "resolved": "github:NixOS/nixpkgs/1c74cc292b61614e74c1cf0d372f79d57fb4936b#zls", - "source": "devbox-search", - "version": "0.11.0", - "systems": { - "aarch64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/5s39fhwc1c9aj06q01xj6qi8w2az8jbr-zls-0.11.0", - "default": true - } - ], - "store_path": "/nix/store/5s39fhwc1c9aj06q01xj6qi8w2az8jbr-zls-0.11.0" - }, - "aarch64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/kj30iw7fvs6vhsigaphhla3zlj5b4l0f-zls-0.11.0", - "default": true - } - ], - "store_path": "/nix/store/kj30iw7fvs6vhsigaphhla3zlj5b4l0f-zls-0.11.0" - }, - "x86_64-darwin": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/i6m8fi0nd0afnlvr1c7iaxbn59546jik-zls-0.11.0", - "default": true - } - ], - "store_path": "/nix/store/i6m8fi0nd0afnlvr1c7iaxbn59546jik-zls-0.11.0" - }, - "x86_64-linux": { - "outputs": [ - { - "name": "out", - "path": "/nix/store/5a8ais58j8vi2502vimyzbbclvqi306v-zls-0.11.0", - "default": true - } - ], - "store_path": "/nix/store/5a8ais58j8vi2502vimyzbbclvqi306v-zls-0.11.0" - } - } - } - } -} diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..e901168 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,2 @@ +/.zig-cache +/zig-out diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..6119da7 --- /dev/null +++ b/examples/README.md @@ -0,0 +1 @@ +Example usage of zigcv package. diff --git a/examples/build.zig b/examples/build.zig new file mode 100644 index 0000000..18f3912 --- /dev/null +++ b/examples/build.zig @@ -0,0 +1,84 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const examples = [_]Program{ + .{ + .name = "hello", + .path = "hello/main.zig", + .desc = "Show Webcam", + }, + .{ + .name = "version", + .path = "version/main.zig", + .desc = "Print OpenCV Version", + }, + .{ + .name = "show_image", + .path = "showimage/main.zig", + .desc = "Show Image Demo", + }, + .{ + .name = "face_detection", + .path = "facedetect/main.zig", + .desc = "Face Detection Demo", + }, + .{ + .name = "face_blur", + .path = "faceblur/main.zig", + .desc = "Face Detection and Blur Demo", + }, + .{ + .name = "dnn_detection", + .path = "dnndetection/main.zig", + .desc = "DNN Detection Demo", + }, + .{ + .name = "saveimage", + .path = "saveimage/main.zig", + .desc = "Save Image Demo", + }, + .{ + .name = "detail_enhance", + .path = "detail_enhance/main.zig", + .desc = "Detail Enhanced Image Demo", + }, + }; + + const examples_step = b.step("examples", "Builds all the examples"); + + for (examples) |ex| { + const exe = b.addExecutable(.{ + .name = ex.name, + .root_source_file = b.path(ex.path), + .target = target, + .optimize = optimize, + }); + + b.installArtifact(exe); + + const zigcv = b.dependency("zigcv", .{}); + exe.root_module.addImport("zigcv", zigcv.module("root")); + exe.linkLibrary(zigcv.artifact("zigcv")); + + const run_cmd = b.addRunArtifact(exe); + const run_step = b.step(ex.name, ex.desc); + const artifact_step = &b.addInstallArtifact(exe, .{}).step; + if (b.args) |args| { + run_cmd.addArgs(args); + } + run_step.dependOn(artifact_step); + run_step.dependOn(&run_cmd.step); + examples_step.dependOn(&exe.step); + examples_step.dependOn(artifact_step); + } +} + +const Program = struct { + name: []const u8, + path: []const u8, + desc: []const u8, + fstage1: bool = false, +}; diff --git a/examples/build.zig.zon b/examples/build.zig.zon new file mode 100644 index 0000000..4ca465e --- /dev/null +++ b/examples/build.zig.zon @@ -0,0 +1,39 @@ +.{ + // This is the default name used by packages depending on this one. For + // example, when a user runs `zig fetch --save `, this field is used + // as the key in the `dependencies` table. Although the user can choose a + // different name, most users will stick with this provided value. + // + // It is redundant to include "zig" in this name because it is already + // within the Zig package namespace. + .name = "examples", + + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.0.0", + + // This field is optional. + // This is currently advisory only; Zig does not yet do anything + // with this value. + //.minimum_zig_version = "0.11.0", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{ + .zigcv = .{ + .url = "..", + .hash = "12207c9ccc6e2e1a657c3340e8c037033c7ad276b0c3864fdd8d8894edd906ae8570", + }, + }, + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + // For example... + //"LICENSE", + //"README.md", + }, +} diff --git a/examples/detail_enhance/main.zig b/examples/detail_enhance/main.zig index d8c07e6..06cad9f 100644 --- a/examples/detail_enhance/main.zig +++ b/examples/detail_enhance/main.zig @@ -21,7 +21,7 @@ pub fn main() anyerror!void { while (true) { webcam.read(&img) catch { std.debug.print("capture failed", .{}); - std.os.exit(1); + std.process.exit(1); }; cv.detailEnhance(img, &img2, 100, 0.5); diff --git a/examples/dnndetection/main.zig b/examples/dnndetection/main.zig index 143c4bc..f6ae83d 100644 --- a/examples/dnndetection/main.zig +++ b/examples/dnndetection/main.zig @@ -26,19 +26,19 @@ const Mat = cv.Mat; const Size = cv.Size; const c_api = cv.c_api; -const cache_dir = "./zig-cache/tmp/"; +const cache_dir = "./.zig-cache/tmp/"; const model_path = cache_dir ++ "res10_300x300_ssd_iter_140000.caffemodel"; const model_url = "https://github.com/opencv/opencv_3rdparty/raw/dnn_samples_face_detector_20170830/res10_300x300_ssd_iter_140000.caffemodel"; const config_path = cache_dir ++ "deploy.prototxt"; const config_url = "https://raw.githubusercontent.com/opencv/opencv/master/samples/dnn/face_detector/deploy.prototxt"; pub fn main() anyerror!void { - var allocator = std.heap.page_allocator; + const allocator = std.heap.page_allocator; var args = try std.process.argsWithAllocator(allocator); const prog = args.next(); const device_id_char = args.next() orelse { std.log.err("usage: {s} [cameraID]", .{prog.?}); - std.os.exit(1); + std.process.exit(1); }; args.deinit(); @@ -63,13 +63,13 @@ pub fn main() anyerror!void { // try downloadFile(config_url, cache_dir, allocator); var net = cv.Net.readNet(model_path, config_path) catch |err| { std.debug.print("Error: {}\n", .{err}); - std.os.exit(1); + std.process.exit(1); }; defer net.deinit(); if (net.isEmpty()) { std.debug.print("Error: could not load model\n", .{}); - std.os.exit(1); + std.process.exit(1); } net.setPreferableBackend(.default); @@ -82,7 +82,7 @@ pub fn main() anyerror!void { while (true) { webcam.read(&img) catch { std.debug.print("capture failed", .{}); - std.os.exit(1); + std.process.exit(1); }; if (img.isEmpty()) { continue; @@ -123,14 +123,14 @@ fn performDetection(frame: *Mat, results: Mat) void { const green = cv.Color{ .g = 255 }; var i: usize = 0; while (i < results.total()) { - var confidence = results.get(f32, 0, i + 2); + const confidence = results.get(f32, 0, i + 2); const cols: f32 = @floatFromInt(frame.cols()); const rows: f32 = @floatFromInt(frame.rows()); if (confidence > 0.5) { - var left: i32 = @intFromFloat(results.get(f32, 0, i + 3) * cols); - var top: i32 = @intFromFloat(results.get(f32, 0, i + 4) * rows); - var right: i32 = @intFromFloat(results.get(f32, 0, i + 5) * cols); - var bottom: i32 = @intFromFloat(results.get(f32, 0, i + 6) * rows); + const left: i32 = @intFromFloat(results.get(f32, 0, i + 3) * cols); + const top: i32 = @intFromFloat(results.get(f32, 0, i + 4) * rows); + const right: i32 = @intFromFloat(results.get(f32, 0, i + 5) * cols); + const bottom: i32 = @intFromFloat(results.get(f32, 0, i + 6) * rows); cv.rectangle(frame, cv.Rect{ .x = left, .y = top, .width = right, .height = bottom }, green, 2); } i += 7; diff --git a/examples/faceblur/main.zig b/examples/faceblur/main.zig index 28fabcb..8ac89c0 100644 --- a/examples/faceblur/main.zig +++ b/examples/faceblur/main.zig @@ -3,13 +3,13 @@ const cv = @import("zigcv"); const cv_c_api = cv.c_api; pub fn main() anyerror!void { - var allocator = std.heap.page_allocator; + const allocator = std.heap.page_allocator; var args = try std.process.argsWithAllocator(allocator); defer args.deinit(); const prog = args.next(); const device_id_char = args.next() orelse { std.log.err("usage: {s} [cameraID]", .{prog.?}); - std.os.exit(1); + std.process.exit(1); }; const device_id = try std.fmt.parseUnsigned(c_int, device_id_char, 10); @@ -33,14 +33,14 @@ pub fn main() anyerror!void { classifier.load("./libs/gocv/data/haarcascade_frontalface_default.xml") catch { std.debug.print("no xml", .{}); - std.os.exit(1); + std.process.exit(1); }; const size = cv.Size{ .width = 75, .height = 75 }; while (true) { webcam.read(&img) catch { std.debug.print("capture failed", .{}); - std.os.exit(1); + std.process.exit(1); }; if (img.isEmpty()) { continue; diff --git a/examples/facedetect/main.zig b/examples/facedetect/main.zig index e9b945c..1db59d6 100644 --- a/examples/facedetect/main.zig +++ b/examples/facedetect/main.zig @@ -3,12 +3,12 @@ const cv = @import("zigcv"); const cv_c_api = cv.c_api; pub fn main() anyerror!void { - var allocator = std.heap.page_allocator; + const allocator = std.heap.page_allocator; var args = try std.process.argsWithAllocator(allocator); const prog = args.next(); const device_id_char = args.next() orelse { std.log.err("usage: {s} [cameraID]", .{prog.?}); - std.os.exit(1); + std.process.exit(1); }; args.deinit(); @@ -34,14 +34,14 @@ pub fn main() anyerror!void { classifier.load("./libs/gocv/data/haarcascade_frontalface_default.xml") catch { std.debug.print("no xml", .{}); - std.os.exit(1); + std.process.exit(1); }; const blue = cv.Color{ .b = 255 }; while (true) { webcam.read(&img) catch { std.debug.print("capture failed", .{}); - std.os.exit(1); + std.process.exit(1); }; if (img.isEmpty()) { continue; diff --git a/examples/hello/main.zig b/examples/hello/main.zig index f2eb8be..a79cdb6 100644 --- a/examples/hello/main.zig +++ b/examples/hello/main.zig @@ -1,6 +1,5 @@ const std = @import("std"); const cv = @import("zigcv"); -const cv_c_api = cv.c_api; pub fn main() anyerror!void { // open webcam @@ -19,7 +18,7 @@ pub fn main() anyerror!void { while (true) { webcam.read(&img) catch { std.debug.print("capture failed", .{}); - std.os.exit(1); + std.process.exit(1); }; window.imShow(img); diff --git a/examples/saveimage/main.zig b/examples/saveimage/main.zig index 467cf01..d65fb58 100644 --- a/examples/saveimage/main.zig +++ b/examples/saveimage/main.zig @@ -2,12 +2,12 @@ const std = @import("std"); const cv = @import("zigcv"); pub fn main() anyerror!void { - var allocator = std.heap.page_allocator; + const allocator = std.heap.page_allocator; var args = try std.process.argsWithAllocator(allocator); const prog = args.next(); const device_id_char = args.next() orelse { std.log.err("usage: {s} [cameraID]", .{prog.?}); - std.os.exit(1); + std.process.exit(1); }; args.deinit(); diff --git a/examples/showimage/main.zig b/examples/showimage/main.zig index 36bcfff..f601cf2 100644 --- a/examples/showimage/main.zig +++ b/examples/showimage/main.zig @@ -1,6 +1,5 @@ const std = @import("std"); const cv = @import("zigcv"); -const cv_c_api = cv.c_api; pub fn main() anyerror!void { var args = try std.process.argsWithAllocator(std.heap.page_allocator); @@ -8,7 +7,7 @@ pub fn main() anyerror!void { const prog = args.next(); const img_PATH = args.next() orelse { std.log.err("usage: {s} [image_PATH]", .{prog.?}); - std.os.exit(1); + std.process.exit(1); }; // open display window diff --git a/examples/version/main.zig b/examples/version/main.zig index 0649e3b..0cb451b 100644 --- a/examples/version/main.zig +++ b/examples/version/main.zig @@ -1,6 +1,7 @@ const std = @import("std"); const cv = @import("zigcv"); -pub fn main() anyerror!void { - std.debug.print("version:\t{s}\n", .{cv.openCVVersion()}); +pub fn main() !void { + std.debug.print("version via zig binding:\t{s}\n", .{cv.openCVVersion()}); + std.debug.print("version via c api directly:\t{s}\n", .{cv.c.openCVVersion()}); } diff --git a/libs.zig b/libs.zig deleted file mode 100644 index 4a3e5fc..0000000 --- a/libs.zig +++ /dev/null @@ -1,215 +0,0 @@ -const std = @import("std"); -const ArrayList = std.ArrayList; -const LazyPath = std.build.LazyPath; - -pub fn addAsPackage(exe: *std.Build.CompileStep) void { - addAsPackageWithCustomName(exe, "zigcv"); -} - -pub fn addAsPackageWithCustomName(exe: *std.Build.CompileStep, name: []const u8) void { - const owner = exe.step.owner; - var module = std.build.createModule(owner, .{ - .source_file = std.Build.FileSource.relative("src/main.zig"), - .dependencies = &.{}, - }); - exe.addModule(name, module); -} - -pub fn link(b: *std.build.Builder, exe: *std.Build.CompileStep) void { - ensureSubmodules(exe); - - const target = exe.target; - const mode = exe.optimize; - const builder = exe.step.owner; - - const go_src_files = .{ - "asyncarray.cpp", - "calib3d.cpp", - "core.cpp", - "dnn.cpp", - "features2d.cpp", - "highgui.cpp", - "imgcodecs.cpp", - "imgproc.cpp", - "objdetect.cpp", - "photo.cpp", - "svd.cpp", - "version.cpp", - "video.cpp", - "videoio.cpp", - }; - - const cv = builder.addStaticLibrary(std.Build.StaticLibraryOptions{ - .name = "opencv", - .target = target, - .optimize = mode, - }); - - inline for (go_src_files) |file| { - const go_src_dir_path = go_src_dir.getPath(b); - const c_file_path = b.pathJoin(&.{ go_src_dir_path, file }); - cv.addCSourceFile(.{ - .file = .{ .path = c_file_path }, - .flags = c_build_options, - }); - } - - linkToOpenCV(cv); - - exe.linkLibrary(cv); - linkToOpenCV(exe); -} - -fn linkToOpenCV(exe: *std.build.CompileStep) void { - const target_os = exe.target.toTarget().os.tag; - - exe.addIncludePath(go_src_dir); - exe.addIncludePath(zig_src_dir); - switch (target_os) { - .windows => { - exe.addIncludePath(.{ .path = "c:/msys64/mingw64/include" }); - exe.addIncludePath(.{ .path = "c:/msys64/mingw64/include/c++/12.2.0" }); - exe.addIncludePath(.{ .path = "c:/msys64/mingw64/include/c++/12.2.0/x86_64-w64-mingw32" }); - exe.addLibraryPath(.{ .path = "c:/msys64/mingw64/lib" }); - exe.addIncludePath(.{ .path = "c:/opencv/build/install/include" }); - exe.addLibraryPath(.{ .path = "c:/opencv/build/install/x64/mingw/staticlib" }); - - exe.linkSystemLibrary("opencv4"); - exe.linkSystemLibrary("stdc++.dll"); - exe.linkSystemLibrary("unwind"); - exe.linkSystemLibrary("m"); - exe.linkSystemLibrary("c"); - }, - else => { - exe.linkLibCpp(); - exe.linkSystemLibrary("opencv4"); - exe.linkSystemLibrary("unwind"); - exe.linkSystemLibrary("m"); - exe.linkSystemLibrary("c"); - }, - } -} - -pub const contrib = struct { - pub fn addAsPackage(exe: *std.build.LibExeObjStep) void { - @This().addAsPackageWithCutsomName(exe, "zigcv_contrib"); - } - - pub fn addAsPackageWithCutsomName(exe: *std.build.LibExeObjStep, name: []const u8) void { - exe.addPackagePath(name, .{ .path = "src/contrib/main.zig" }); - } - - pub fn link(b: *std.build.Builder, exe: *std.build.LibExeObjStep) void { - ensureSubmodules(exe); - - const target = exe.target; - const optimize = exe.optimize; - const builder = exe.step.owner; - - const contrib_dir = b.pathJoin(.{ go_src_dir.getPath(b), "contrib/" }); - - const contrib_files = .{ - "aruco.cpp", - "bgsegm.cpp", - "face.cpp", - "img_hash.cpp", - "tracking.cpp", - "wechat_qrcode.cpp", - "xfeatures2d.cpp", - "ximgproc.cpp", - "xphoto.cpp", - }; - - const cv_contrib = builder.addStaticLibrary(.{ - .name = "opencv_contrib", - .target = target, - .optimize = optimize, - }); - cv_contrib.force_pic = true; - for (contrib_files) |file| { - const c_path = b.pathJoin(&.{ contrib_dir, file }); - cv_contrib.addCSourceFile(.{ - .file = .{ .path = c_path }, - .flags = c_build_options, - }); - } - cv_contrib.addIncludePath(.{ .path = contrib_dir }); - linkToOpenCV(cv_contrib); - - exe.linkLibrary(cv_contrib); - linkToOpenCV(exe); - } -}; - -pub const cuda = struct { - pub fn addAsPackage(exe: *std.build.LibExeObjStep) void { - @This().addAsPackageWithCutsomName(exe, "zigcv_cuda"); - } - - pub fn addAsPackageWithCutsomName(exe: *std.build.LibExeObjStep, name: []const u8) void { - exe.addPackagePath(name, .{ .path = "src/cuda/main.zig" }); - } - - pub fn link(b: *std.build.Builder, exe: *std.build.LibExeObjStep) void { - ensureSubmodules(exe); - - const target = exe.target; - const mode = exe.build_mode; - const builder = exe.step.owner; - - const cuda_dir = b.pathJoin(&.{ go_src_dir.getPath(builder), "cuda/" }); - - const cuda_files = .{ - "arithm.cpp", - "bgsegm.cpp", - "core.cpp", - "cuda.cpp", - "filters.cpp", - "imgproc.cpp", - "objdetect.cpp", - "optflow.cpp", - "warping.cpp", - }; - - const cv_cuda = builder.addStaticLibrary("opencv_cuda"); - cv_cuda.setTarget(target); - cv_cuda.setBuildMode(mode); - cv_cuda.force_pic = true; - for (cuda_files) |file| { - const c_path = b.pathJoin(&.{ cuda_dir, file }); - cv_cuda.addCSourceFile(.{ - .file = .{ .path = c_path }, - .flags = c_build_options, - }); - } - cv_cuda.addIncludePath(go_src_dir); - linkToOpenCV(cv_cuda); - - exe.linkLibrary(cv_cuda); - linkToOpenCV(exe); - } -}; - -var ensure_submodule: bool = false; -fn ensureSubmodules(exe: *std.build.LibExeObjStep) void { - const b = exe.step.owner; - if (!ensure_submodule) { - exe.step.dependOn(&b.addSystemCommand(&.{ "git", "submodule", "update", "--init", "--recursive" }).step); - ensure_submodule = true; - } -} - -const go_src_dir = (LazyPath{ .path = "libs/gocv/" }); -const zig_src_dir = (LazyPath{ .path = "src/" }); - -const Program = struct { - name: []const u8, - path: []const u8, - desc: []const u8, -}; - -const c_build_options: []const []const u8 = &.{ - "-Wall", - "-Wextra", - "--std=c++11", -}; diff --git a/libs/gocv b/libs/gocv deleted file mode 160000 index 62e7b0c..0000000 --- a/libs/gocv +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 62e7b0c03570ddbe180bc9b34096d635491a7994 diff --git a/scripts/download_models.ts b/scripts/download_models.ts deleted file mode 100755 index c0a86ff..0000000 --- a/scripts/download_models.ts +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env -S deno run -A -import { $ } from "jsr:@david/dax@0.41.0"; - -$.setPrintCommand(true); - -const MODEL_URLS = [ - "http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel", - "https://raw.githubusercontent.com/opencv/opencv_extra/20d18acad1bcb312045ea64a239ebe68c8728b88/testdata/dnn/bvlc_googlenet.prototxt", - "https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip", - "https://github.com/onnx/models/raw/4eff8f9b9189672de28d087684e7085ad977747c/vision/classification/inception_and_googlenet/googlenet/model/googlenet-9.onnx", - "https://github.com/opencv/opencv_3rdparty/raw/dnn_samples_face_detector_20170830/res10_300x300_ssd_iter_140000.caffemodel", - "https://raw.githubusercontent.com/opencv/opencv/master/samples/dnn/face_detector/deploy.prototxt", -] as const; - -/** get the root of the git repository */ -const git_root = await $`git rev-parse --show-toplevel`.text(); - -/** save the models in the zig-cache/tmp/ directory */ -const saveDir = $.path(git_root).join("./zig-cache/tmp/"); - -/** create the directory if it does not exist */ -await $`mkdir -p ${saveDir.toString()}`; - -$.cd(saveDir); - -/** list the files in the directory */ -await $`ls -lh ${saveDir}`; - -/** download the models */ -const downloadedPath = await Promise.all( - MODEL_URLS.map((url) => $.request(url).showProgress().pipeToPath()), -); - -/** decompress the zip files */ -await Promise.all( - downloadedPath - .filter((path) => path.extname() === ".zip") - .map((path) => $`unzip -o ${path}`), -); - -/** list the files in the directory */ -await $`ls -lh ${saveDir}`; diff --git a/src/asyncarray.zig b/src/asyncarray.zig index d92a3a4..6defe50 100644 --- a/src/asyncarray.zig +++ b/src/asyncarray.zig @@ -12,7 +12,7 @@ pub const AsyncArray = struct { const Self = @This(); pub fn init() !Self { - var ptr = c.AsyncArray_New(); + const ptr = c.AsyncArray_New(); return try Self.initFromC(ptr); } diff --git a/src/c_api.zig b/src/c_api.zig index d0c5531..157f26b 100644 --- a/src/c_api.zig +++ b/src/c_api.zig @@ -1,6 +1,8 @@ pub usingnamespace @cImport({ @cInclude("stdlib.h"); + @cInclude("asyncarray.h"); + @cInclude("aruco.h"); @cInclude("calib3d.h"); @cInclude("core.h"); @cInclude("dnn.h"); @@ -9,9 +11,22 @@ pub usingnamespace @cImport({ @cInclude("imgcodecs.h"); @cInclude("imgproc.h"); @cInclude("objdetect.h"); + @cInclude("persistence.h"); @cInclude("photo.h"); @cInclude("svd.h"); @cInclude("version.h"); @cInclude("video.h"); @cInclude("videoio.h"); + + @cInclude("bgsegm.h"); + @cInclude("face.h"); + @cInclude("freetype.h"); + @cInclude("img_hash.h"); + @cInclude("tracking.h"); + @cInclude("wechat_qrcode.h"); + @cInclude("xfeatures2d.h"); + @cInclude("ximgproc.h"); + @cInclude("xphoto.h"); + + @cInclude("core/zig_core.hpp"); }); diff --git a/src/calib3d.zig b/src/calib3d.zig index 0b02351..f0b5d95 100644 --- a/src/calib3d.zig +++ b/src/calib3d.zig @@ -136,7 +136,7 @@ pub const Fisheye = struct { new_size: Size, fov_scale: f64, ) !Mat { - var mat = try Mat.init(); + const mat = try Mat.init(); _ = c.Fisheye_EstimateNewCameraMatrixForUndistortRectify( k.toC(), d.toC(), @@ -310,7 +310,7 @@ pub fn drawChessboardCorners( /// For further details, please see: /// https://docs.opencv.org/master/d9/d0c/group__calib3d.html#gad767faff73e9cbd8b9d92b955b50062d pub fn estimateAffinePartial2D(from: Point2fVector, to: Point2fVector) !Mat { - var ptr = c.EstimateAffinePartial2D(from.toC(), to.toC()); + const ptr = c.EstimateAffinePartial2D(from.toC(), to.toC()); return try Mat.initFromC(ptr); } @@ -319,7 +319,7 @@ pub fn estimateAffinePartial2D(from: Point2fVector, to: Point2fVector) !Mat { /// For further details, please see: /// https://docs.opencv.org/4.0.0/d9/d0c/group__calib3d.html#ga27865b1d26bac9ce91efaee83e94d4dd pub fn estimateAffine2D(from: Point2fVector, to: Point2fVector) !Mat { - var ptr = c.EstimateAffine2D(from.toC(), to.toC()); + const ptr = c.EstimateAffine2D(from.toC(), to.toC()); return try Mat.initFromC(ptr); } @@ -342,7 +342,7 @@ pub fn estimateAffine2DWithParams( confidence: f64, refine_iters: usize, ) !Mat { - var ptr = c.EstimateAffine2DWithParams( + const ptr = c.EstimateAffine2DWithParams( from.toC(), to.toC(), inliers.toC(), @@ -358,8 +358,8 @@ pub fn estimateAffine2DWithParams( const testing = std.testing; const imgcodecs = @import("imgcodecs.zig"); const imgproc = @import("imgproc.zig"); -const img_dir = "./libs/gocv/images/"; -const cache_dir = "./zig-cache/tmp/"; +const img_dir = "test/images/"; +const cache_dir = "./.zig-cache/tmp/"; test "calib3d fisheye undistortImage" { var img = try imgcodecs.imRead(img_dir ++ "fisheye_sample.jpg", .gray_scale); defer img.deinit(); @@ -435,7 +435,7 @@ test "calib3d fisheye undistortImageWithParams" { k_new.set(f64, 0, 0, 0.4 * k.get(f64, 0, 0)); k_new.set(f64, 1, 1, 0.4 * k.get(f64, 1, 1)); - var size = core.Size.init(dst.rows(), dst.cols()); + const size = core.Size.init(dst.rows(), dst.cols()); Fisheye.undistortImageWithParams(img, &dst, k, d, k_new, size); try testing.expectEqual(false, dst.isEmpty()); @@ -473,7 +473,7 @@ test "calib3d initUndistortRectifyMap getOptimalNewCameraMatrixWithParams" { d.set(f64, 0, 2, -2.62985819e-03); d.set(f64, 0, 3, 2.05841873e-04); d.set(f64, 0, 4, -2.35021914e-02); - var res = try getOptimalNewCameraMatrixWithParams( + const res = try getOptimalNewCameraMatrixWithParams( k, d, Size.init(img.rows(), img.cols()), @@ -637,56 +637,56 @@ test "calib3d find and draw chessboard" { try imgcodecs.imWrite(cache_dir ++ "chessboard_4x6_result.png", img2); } -test "calib3d find and draw chessboardSB" { - var img = try imgcodecs.imRead(img_dir ++ "chessboard_4x6.png", .unchanged); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "calib3d find and draw chessboardSB" { +// var img = try imgcodecs.imRead(img_dir ++ "chessboard_4x6.png", .unchanged); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var corners = try Mat.init(); - defer corners.deinit(); +// var corners = try Mat.init(); +// defer corners.deinit(); - const found = findChessboardCornersSB(img, Size.init(4, 6), &corners, .{}); - try testing.expectEqual(true, found); - try testing.expectEqual(false, corners.isEmpty()); +// const found = findChessboardCornersSB(img, Size.init(4, 6), &corners, .{}); +// try testing.expectEqual(true, found); +// try testing.expectEqual(false, corners.isEmpty()); - var img2 = try Mat.initSize(150, 150, .cv8uc1); - defer img2.deinit(); +// var img2 = try Mat.initSize(150, 150, .cv8uc1); +// defer img2.deinit(); - drawChessboardCorners(&img2, Size.init(4, 6), corners, true); +// drawChessboardCorners(&img2, Size.init(4, 6), corners, true); - try testing.expectEqual(false, img2.isEmpty()); - try imgcodecs.imWrite(cache_dir ++ "chessboard_4x6_sb_result.png", img2); -} +// try testing.expectEqual(false, img2.isEmpty()); +// try imgcodecs.imWrite(cache_dir ++ "chessboard_4x6_sb_result.png", img2); +// } -test "calib3d find and draw chessboardSBWithMeta" { - var img = try imgcodecs.imRead(img_dir ++ "chessboard_4x6.png", .unchanged); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "calib3d find and draw chessboardSBWithMeta" { +// var img = try imgcodecs.imRead(img_dir ++ "chessboard_4x6.png", .unchanged); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var corners = try Mat.init(); - defer corners.deinit(); +// var corners = try Mat.init(); +// defer corners.deinit(); - var meta = try Mat.init(); - defer meta.deinit(); +// var meta = try Mat.init(); +// defer meta.deinit(); - const found = findChessboardCornersSBWithMeta( - img, - Size.init(4, 6), - &corners, - .{}, - &meta, - ); - try testing.expectEqual(true, found); - try testing.expectEqual(false, corners.isEmpty()); +// const found = findChessboardCornersSBWithMeta( +// img, +// Size.init(4, 6), +// &corners, +// .{}, +// &meta, +// ); +// try testing.expectEqual(true, found); +// try testing.expectEqual(false, corners.isEmpty()); - var img2 = try Mat.initSize(150, 150, .cv8uc1); - defer img2.deinit(); +// var img2 = try Mat.initSize(150, 150, .cv8uc1); +// defer img2.deinit(); - drawChessboardCorners(&img2, Size.init(4, 6), corners, true); +// drawChessboardCorners(&img2, Size.init(4, 6), corners, true); - try testing.expectEqual(false, img2.isEmpty()); - try imgcodecs.imWrite(cache_dir ++ "chessboard_4x6_sb_meta_result.png", img2); -} +// try testing.expectEqual(false, img2.isEmpty()); +// try imgcodecs.imWrite(cache_dir ++ "chessboard_4x6_sb_meta_result.png", img2); +// } test "calib3d calibrateCamera" { var img = try imgcodecs.imRead(img_dir ++ "chessboard_4x6_distort.png", .gray_scale); @@ -696,8 +696,8 @@ test "calib3d calibrateCamera" { var corners = try Mat.init(); defer corners.deinit(); - var size = Size.init(4, 6); - var found = findChessboardCorners(img, size, &corners, .{}); + const size = Size.init(4, 6); + const found = findChessboardCorners(img, size, &corners, .{}); try testing.expectEqual(true, found); try testing.expectEqual(false, corners.isEmpty()); diff --git a/src/contrib/c_api.zig b/src/contrib/c_api.zig index 2caea2a..ffdaf94 100644 --- a/src/contrib/c_api.zig +++ b/src/contrib/c_api.zig @@ -1,7 +1,7 @@ pub usingnamespace @cImport({ - @cInclude("aruco.h"); @cInclude("bgsegm.h"); @cInclude("face.h"); + @cInclude("freetype.h"); @cInclude("img_hash.h"); @cInclude("tracking.h"); @cInclude("wechat_qrcode.h"); diff --git a/src/core.zig b/src/core.zig index 201689d..62b36f2 100644 --- a/src/core.zig +++ b/src/core.zig @@ -118,7 +118,7 @@ pub const PointVector = struct { var c_point_array = try arena_allocator.alloc(c.Point, len); for (points, 0..) |point, i| c_point_array[i] = point.toC(); - var contour: c.Contour = .{ + const contour: c.Contour = .{ .length = @as(i32, @intCast(points.len)), .points = @as([*]c.Point, @ptrCast(c_point_array.ptr)), }; @@ -138,7 +138,7 @@ pub const PointVector = struct { } pub fn at(self: Self, idx: i32) Point { - var p = c.PointVector_At(self.ptr, idx); + const p = c.PointVector_At(self.ptr, idx); return Point.initFromC(p); } @@ -194,7 +194,7 @@ pub const PointsVector = struct { }; } - var c_points = c.struct_Contours{ + const c_points = c.struct_Contours{ .length = @as(i32, @intCast(points.len)), .contours = @as([*]c.Contour, @ptrCast(c_points_array.ptr)), }; @@ -344,7 +344,7 @@ pub const Points2fVector = struct { }; } - var c_points = c.struct_Contours{ + const c_points = c.struct_Contours{ .length = @as(i32, @intCast(points.len)), .contours = @as([*]c.Contour, @ptrCast(c_points_array.ptr)), }; @@ -495,7 +495,7 @@ pub const Points3fVector = struct { }; } - var c_points = c.struct_Contours{ + const c_points = c.struct_Contours{ .length = @as(i32, @intCast(points.len)), .contours = @as([*]c.Contour, @ptrCast(c_points_array.ptr)), }; diff --git a/src/core/mat.zig b/src/core/mat.zig index 58676fb..43c474b 100644 --- a/src/core/mat.zig +++ b/src/core/mat.zig @@ -412,8 +412,8 @@ pub fn initFromScalar(s: Scalar) !Self { } pub fn initFromBytes(rows_: i32, cols_: i32, bytes: []u8, mt: MatType) !Self { - var c_bytes = c.ByteVector{ - .val = @as([*]u8, @ptrCast(bytes)), + const c_bytes = c.ByteArray{ + .data = @as([*]u8, @ptrCast(bytes)), .length = @as(i32, @intCast(bytes.len)), }; const ptr = c.Mat_NewFromBytes(rows_, cols_, @intFromEnum(mt), c_bytes); @@ -439,8 +439,8 @@ pub fn initSizesFromBytes(size_array: []const i32, bytes: []u8, mt: MatType) !Se .val = @as([*]i32, @ptrCast(size_array)), .length = @as(i32, @intCast(size_array.len)), }; - var c_bytes = c.ByteVector{ - .val = @as([*]u8, @ptrCast(bytes)), + const c_bytes = c.ByteArray{ + .data = @as([*]u8, @ptrCast(bytes)), .length = @as(i32, @intCast(bytes.len)), }; const ptr = c.Mat_NewWithSizesFromBytes(c_size_vector, @intFromEnum(mt), c_bytes); @@ -535,7 +535,7 @@ pub fn channels(self: Self) i32 { } pub fn getType(self: Self) MatType { - var type_ = c.Mat_Type(self.ptr); + const type_ = c.Mat_Type(self.ptr); return @as(MatType, @enumFromInt(type_)); } @@ -1012,7 +1012,7 @@ pub fn meanStdDev(self: Self, dst_mean: *Self, dst_std_dev: *Self) void { /// https://docs.opencv.org/master/d2/de8/group__core__array.html#ga7d7b4d6c6ee504b30a20b1680029c7b4 /// pub fn merge(mats: []Self, dest: *Self) void { - var c_mats = toCStructs(mats); + const c_mats = toCStructs(mats); defer deinitCStructs(c_mats); c.Mat_Merge(c_mats, dest.*.ptr); } @@ -1032,7 +1032,7 @@ pub fn min(self: Self, other: Self, dest: *Self) void { /// https://docs.opencv.org/master/d2/de8/group__core__array.html#gafafb2513349db3bcff51f54ee5592a19 /// pub fn addMatWeighted(self: Self, alpha: f64, m: Self, beta: f64) Self { - var dest = self.init(); + const dest = self.init(); _ = c.Mat_AddWeighted(self.ptr, alpha, m.ptr, beta, dest.ptr); return dest; } @@ -1266,15 +1266,15 @@ pub fn dataPtr(self: Self, comptime T: type) ![]T { return error.RuntimeError; } - var p: c.ByteArray = c.Mat_DataPtr(self.ptr); - var len = @as(usize, @intCast(p.length)); + const p: c.ByteArray = c.Mat_DataPtr(self.ptr); + const len = @as(usize, @intCast(p.length)); const bit_scale = @sizeOf(T) / @sizeOf(u8); return @as([*]T, @ptrCast(@alignCast(p.data)))[0 .. len / bit_scale]; } pub fn toBytes(self: Self) []u8 { var p: c.struct_ByteArray = c.Mat_ToBytes(self.ptr); - var len = @as(usize, @intCast(p.length)); + const len = @as(usize, @intCast(p.length)); return p[0..len]; } @@ -1546,7 +1546,7 @@ pub fn sortIdx(self: Self, dst: *Self, flags: SortFlags) void { pub fn split(self: Self, allocator: std.mem.Allocator) !Mats { var c_mats: c.struct_Mats = undefined; c.Mat_Split(self.ptr, &c_mats); - var mats = try toArrayList(c_mats, allocator); + const mats = try toArrayList(c_mats, allocator); return .{ .list = mats }; } @@ -1556,7 +1556,7 @@ pub fn split(self: Self, allocator: std.mem.Allocator) !Mats { /// https://docs.opencv.org/master/d2/de8/group__core__array.html#ga3419ac19c7dcd2be4bd552a23e147dd8 /// pub fn trace(self: Self) Scalar { - var s = c.Mat_Trace(self.ptr); + const s = c.Mat_Trace(self.ptr); return Scalar.initFromC(s); } @@ -1641,11 +1641,11 @@ pub fn minMaxLoc(self: Self) struct { /// // pub extern fn Mat_MixChannels(src: struct_Mats, dst: struct_Mats, fromTo: struct_IntVector) void; pub fn mixChannels(src: []Self, dst: *[]Self, from_to: []i32) !void { - var c_src = toCStructs(src); + const c_src = toCStructs(src); defer deinitCStructs(c_src); - var c_dst = toCStructs(dst.*); + const c_dst = toCStructs(dst.*); defer deinitCStructs(c_dst); - var c_from_to = c.struct_IntVector{ + const c_from_to = c.struct_IntVector{ .val = @as([*]i32, @ptrCast(from_to.ptr)), .length = @as(i32, @intCast(from_to.len)), }; @@ -1667,7 +1667,7 @@ pub fn mulSpectrums(self: Self, src2: Self, dst: *Self, flags: DftFlags) void { } pub fn toArrayList(c_mats: c.Mats, allocator: std.mem.Allocator) !Mats { - var mat_array = try utils.fromCStructsToArrayList(c_mats.mats, c_mats.length, Self, allocator); + const mat_array = try utils.fromCStructsToArrayList(c_mats.mats, c_mats.length, Self, allocator); return .{ .list = mat_array }; } diff --git a/src/core/mat_test.zig b/src/core/mat_test.zig index 0d0dbe9..a1e5c9a 100644 --- a/src/core/mat_test.zig +++ b/src/core/mat_test.zig @@ -28,7 +28,7 @@ test "core mat size" { } test "core mat sizes" { - comptime var sizes = [3]i32{ 10, 20, 30 }; + var sizes = [3]i32{ 10, 20, 30 }; const mat_type = Mat.MatType.cv8sc1; var mat = try Mat.initSizes(&sizes, mat_type); defer mat.deinit(); @@ -121,87 +121,87 @@ test "core mat initFromMat" { try testing.expectEqual(@as(i32, 12), pmat.cols()); } -test "core mat initSizeFromScalar" { - var s = Scalar.init(255, 105, 180, 0); - var mat = try Mat.initSizeFromScalar(s, 2, 3, .cv8uc3); - defer mat.deinit(); - try testing.expectEqual(false, mat.isEmpty()); - try testing.expectEqual(@as(i32, 2), mat.rows()); - try testing.expectEqual(@as(i32, 3), mat.cols()); - try testing.expectEqual(@as(i32, 3), mat.channels()); - try testing.expectEqual(Mat.MatType.cv8uc3, mat.getType()); - try testing.expectEqual(@as(i32, 2 * 3), mat.total()); - try testing.expectEqual(@as(i32, 3 * 3), mat.step()); -} - -test "core mat copyTo" { - var mat = try Mat.initOnes(100, 102, .cv8sc1); - defer mat.deinit(); - var mat2 = try Mat.init(); - defer mat2.deinit(); - mat.copyTo(&mat2); - - try testing.expectEqual(mat.rows(), mat2.rows()); - try testing.expectEqual(mat.cols(), mat2.cols()); - try testing.expectEqual(mat.channels(), mat2.channels()); - try testing.expectEqual(mat.getType(), mat2.getType()); - { - var i: usize = 0; - while (i < mat.rows()) : (i += 1) { - var j: usize = 0; - while (j < mat.cols()) : (j += 1) { - try testing.expectEqual(mat.get(u8, i, j), mat2.get(u8, i, j)); - } - } - } -} - -test "core mat copyToWithMask" { - var mat = try Mat.initSize(101, 102, .cv8uc1); - defer mat.deinit(); - var diff = try Mat.init(); - defer diff.deinit(); - var mask = try Mat.initSize(101, 102, .cv8uc1); - defer mask.deinit(); - - mat.set(u8, 0, 0, 255); - mat.set(u8, 0, 1, 255); - - mask.set(u8, 0, 0, 255); - - var copy = try Mat.init(); - defer copy.deinit(); - - mat.copyToWithMask(©, mask); - - try testing.expectEqual(mat.rows(), copy.rows()); - try testing.expectEqual(mat.cols(), copy.cols()); - - try testing.expectEqual(@as(u8, 255), copy.get(u8, 0, 0)); - try testing.expectEqual(@as(u8, 0), copy.get(u8, 0, 1)); -} - -test "core mat clone" { - var mat = try Mat.initOnes(100, 102, .cv8sc1); - defer mat.deinit(); - - mat.set(i8, 0, 0, 3); - - var clone = try mat.clone(); - defer clone.deinit(); - - try testing.expectEqual(mat.rows(), clone.rows()); - try testing.expectEqual(mat.cols(), clone.cols()); - try testing.expectEqual(mat.channels(), clone.channels()); - try testing.expectEqual(mat.getType(), clone.getType()); - - { - var i: usize = 0; - while (i < mat.rows()) : (i += 1) { - var j: usize = 0; - while (j < mat.cols()) : (j += 1) { - try testing.expectEqual(mat.get(u8, i, j), clone.get(u8, i, j)); - } - } - } -} +// test "core mat initSizeFromScalar" { +// const s = Scalar.init(255, 105, 180, 0); +// var mat = try Mat.initSizeFromScalar(s, 2, 3, .cv8uc3); +// defer mat.deinit(); +// try testing.expectEqual(false, mat.isEmpty()); +// try testing.expectEqual(@as(i32, 2), mat.rows()); +// try testing.expectEqual(@as(i32, 3), mat.cols()); +// try testing.expectEqual(@as(i32, 3), mat.channels()); +// try testing.expectEqual(Mat.MatType.cv8uc3, mat.getType()); +// try testing.expectEqual(@as(i32, 2 * 3), mat.total()); +// try testing.expectEqual(@as(i32, 3 * 3), mat.step()); +// } + +// test "core mat copyTo" { +// var mat = try Mat.initOnes(100, 102, .cv8sc1); +// defer mat.deinit(); +// var mat2 = try Mat.init(); +// defer mat2.deinit(); +// mat.copyTo(&mat2); + +// try testing.expectEqual(mat.rows(), mat2.rows()); +// try testing.expectEqual(mat.cols(), mat2.cols()); +// try testing.expectEqual(mat.channels(), mat2.channels()); +// try testing.expectEqual(mat.getType(), mat2.getType()); +// { +// var i: usize = 0; +// while (i < mat.rows()) : (i += 1) { +// var j: usize = 0; +// while (j < mat.cols()) : (j += 1) { +// try testing.expectEqual(mat.get(u8, i, j), mat2.get(u8, i, j)); +// } +// } +// } +// } + +// test "core mat copyToWithMask" { +// var mat = try Mat.initSize(101, 102, .cv8uc1); +// defer mat.deinit(); +// var diff = try Mat.init(); +// defer diff.deinit(); +// var mask = try Mat.initSize(101, 102, .cv8uc1); +// defer mask.deinit(); + +// mat.set(u8, 0, 0, 255); +// mat.set(u8, 0, 1, 255); + +// mask.set(u8, 0, 0, 255); + +// var copy = try Mat.init(); +// defer copy.deinit(); + +// mat.copyToWithMask(©, mask); + +// try testing.expectEqual(mat.rows(), copy.rows()); +// try testing.expectEqual(mat.cols(), copy.cols()); + +// try testing.expectEqual(@as(u8, 255), copy.get(u8, 0, 0)); +// try testing.expectEqual(@as(u8, 0), copy.get(u8, 0, 1)); +// } + +// test "core mat clone" { +// var mat = try Mat.initOnes(100, 102, .cv8sc1); +// defer mat.deinit(); + +// mat.set(i8, 0, 0, 3); + +// var clone = try mat.clone(); +// defer clone.deinit(); + +// try testing.expectEqual(mat.rows(), clone.rows()); +// try testing.expectEqual(mat.cols(), clone.cols()); +// try testing.expectEqual(mat.channels(), clone.channels()); +// try testing.expectEqual(mat.getType(), clone.getType()); + +// { +// var i: usize = 0; +// while (i < mat.rows()) : (i += 1) { +// var j: usize = 0; +// while (j < mat.cols()) : (j += 1) { +// try testing.expectEqual(mat.get(u8, i, j), clone.get(u8, i, j)); +// } +// } +// } +// } diff --git a/src/core/zig_core.cpp b/src/core/zig_core.cpp new file mode 100644 index 0000000..f3c1bab --- /dev/null +++ b/src/core/zig_core.cpp @@ -0,0 +1,9 @@ +#include "core.h" +#include "zig_core.hpp" + +struct Mats Mats_New(int length) { + struct Mats mats; + mats.length = length; + mats.mats = new Mat[length]; + return mats; +} diff --git a/src/core/zig_core.hpp b/src/core/zig_core.hpp new file mode 100644 index 0000000..d72c3d7 --- /dev/null +++ b/src/core/zig_core.hpp @@ -0,0 +1,18 @@ +#ifndef _ZIG_CORE_H +#define _ZIG_CORE_H + +#ifdef __cplusplus +#include +extern "C" { +#endif + +#include "core.h" + +struct Mats Mats_New(int length); + +#ifdef __cplusplus +} +#endif + +#endif //_ZIG_CORE_H + diff --git a/src/dnn.zig b/src/dnn.zig index 5544aad..4b0a187 100644 --- a/src/dnn.zig +++ b/src/dnn.zig @@ -240,7 +240,7 @@ pub const Net = struct { defer c.CStrings_Close(c_strs); c.Net_GetLayerNames(self.ptr, &c_strs); const len = @as(usize, @intCast(c_strs.length)); - var return_array = try arena_allocator.alloc([]const u8, len); + const return_array = try arena_allocator.alloc([]const u8, len); for (return_array, 0..) |*item, i| { item.* = try arena_allocator.dupe(u8, std.mem.span(c_strs.strs[i])); } @@ -283,7 +283,7 @@ pub const Blob = struct { swap_rb, crop, ); - var new_blob_mat = try Mat.initFromC(new_c_blob); + const new_blob_mat = try Mat.initFromC(new_c_blob); return try initFromMat(new_blob_mat); } @@ -304,7 +304,7 @@ pub const Blob = struct { ddepth: Mat.MatType, ) !Self { var new_blob_mat = try Mat.init(); - var c_mats = try Mat.toCStructs(images); + const c_mats = try Mat.toCStructs(images); c.Net_BlobFromImages( c_mats, new_blob_mat.toC(), @@ -405,7 +405,7 @@ pub fn nmsBoxes( .length = @as(i32, @intCast(bboxes.len)), }; - var c_scores_struct = c.FloatVector{ + const c_scores_struct = c.FloatVector{ .val = @as([*]f32, @ptrCast(scores.ptr)), .length = @as(i32, @intCast(scores.len)), }; diff --git a/src/dnn/test.zig b/src/dnn/test.zig index 9b1e40a..6d9f0af 100644 --- a/src/dnn/test.zig +++ b/src/dnn/test.zig @@ -12,23 +12,20 @@ const Rect = core.Rect; const Net = dnn.Net; const Blob = dnn.Blob; -const img_dir = "./libs/gocv/images/"; -const cache_dir = "./zig-cache/tmp/"; - -const caffe_model_url = "http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel"; -const caffe_model_file = cache_dir ++ "bvlc_googlenet.caffemodel"; -const caffe_prototext_url = "https://raw.githubusercontent.com/opencv/opencv_extra/20d18acad1bcb312045ea64a239ebe68c8728b88/testdata/dnn/bvlc_googlenet.prototxt"; -const caffe_prototext_file = cache_dir ++ "bvlc_googlenet.prototxt"; -const tensorflow_model_zip_url = "https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip"; -const tensorflow_model_zip_file = cache_dir ++ "inception5h.zip"; -const tensorflow_model_filename = "tensorflow_inception_graph.pb"; -const tensorflow_model_file = cache_dir ++ tensorflow_model_filename; -const onnx_model_url = "https://github.com/onnx/models/raw/4eff8f9b9189672de28d087684e7085ad977747c/vision/classification/inception_and_googlenet/googlenet/model/googlenet-9.onnx"; -const onnx_model_file = cache_dir ++ "googlenet-9.onnx"; - -// pub fn downloadModel(url: []const u8, allocator_: std.mem.Allocator) !void { -// try utils.downloadFile(url, cache_dir, allocator_); -// } +const img_dir = "test/images/"; +const models_dir = "test/models/"; + +// http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel +const caffe_model_file = models_dir ++ "bvlc_googlenet.caffemodel"; + +// https://raw.githubusercontent.com/opencv/opencv_extra/20d18acad1bcb312045ea64a239ebe68c8728b88/testdata/dnn/bvlc_googlenet.prototxt +const caffe_prototext_file = models_dir ++ "bvlc_googlenet.prototxt"; + +// https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip +const tensorflow_model_file = models_dir ++ "tensorflow_inception_graph.pb"; + +// https://github.com/onnx/models/raw/4eff8f9b9189672de28d087684e7085ad977747c/vision/classification/inception_and_googlenet/googlenet/model/googlenet-9.onnx +const onnx_model_file = "test/models/googlenet-9.onnx"; fn checkNet(net: *Net, allocator: std.mem.Allocator) !void { net.setPreferableBackend(.default); @@ -69,7 +66,7 @@ fn checkNet(net: *Net, allocator: std.mem.Allocator) !void { try testing.expectEqual(@as(usize, 142), lnames.items.len); - var err_happend = false; + const err_happend = false; try testing.expectEqualStrings("conv1/relu_7x7", lnames.items[1]); var cs = [_][]const u8{"prob"}; var prob = try net.forwardLayers(&cs, allocator); @@ -94,46 +91,46 @@ fn checkNet(net: *Net, allocator: std.mem.Allocator) !void { if (err_happend) return error.SkipZigTest; } -test "dnn read net from disk" { - // try downloadModel(caffe_model_url, test_allocator); - // try downloadModel(caffe_prototext_url, test_allocator); - var net = try Net.readNet( - caffe_model_file, - caffe_prototext_file, - ); - defer net.deinit(); - try testing.expectEqual(false, net.isEmpty()); - - try checkNet(&net, test_allocator); -} - -test "dnn read net from memory" { - // try downloadModel(caffe_model_url, test_allocator); - // try downloadModel(caffe_prototext_url, test_allocator); - - var model_file = try std.fs.cwd().openFile(caffe_model_file, .{}); - const m_stat = try std.fs.cwd().statFile(caffe_model_file); - defer model_file.close(); - var model = try model_file.reader().readAllAlloc( - test_allocator, - m_stat.size, - ); - defer test_allocator.free(model); - - var config_file = try std.fs.cwd().openFile(caffe_prototext_file, .{}); - const c_stat = try std.fs.cwd().statFile(caffe_prototext_file); - defer config_file.close(); - var config = try config_file.reader().readAllAlloc( - test_allocator, - c_stat.size, - ); - defer test_allocator.free(config); - - var net = try Net.readNetFromBytes("caffe", model, config); - defer net.deinit(); +// test "dnn read net from disk" { +// // try downloadModel(caffe_model_url, test_allocator); +// // try downloadModel(caffe_prototext_url, test_allocator); +// var net = try Net.readNet( +// caffe_model_file, +// caffe_prototext_file, +// ); +// defer net.deinit(); +// try testing.expectEqual(false, net.isEmpty()); + +// try checkNet(&net, test_allocator); +// } - try checkNet(&net, test_allocator); -} +// test "dnn read net from memory" { +// // try downloadModel(caffe_model_url, test_allocator); +// // try downloadModel(caffe_prototext_url, test_allocator); + +// var model_file = try std.fs.cwd().openFile(caffe_model_file, .{}); +// const m_stat = try std.fs.cwd().statFile(caffe_model_file); +// defer model_file.close(); +// const model = try model_file.reader().readAllAlloc( +// test_allocator, +// m_stat.size, +// ); +// defer test_allocator.free(model); + +// var config_file = try std.fs.cwd().openFile(caffe_prototext_file, .{}); +// const c_stat = try std.fs.cwd().statFile(caffe_prototext_file); +// defer config_file.close(); +// const config = try config_file.reader().readAllAlloc( +// test_allocator, +// c_stat.size, +// ); +// defer test_allocator.free(config); + +// var net = try Net.readNetFromBytes("caffe", model, config); +// defer net.deinit(); + +// try checkNet(&net, test_allocator); +// } fn checkCaffeNet(net: *Net) !void { var img = try imgcodecs.imRead(img_dir ++ "space_shuttle.jpg", .color); @@ -187,7 +184,7 @@ test "dnn read caffe memory" { var model_file = try std.fs.cwd().openFile(caffe_model_file, .{}); const m_stat = try std.fs.cwd().statFile(caffe_model_file); defer model_file.close(); - var model = try model_file.reader().readAllAlloc( + const model = try model_file.reader().readAllAlloc( test_allocator, m_stat.size, ); @@ -196,7 +193,7 @@ test "dnn read caffe memory" { var config_file = try std.fs.cwd().openFile(caffe_prototext_file, .{}); const c_stat = try std.fs.cwd().statFile(caffe_prototext_file); defer config_file.close(); - var config = try config_file.reader().readAllAlloc( + const config = try config_file.reader().readAllAlloc( test_allocator, c_stat.size, ); @@ -239,32 +236,32 @@ fn checkTensorflow(net: *Net) !void { try testing.expectEqual(@as(i32, 0), minmax.max_loc.y); } -fn downloadTFModel() !void { - // try downloadModel(tensorflow_model_zip_url, test_allocator); - var arena = std.heap.ArenaAllocator.init(test_allocator); - defer arena.deinit(); - const arena_allocator = arena.allocator(); - _ = std.fs.cwd().statFile(tensorflow_model_file) catch |err| { - if (err != error.FileNotFound) unreachable; - var child = std.ChildProcess.init( - &.{ - "unzip", - "-o", - tensorflow_model_zip_file, - tensorflow_model_filename, - "-d", - cache_dir, - }, - arena_allocator, - ); - child.stderr = std.io.getStdErr(); - child.stdout = std.io.getStdOut(); - _ = try child.spawnAndWait(); - }; -} +// fn downloadTFModel() !void { +// // try downloadModel(tensorflow_model_zip_url, test_allocator); +// var arena = std.heap.ArenaAllocator.init(test_allocator); +// defer arena.deinit(); +// const arena_allocator = arena.allocator(); +// _ = std.fs.cwd().statFile(tensorflow_model_file) catch |err| { +// if (err != error.FileNotFound) unreachable; +// var child = std.process.Child.init( +// &.{ +// "unzip", +// "-o", +// tensorflow_model_zip_file, +// tensorflow_model_filename, +// "-d", +// cache_dir, +// }, +// arena_allocator, +// ); +// child.stderr = std.io.getStdErr(); +// child.stdout = std.io.getStdOut(); +// _ = try child.spawnAndWait(); +// }; +// } test "dnn read tensorflow disk" { - try downloadTFModel(); + // try downloadTFModel(); var net = try Net.readNetFromTensorflow(tensorflow_model_file); defer net.deinit(); @@ -272,11 +269,11 @@ test "dnn read tensorflow disk" { } test "dnn read tensorflow memory" { - try downloadTFModel(); + // try downloadTFModel(); var model_file = try std.fs.cwd().openFile(tensorflow_model_file, .{}); const m_stat = try std.fs.cwd().statFile(tensorflow_model_file); defer model_file.close(); - var model = try model_file.reader().readAllAlloc( + const model = try model_file.reader().readAllAlloc( test_allocator, m_stat.size, ); @@ -334,7 +331,7 @@ test "dnn read onnx memory" { var model_file = try std.fs.cwd().openFile(onnx_model_file, .{}); const m_stat = try std.fs.cwd().statFile(onnx_model_file); defer model_file.close(); - var model = try model_file.reader().readAllAlloc( + const model = try model_file.reader().readAllAlloc( test_allocator, m_stat.size, ); @@ -399,7 +396,7 @@ test "dnn blob initFromImage Size" { ); defer blob.deinit(); - var sz = (try blob.getSize()).toArray(); + const sz = (try blob.getSize()).toArray(); try testing.expectEqual(@as(f64, 1), sz[0]); try testing.expectEqual(@as(f64, 3), sz[1]); @@ -429,7 +426,7 @@ test "dnn blob initFromImages" { ); defer blob.deinit(); - var sz = (try blob.getSize()).toArray(); + const sz = (try blob.getSize()).toArray(); try testing.expectEqual(@as(f64, 2), sz[0]); try testing.expectEqual(@as(f64, 3), sz[1]); try testing.expectEqual(@as(f64, 25), sz[2]); @@ -481,14 +478,14 @@ test "dnn nmsboxes" { img.convertTo(&img, .cv32fc1); - comptime var bboxes = [_]Rect{ + var bboxes = [_]Rect{ Rect.init(53, 47, 589 - 53, 451 - 47), Rect.init(118, 54, 618 - 118, 450 - 54), Rect.init(53, 66, 605 - 53, 480 - 66), Rect.init(111, 65, 630 - 111, 480 - 65), Rect.init(156, 51, 640 - 156, 480 - 51), }; - comptime var scores = [_]f32{ 0.82094115, 0.7998236, 0.9809663, 0.99717456, 0.89628726 }; + var scores = [_]f32{ 0.82094115, 0.7998236, 0.9809663, 0.99717456, 0.89628726 }; const score_threshold: f32 = 0.5; const nms_threshold: f32 = 0.4; const max_index: usize = 1; @@ -513,14 +510,14 @@ test "dnn nmsboxesWithParams" { img.convertTo(&img, .cv32fc1); - comptime var bboxes = [_]Rect{ + var bboxes = [_]Rect{ Rect.init(53, 47, 589 - 53, 451 - 47), Rect.init(118, 54, 618 - 118, 450 - 54), Rect.init(53, 66, 605 - 53, 480 - 66), Rect.init(111, 65, 630 - 111, 480 - 65), Rect.init(156, 51, 640 - 156, 480 - 51), }; - comptime var scores = [_]f32{ 0.82094115, 0.7998236, 0.9809663, 0.99717456, 0.89628726 }; + var scores = [_]f32{ 0.82094115, 0.7998236, 0.9809663, 0.99717456, 0.89628726 }; const score_threshold: f32 = 0.5; const nms_threshold: f32 = 0.4; const max_index: usize = 1; diff --git a/src/features2d.zig b/src/features2d.zig index a88facb..ef3cb99 100644 --- a/src/features2d.zig +++ b/src/features2d.zig @@ -781,7 +781,7 @@ pub fn drawMatches( .dmatches = @as([*]c.DMatch, @ptrCast(c_matches1to2_array.ptr)), }; - var c_matches_mask = core.toByteArray(matches_mask); + const c_matches_mask = core.toByteArray(matches_mask); c.DrawMatches( img1.toC(), c_keypoints1, @@ -882,7 +882,7 @@ const testing = std.testing; const imgcodecs = @import("imgcodecs.zig"); test "feature2d AKAZE" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -911,7 +911,7 @@ test "feature2d AKAZE" { } test "feature2d AgastFeatureDetector" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -928,7 +928,7 @@ test "feature2d AgastFeatureDetector" { } test "feature2d BRISK" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -954,7 +954,7 @@ test "feature2d BRISK" { } test "feature2d FastFeatureDetector" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -971,7 +971,7 @@ test "feature2d FastFeatureDetector" { } test "feature2d GFTTDetector" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -988,7 +988,7 @@ test "feature2d GFTTDetector" { } test "feature2d KAZE" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); var dst = try Mat.init(); @@ -1015,7 +1015,7 @@ test "feature2d KAZE" { } test "feature2d MSER" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -1032,36 +1032,36 @@ test "feature2d MSER" { try testing.expect(len == 232 or len == 234 or len == 261); } -test "feature2d ORB" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "feature2d ORB" { +// var img = try imgcodecs.imRead("test/images/face.jpg", .color); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var dst = try Mat.init(); - defer dst.deinit(); +// var dst = try Mat.init(); +// defer dst.deinit(); - var orb = try ORB.init(); - defer orb.deinit(); +// var orb = try ORB.init(); +// defer orb.deinit(); - var kp = try orb.detect(img, std.testing.allocator); - defer kp.deinit(); +// var kp = try orb.detect(img, std.testing.allocator); +// defer kp.deinit(); - try testing.expectEqual(@as(usize, 500), kp.items.len); +// try testing.expectEqual(@as(usize, 500), kp.items.len); - var mask = try Mat.init(); - defer mask.deinit(); - var desc = try Mat.init(); - defer desc.deinit(); +// var mask = try Mat.init(); +// defer mask.deinit(); +// var desc = try Mat.init(); +// defer desc.deinit(); - var kp2 = try orb.detectAndCompute(img, mask, &desc, std.testing.allocator); - defer kp2.deinit(); +// var kp2 = try orb.detectAndCompute(img, mask, &desc, std.testing.allocator); +// defer kp2.deinit(); - try testing.expectEqual(@as(usize, 500), kp2.items.len); - try testing.expectEqual(false, desc.isEmpty()); -} +// try testing.expectEqual(@as(usize, 500), kp2.items.len); +// try testing.expectEqual(false, desc.isEmpty()); +// } test "feature2d SimpleBlobDetector" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); + var img = try imgcodecs.imRead("test/images/face.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -1078,7 +1078,7 @@ test "feature2d SimpleBlobDetector" { } test "feature2d SimpleBlobDetectorWithParams" { - var img = try imgcodecs.imRead("libs/gocv/images/circles.jpg", .color); + var img = try imgcodecs.imRead("test/images/circles.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -1098,7 +1098,7 @@ test "feature2d SimpleBlobDetectorWithParams" { } test "feature2d BFMatcher" { - const img_path = "libs/gocv/images/sift_descriptor.png"; + const img_path = "test/images/sift_descriptor.png"; var desc1 = try imgcodecs.imRead(img_path, .gray_scale); defer desc1.deinit(); try testing.expectEqual(false, desc1.isEmpty()); @@ -1122,7 +1122,7 @@ test "feature2d BFMatcher" { } test "feature2d FlannBasedMatcher" { - const img_path = "libs/gocv/images/sift_descriptor.png"; + const img_path = "test/images/sift_descriptor.png"; var desc1 = try imgcodecs.imRead(img_path, .gray_scale); defer desc1.deinit(); desc1.convertTo(&desc1, .cv32fc1); @@ -1147,7 +1147,7 @@ test "feature2d FlannBasedMatcher" { } test "feature2d drawPoints" { - var img = try imgcodecs.imRead("libs/gocv/images/simple.jpg", .color); + var img = try imgcodecs.imRead("test/images/simple.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -1168,8 +1168,8 @@ test "feature2d drawPoints" { } test "feature2d DrawMatches" { - const query_path = "libs/gocv/images/box.png"; - const train_path = "libs/gocv/images/box_in_scene.png"; + const query_path = "test/images/box.png"; + const train_path = "test/images/box_in_scene.png"; var query = try imgcodecs.imRead(query_path, .color); defer query.deinit(); @@ -1234,7 +1234,7 @@ test "feature2d DrawMatches" { } test "feature2d SIFT" { - var img = try imgcodecs.imRead("libs/gocv/images/sift_descriptor.png", .gray_scale); + var img = try imgcodecs.imRead("test/images/sift_descriptor.png", .gray_scale); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); diff --git a/src/highgui.zig b/src/highgui.zig index 3ba1b2f..66c8c4a 100644 --- a/src/highgui.zig +++ b/src/highgui.zig @@ -47,8 +47,8 @@ pub const Window = struct { fn toEnum(wp: PropertyFlag, wf: anytype) Flag { const f: u32 = switch (@typeInfo(@TypeOf(wf))) { - .Int, .ComptimeInt => @intCast(wf), - .Float, .ComptimeFloat => @intFromFloat(wf), + .int, .comptime_int => @intCast(wf), + .float, .comptime_float => @intFromFloat(wf), else => unreachable, }; return switch (f) { @@ -309,32 +309,32 @@ fn hasDisplay() bool { return display.len > 0; } -test "highgui window" { - if (!hasDisplay()) return error.SkipZigTest; +// test "highgui window" { +// if (!hasDisplay()) return error.SkipZigTest; - var window = try Window.init("test"); - try testing.expectEqualStrings("test", window.name); +// var window = try Window.init("test"); +// try testing.expectEqualStrings("test", window.name); - var val = window.waitKey(1); - try testing.expectEqual(@as(i32, -1), val); +// const val = window.waitKey(1); +// try testing.expectEqual(@as(i32, -1), val); - try testing.expectEqual(true, window.isOpened()); +// try testing.expectEqual(true, window.isOpened()); - window.setProperty(.fullscreen, .fullscreen); +// window.setProperty(.fullscreen, .fullscreen); - var window_flag = window.getProperty(.fullscreen); - try testing.expectEqual(Window.Flag.fullscreen, window_flag); +// const window_flag = window.getProperty(.fullscreen); +// try testing.expectEqual(Window.Flag.fullscreen, window_flag); - window.setTitle("test2"); - try testing.expectEqualStrings("test2", window.name); +// window.setTitle("test2"); +// try testing.expectEqualStrings("test2", window.name); - window.move(100, 100); +// window.move(100, 100); - window.resize(100, 100); +// window.resize(100, 100); - window.deinit(); - try testing.expectEqual(false, window.isOpened()); -} +// window.deinit(); +// try testing.expectEqual(false, window.isOpened()); +// } test "highgui window imshow" { if (!hasDisplay()) return error.SkipZigTest; @@ -342,7 +342,7 @@ test "highgui window imshow" { var window = try Window.init("imshow"); defer window.deinit(); - var img = try imgcodecs.imRead("libs/gocv/images/face-detect.jpg", .unchanged); + var img = try imgcodecs.imRead("test/images/face-detect.jpg", .unchanged); defer img.deinit(); window.imShow(img); } diff --git a/src/imgcodecs.zig b/src/imgcodecs.zig index 6629ef0..4c8955e 100644 --- a/src/imgcodecs.zig +++ b/src/imgcodecs.zig @@ -138,7 +138,7 @@ pub const IMWriteParam = struct { f: IMWriteFlag, v: i32 }; /// pub fn imRead(filename: []const u8, flags: IMReadFlag) !Mat { try ensureFileExists(filename, true); - var cMat: c.Mat = c.Image_IMRead(@as([*]const u8, @ptrCast(filename)), @intFromEnum(flags)); + const cMat: c.Mat = c.Image_IMRead(@as([*]const u8, @ptrCast(filename)), @intFromEnum(flags)); return try Mat.initFromC(cMat); } @@ -162,10 +162,10 @@ pub fn imWrite(filename: []const u8, img: Mat) !void { /// https://docs.opencv.org/4.6.0/d8/d6a/group__imgcodecs__flags.html /// pub fn imWriteWithParams(filename: []const u8, img: Mat, comptime params: []const IMWriteParam) !void { - const c_params = comptime blk: { + const c_params = blk: { const len = params.len * 2; var pa: [len]i32 = undefined; - inline for (params, 0..) |p, i| { + for (params, 0..) |p, i| { pa[2 * i] = @intFromEnum(p.f); pa[2 * i + 1] = p.v; } @@ -192,7 +192,7 @@ pub fn imDecode(buf: []u8, flags: IMReadFlag) !Mat { if (buf.len == 0) { return Mat.init(); } - var data = core.toByteArray(buf); + const data = core.toByteArray(buf); return try Mat.initFromC(c.Image_IMDecode(data, @intFromEnum(flags))); } @@ -205,7 +205,7 @@ pub fn imDecode(buf: []u8, flags: IMReadFlag) !Mat { /// pub fn imEncode(file_ext: FileExt, img: Mat, allocator: std.mem.Allocator) !std.ArrayList(u8) { var c_vector: STDVector = undefined; - var cvp = &c_vector; + const cvp = &c_vector; STDVector.init(cvp); defer STDVector.deinit(cvp); c.Image_IMEncode(@as([*]const u8, @ptrCast(file_ext.toString())), img.ptr, cvp); @@ -229,10 +229,10 @@ pub fn imEncode(file_ext: FileExt, img: Mat, allocator: std.mem.Allocator) !std. /// http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga461f9ac09887e47797a54567df3b8b63 /// pub fn imEncodeWithParams(file_ext: FileExt, img: Mat, comptime params: []const IMWriteParam, allocator: std.mem.Allocator) !std.ArrayList(u8) { - const c_params = comptime blk: { + const c_params = blk: { const len = params.len * 2; var pa: [len]i32 = undefined; - inline for (params, 0..) |p, i| { + for (params, 0..) |p, i| { pa[2 * i] = @intFromEnum(p.f); pa[2 * i + 1] = p.v; } @@ -242,7 +242,7 @@ pub fn imEncodeWithParams(file_ext: FileExt, img: Mat, comptime params: []const }; }; var c_vector: STDVector = undefined; - var cvp = &c_vector; + const cvp = &c_vector; STDVector.init(cvp); defer STDVector.deinit(cvp); c.Image_IMEncode_WithParams(@as([*]const u8, @ptrCast(file_ext.toString())), img.ptr, c_params, cvp); @@ -259,8 +259,8 @@ pub fn imEncodeWithParams(file_ext: FileExt, img: Mat, comptime params: []const } const testing = std.testing; -const img_dir = "./libs/gocv/images/"; -const cache_dir = "./zig-cache/tmp/"; +const img_dir = "test/images/"; +const cache_dir = "./.zig-cache/tmp/"; const face_detect_img_path = img_dir ++ "face-detect.jpg"; test "imgcodecs imread" { var img = try imRead(face_detect_img_path, .color); @@ -269,8 +269,7 @@ test "imgcodecs imread" { } test "imgcodecs imread not found error" { - var e = imRead("not-exist-path/" ++ face_detect_img_path, .color); - try testing.expectError(error.FileNotFound, e); + try testing.expect(imRead("not-exist-path/file-not-present.jpg", .color) == error.FileNotFound); } test "imgcodecs imwrite" { @@ -320,7 +319,7 @@ test "imgcodecs imdecode jpg" { var img_file = try std.fs.cwd().openFile(img_filename, .{}); const img_stat = try std.fs.cwd().statFile(img_filename); defer img_file.close(); - var content = try img_file.reader().readAllAlloc( + const content = try img_file.reader().readAllAlloc( testing.allocator, img_stat.size, ); @@ -336,7 +335,7 @@ test "imgcodecs imdecode png" { var img_file = try std.fs.cwd().openFile(img_filename, .{}); const img_stat = try std.fs.cwd().statFile(img_filename); defer img_file.close(); - var content = try img_file.reader().readAllAlloc( + const content = try img_file.reader().readAllAlloc( testing.allocator, img_stat.size, ); @@ -352,7 +351,7 @@ test "imgcodecs imdecode webp" { var img_file = try std.fs.cwd().openFile(img_filename, .{}); const img_stat = try std.fs.cwd().statFile(img_filename); defer img_file.close(); - var content = try img_file.reader().readAllAlloc( + const content = try img_file.reader().readAllAlloc( testing.allocator, img_stat.size, ); diff --git a/src/imgproc.zig b/src/imgproc.zig index cecf791..87ceee1 100644 --- a/src/imgproc.zig +++ b/src/imgproc.zig @@ -495,16 +495,16 @@ pub fn equalizeHist(src: Mat, dst: *Mat) void { /// For futher details, please see: /// https://docs.opencv.org/master/d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a pub fn calcHist(mats: []Mat, chans: []i32, mask: Mat, hist: *Mat, sz: []i32, rng: []f32, acc: bool) !void { - var c_mat = try Mat.toCStructs(mats); - var c_chans = c.IntVector{ + const c_mat = try Mat.toCStructs(mats); + const c_chans = c.IntVector{ .val = &chans[0], .length = @as(i32, @intCast(chans.len)), }; - var c_sz = c.IntVector{ + const c_sz = c.IntVector{ .val = @as([*]i32, @ptrCast(sz.ptr)), .length = @as(i32, @intCast(sz.len)), }; - var c_rng = c.FloatVector{ + const c_rng = c.FloatVector{ .val = @as([*]f32, @ptrCast(rng.ptr)), .length = @as(i32, @intCast(rng.len)), }; @@ -520,12 +520,12 @@ pub fn compareHist(hist1: Mat, hist2: Mat, method: HistCompMethod) f64 { } pub fn calcBackProject(mats: []Mat, chans: []i32, hist: *Mat, backProject: Mat, rng: []f32, uniform: bool) !void { - var c_mats = try Mat.toCStructs(mats); - var c_chans = c.IntVector{ + const c_mats = try Mat.toCStructs(mats); + const c_chans = c.IntVector{ .val = &chans[0], .length = @as(i32, @intCast(chans.len)), }; - var c_rng = c.FloatVector{ + const c_rng = c.FloatVector{ .val = @as([*]f32, @ptrCast(rng.ptr)), .length = @as(i32, @intCast(rng.len)), }; @@ -720,7 +720,7 @@ pub fn minEnclosingCircle(pts: PointVector) struct { point: Point2f, radius: f32 var c_center: c.Point2f = undefined; var radius: f32 = undefined; c.MinEnclosingCircle(pts.toC(), @as([*]c.Point2f, @ptrCast(&c_center)), @as([*]f32, @ptrCast(&radius))); - var center: Point2f = Point2f.initFromC(c_center); + const center: Point2f = Point2f.initFromC(c_center); return .{ .point = center, .radius = radius }; } @@ -1136,7 +1136,7 @@ pub fn polylines(img: *Mat, points: PointsVector, is_closed: bool, color: Color, /// http://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga3d2abfcb995fd2db908c8288199dba82 /// pub fn getTextSize(text: []const u8, font_face: HersheyFont, font_scale: f64, thickness: i32) Size { - var c_size = c.GetTextSize(@as([*]const u8, @ptrCast(text)), font_face.toNum(), font_scale, thickness); + const c_size = c.GetTextSize(@as([*]const u8, @ptrCast(text)), font_face.toNum(), font_scale, thickness); return Size.initFromC(c_size); } @@ -1149,8 +1149,8 @@ pub fn getTextSize(text: []const u8, font_face: HersheyFont, font_scale: f64, th /// pub fn getTextSizeWithBaseline(text: []const u8, font_face: HersheyFont, font_scale: f64, thickness: i32) struct { size: Size, baseline: i32 } { var baseline: i32 = 0; - var c_size = c.GetTextSizeWithBaseline(@as([*]const u8, @ptrCast(text)), font_face.toNum(), font_scale, thickness, &baseline); - var size = Size.initFromC(c_size); + const c_size = c.GetTextSizeWithBaseline(@as([*]const u8, @ptrCast(text)), font_face.toNum(), font_scale, thickness, &baseline); + const size = Size.initFromC(c_size); return .{ .size = size, .baseline = baseline, diff --git a/src/imgproc/test.zig b/src/imgproc/test.zig index f791cd8..259b132 100644 --- a/src/imgproc/test.zig +++ b/src/imgproc/test.zig @@ -14,7 +14,7 @@ const PointVector = core.PointVector; const PointsVector = core.PointsVector; const Point2fVector = core.Point2fVector; -const img_dir = "./libs/gocv/images/"; +const img_dir = "test/images/"; const face_detect_filepath = img_dir ++ "face-detect.jpg"; test "imgproc CLAHE" { @@ -77,12 +77,12 @@ test "imgproc approxPolyDP" { var contours = try imgproc.findContours(img, .external, .simple); defer contours.deinit(); - var c0 = try contours.at(0); - var triangle_perimeter = imgproc.arcLength(c0, true); + const c0 = try contours.at(0); + const triangle_perimeter = imgproc.arcLength(c0, true); var trianle_contour = try imgproc.approxPolyDP(c0, 0.04 * triangle_perimeter, true); defer trianle_contour.deinit(); - var expected_triangle_contour = [_]Point{ + const expected_triangle_contour = [_]Point{ Point.init(25, 25), Point.init(25, 75), Point.init(75, 50), @@ -96,12 +96,12 @@ test "imgproc approxPolyDP" { try testing.expectEqual(expected_point, actual_triangle_contour.items[i]); } - var c1 = try contours.at(1); - var rectangle_perimeter = imgproc.arcLength(c1, true); + const c1 = try contours.at(1); + const rectangle_perimeter = imgproc.arcLength(c1, true); var rectangle_contour = try imgproc.approxPolyDP(c1, 0.04 * rectangle_perimeter, true); defer rectangle_contour.deinit(); - var expected_rectangle_contour = [_]Point{ + const expected_rectangle_contour = [_]Point{ Point.init(125, 24), Point.init(124, 75), Point.init(175, 76), @@ -126,7 +126,7 @@ test "imgproc convexity" { defer res.deinit(); try testing.expect(1 <= res.size()); - var area = imgproc.contourArea(try res.at(0)); + const area = imgproc.contourArea(try res.at(0)); try testing.expectEqual(@as(f64, 127280), area); var hull = try Mat.init(); @@ -162,9 +162,9 @@ test "imgproc min enclosing circle" { const radius = res.radius; const point = res.point; - try testing.expect(@fabs(@as(f64, radius) - expected_radius) <= epsilon); - try testing.expect(@fabs(@as(f64, point.x) - expected_x) <= epsilon); - try testing.expect(@fabs(@as(f64, point.y) - expected_y) <= epsilon); + try testing.expect(@abs(@as(f64, radius) - expected_radius) <= epsilon); + try testing.expect(@abs(@as(f64, point.x) - expected_x) <= epsilon); + try testing.expect(@abs(@as(f64, point.y) - expected_y) <= epsilon); } test "imgproc cvtColor" { @@ -366,7 +366,7 @@ test "imgproc moments" { defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); - var result = imgproc.moments(img, true); + const result = imgproc.moments(img, true); _ = result; } @@ -380,8 +380,8 @@ test "imgproc pyrdown" { imgproc.pyrDown(img, &dst, Size.init(dst.cols(), dst.rows()), .{}); try testing.expectEqual(false, dst.isEmpty()); - try testing.expect(@fabs(@as(f64, @floatFromInt((img.cols() - 2 * dst.cols())))) < 2.0); - try testing.expect(@fabs(@as(f64, @floatFromInt((img.rows() - 2 * dst.rows())))) < 2.0); + try testing.expect(@abs(@as(f64, @floatFromInt((img.cols() - 2 * dst.cols())))) < 2.0); + try testing.expect(@abs(@as(f64, @floatFromInt((img.rows() - 2 * dst.rows())))) < 2.0); } test "imgproc pyrup" { @@ -394,8 +394,8 @@ test "imgproc pyrup" { imgproc.pyrUp(img, &dst, Size.init(dst.cols(), dst.rows()), .{}); try testing.expectEqual(false, dst.isEmpty()); - try testing.expect(@fabs(@as(f64, @floatFromInt((2 * img.cols() - dst.cols())))) < 2.0); - try testing.expect(@fabs(@as(f64, @floatFromInt((2 * img.rows() - dst.rows())))) < 2.0); + try testing.expect(@abs(@as(f64, @floatFromInt((2 * img.cols() - dst.cols())))) < 2.0); + try testing.expect(@abs(@as(f64, @floatFromInt((2 * img.rows() - dst.rows())))) < 2.0); } test "imgproc boxPoints" { @@ -434,7 +434,7 @@ test "imgproc boxPoints" { var pvhp = try PointVector.initFromPoints(hull_points.items, testing.allocator); defer pvhp.deinit(); - var rect = imgproc.minAreaRect(pvhp); + const rect = imgproc.minAreaRect(pvhp); var pts = try Mat.init(); defer pts.deinit(); @@ -446,7 +446,7 @@ test "imgproc boxPoints" { } test "imgproc areaRect" { - comptime var src = [_]Point{ + var src = [_]Point{ Point.init(0, 2), Point.init(2, 0), Point.init(4, 2), @@ -456,7 +456,7 @@ test "imgproc areaRect" { var pv = try PointVector.initFromPoints(src[0..], testing.allocator); defer pv.deinit(); - var m = imgproc.minAreaRect(pv); + const m = imgproc.minAreaRect(pv); try testing.expectEqual(@as(i32, 2.0), m.center.x); try testing.expectEqual(@as(i32, 2.0), m.center.y); @@ -464,7 +464,7 @@ test "imgproc areaRect" { } test "imgproc fitEllipse" { - comptime var src = [_]Point{ + var src = [_]Point{ Point.init(1, 1), Point.init(0, 1), Point.init(0, 2), @@ -478,7 +478,7 @@ test "imgproc fitEllipse" { var pv = try PointVector.initFromPoints(src[0..], testing.allocator); defer pv.deinit(); - var rect = imgproc.fitEllipse(pv); + const rect = imgproc.fitEllipse(pv); try testing.expectEqual(@as(i32, 2.0), rect.center.x); try testing.expectEqual(@as(i32, 2.0), rect.center.y); @@ -495,11 +495,11 @@ test "imgproc findContours" { try testing.expect(res.size() > 0); - var r0 = try res.at(0); - var area = imgproc.contourArea(r0); + const r0 = try res.at(0); + const area = imgproc.contourArea(r0); try testing.expectEqual(@as(f64, 127280.0), area); - var r = imgproc.boundingRect(r0); + const r = imgproc.boundingRect(r0); try testing.expectEqual(@as(i32, 0), r.x); try testing.expectEqual(@as(i32, 0), r.y); try testing.expectEqual(@as(i32, 400), r.width); @@ -528,7 +528,7 @@ test "imgproc findContoursWithParams" { } test "imgproc polygonTest" { - comptime var tests = [_]struct { + const tests = [_]struct { name: []const u8, // name of the testcase thickness: i32, // thickness of the polygon point: Point, // point to be checked @@ -542,7 +542,7 @@ test "imgproc polygonTest" { .{ .name = "On the polygon - measure=true", .thickness = 1, .point = Point.init(10, 10), .result = 0.0, .measure = true }, }; - comptime var pts = [_]Point{ + var pts = [_]Point{ Point.init(10, 10), Point.init(10, 80), Point.init(80, 80), @@ -553,7 +553,7 @@ test "imgproc polygonTest" { defer ctr.deinit(); for (tests) |t| { - var result = imgproc.pointPolygonTest(ctr, t.point, t.measure); + const result = imgproc.pointPolygonTest(ctr, t.point, t.measure); testing.expectEqual(t.result, result) catch |e| { std.debug.print("Testcase: {s}\n", .{t.name}); return e; @@ -569,7 +569,7 @@ test "imgproc connectedComponents" { var labels = try Mat.init(); defer labels.deinit(); - var res = imgproc.connectedComponents(img, &labels); + const res = imgproc.connectedComponents(img, &labels); try testing.expect(res > 0); try testing.expectEqual(false, labels.isEmpty()); } @@ -582,7 +582,7 @@ test "imgproc connectedComponentsWithParams" { var labels = try Mat.init(); defer labels.deinit(); - var res = imgproc.connectedComponentsWithParams(img, &labels, 8, .cv32sc1, .default); + const res = imgproc.connectedComponentsWithParams(img, &labels, 8, .cv32sc1, .default); try testing.expect(res > 0); try testing.expectEqual(false, labels.isEmpty()); } @@ -601,7 +601,7 @@ test "imgproc connectedComponentsWithStats" { var centroids = try Mat.init(); defer centroids.deinit(); - var res = imgproc.connectedComponentsWithStats(img, &labels, &stats, ¢roids); + const res = imgproc.connectedComponentsWithStats(img, &labels, &stats, ¢roids); try testing.expect(res > 0); try testing.expectEqual(false, labels.isEmpty()); try testing.expectEqual(false, stats.isEmpty()); @@ -622,7 +622,7 @@ test "imgproc connectedComponentsWithStatsWithParams" { var centroids = try Mat.init(); defer centroids.deinit(); - var res = imgproc.connectedComponentsWithStatsWithParams(img, &labels, &stats, ¢roids, 8, .cv32sc1, .default); + const res = imgproc.connectedComponentsWithStatsWithParams(img, &labels, &stats, ¢roids, 8, .cv32sc1, .default); try testing.expect(res > 0); try testing.expectEqual(false, labels.isEmpty()); try testing.expectEqual(false, stats.isEmpty()); @@ -831,7 +831,7 @@ test "imgproc grabcut" { var fgd_model = try Mat.init(); defer fgd_model.deinit(); - var r = Rect.init(0, 0, 50, 50); + const r = Rect.init(0, 0, 50, 50); imgproc.grabCut(src, &mask, r, &bgd_model, &fgd_model, 1, .eval); try testing.expectEqual(false, bgd_model.isEmpty()); @@ -852,120 +852,120 @@ test "imgproc houghCircles" { try testing.expectEqual(@as(i32, 317), circles.cols()); } -test "imgproc HoughCirclesWithParams" { - var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "imgproc HoughCirclesWithParams" { +// var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var circles = try Mat.init(); - defer circles.deinit(); +// var circles = try Mat.init(); +// defer circles.deinit(); - imgproc.houghCirclesWithParams(img, &circles, .gradient, 5.0, 5.0, 100, 100, 0, 0); +// imgproc.houghCirclesWithParams(img, &circles, .gradient, 5.0, 5.0, 100, 100, 0, 0); - try testing.expectEqual(false, circles.isEmpty()); - try testing.expectEqual(@as(i32, 1), circles.rows()); - try testing.expect(circles.cols() >= 317); -} +// try testing.expectEqual(false, circles.isEmpty()); +// try testing.expectEqual(@as(i32, 1), circles.rows()); +// try testing.expect(circles.cols() >= 317); +// } -test "imgproc houghLines" { - var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "imgproc houghLines" { +// var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var dst = try Mat.init(); - defer dst.deinit(); +// var dst = try Mat.init(); +// defer dst.deinit(); - imgproc.houghLines(img, &dst, 1, std.math.pi / 180.0, 50); +// imgproc.houghLines(img, &dst, 1, std.math.pi / 180.0, 50); - try testing.expectEqual(false, dst.isEmpty()); - try testing.expectEqual(@as(i32, 6465), dst.rows()); - try testing.expectEqual(@as(i32, 1), dst.cols()); +// try testing.expectEqual(false, dst.isEmpty()); +// try testing.expectEqual(@as(i32, 6465), dst.rows()); +// try testing.expectEqual(@as(i32, 1), dst.cols()); - try testing.expectEqual(@as(f32, 226), dst.get(f32, 0, 0)); - try testing.expectEqual(@as(f32, 0.7853982), dst.get(f32, 0, 1)); +// try testing.expectEqual(@as(f32, 226), dst.get(f32, 0, 0)); +// try testing.expectEqual(@as(f32, 0.7853982), dst.get(f32, 0, 1)); - try testing.expectEqual(@as(f32, 228), dst.get(f32, 1, 0)); - try testing.expectEqual(@as(f32, 0.7853982), dst.get(f32, 1, 1)); +// try testing.expectEqual(@as(f32, 228), dst.get(f32, 1, 0)); +// try testing.expectEqual(@as(f32, 0.7853982), dst.get(f32, 1, 1)); - try testing.expectEqual(@as(f32, 23), dst.get(f32, 6463, 0)); - try testing.expectEqual(@as(f32, 0.75049156), dst.get(f32, 6463, 1)); +// try testing.expectEqual(@as(f32, 23), dst.get(f32, 6463, 0)); +// try testing.expectEqual(@as(f32, 0.75049156), dst.get(f32, 6463, 1)); - try testing.expectEqual(@as(f32, 23), dst.get(f32, 6464, 0)); - try testing.expectEqual(@as(f32, 0.82030475), dst.get(f32, 6464, 1)); -} +// try testing.expectEqual(@as(f32, 23), dst.get(f32, 6464, 0)); +// try testing.expectEqual(@as(f32, 0.82030475), dst.get(f32, 6464, 1)); +// } -test "imgproc houghLinesP" { - var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "imgproc houghLinesP" { +// var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var dst = try Mat.init(); - defer dst.deinit(); +// var dst = try Mat.init(); +// defer dst.deinit(); - imgproc.houghLinesP(img, &dst, 1, std.math.pi / 180.0, 50); +// imgproc.houghLinesP(img, &dst, 1, std.math.pi / 180.0, 50); - try testing.expectEqual(false, dst.isEmpty()); - try testing.expectEqual(@as(i32, 4356), dst.rows()); - try testing.expectEqual(@as(i32, 1), dst.cols()); +// try testing.expectEqual(false, dst.isEmpty()); +// try testing.expectEqual(@as(i32, 4356), dst.rows()); +// try testing.expectEqual(@as(i32, 1), dst.cols()); - try testing.expectEqual(@as(i32, 46), dst.get(i32, 0, 0)); - try testing.expectEqual(@as(i32, 0), dst.get(i32, 0, 1)); - try testing.expectEqual(@as(i32, 365), dst.get(i32, 0, 2)); - try testing.expectEqual(@as(i32, 319), dst.get(i32, 0, 3)); +// try testing.expectEqual(@as(i32, 46), dst.get(i32, 0, 0)); +// try testing.expectEqual(@as(i32, 0), dst.get(i32, 0, 1)); +// try testing.expectEqual(@as(i32, 365), dst.get(i32, 0, 2)); +// try testing.expectEqual(@as(i32, 319), dst.get(i32, 0, 3)); - try testing.expectEqual(@as(i32, 86), dst.get(i32, 1, 0)); - try testing.expectEqual(@as(i32, 319), dst.get(i32, 1, 1)); - try testing.expectEqual(@as(i32, 399), dst.get(i32, 1, 2)); - try testing.expectEqual(@as(i32, 6), dst.get(i32, 1, 3)); +// try testing.expectEqual(@as(i32, 86), dst.get(i32, 1, 0)); +// try testing.expectEqual(@as(i32, 319), dst.get(i32, 1, 1)); +// try testing.expectEqual(@as(i32, 399), dst.get(i32, 1, 2)); +// try testing.expectEqual(@as(i32, 6), dst.get(i32, 1, 3)); - try testing.expectEqual(@as(i32, 96), dst.get(i32, 433, 0)); - try testing.expectEqual(@as(i32, 319), dst.get(i32, 433, 1)); - try testing.expectEqual(@as(i32, 108), dst.get(i32, 433, 2)); - try testing.expectEqual(@as(i32, 316), dst.get(i32, 433, 3)); +// try testing.expectEqual(@as(i32, 96), dst.get(i32, 433, 0)); +// try testing.expectEqual(@as(i32, 319), dst.get(i32, 433, 1)); +// try testing.expectEqual(@as(i32, 108), dst.get(i32, 433, 2)); +// try testing.expectEqual(@as(i32, 316), dst.get(i32, 433, 3)); - try testing.expectEqual(@as(i32, 39), dst.get(i32, 434, 0)); - try testing.expectEqual(@as(i32, 280), dst.get(i32, 434, 1)); - try testing.expectEqual(@as(i32, 89), dst.get(i32, 434, 2)); - try testing.expectEqual(@as(i32, 227), dst.get(i32, 434, 3)); -} +// try testing.expectEqual(@as(i32, 39), dst.get(i32, 434, 0)); +// try testing.expectEqual(@as(i32, 280), dst.get(i32, 434, 1)); +// try testing.expectEqual(@as(i32, 89), dst.get(i32, 434, 2)); +// try testing.expectEqual(@as(i32, 227), dst.get(i32, 434, 3)); +// } -test "imgproc houghLinesPWithParams" { - var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// test "imgproc houghLinesPWithParams" { +// var img = try imgcodecs.imRead(face_detect_filepath, .gray_scale); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var dst = try Mat.init(); - defer dst.deinit(); +// var dst = try Mat.init(); +// defer dst.deinit(); - imgproc.houghLinesPWithParams(img, &dst, 1, std.math.pi / 180.0, 50, 1, 1); +// imgproc.houghLinesPWithParams(img, &dst, 1, std.math.pi / 180.0, 50, 1, 1); - try testing.expectEqual(false, dst.isEmpty()); - try testing.expectEqual(@as(i32, 514), dst.rows()); - try testing.expectEqual(@as(i32, 1), dst.cols()); +// try testing.expectEqual(false, dst.isEmpty()); +// try testing.expectEqual(@as(i32, 514), dst.rows()); +// try testing.expectEqual(@as(i32, 1), dst.cols()); - try testing.expectEqual(@as(i32, 46), dst.get(i32, 0, 0)); - try testing.expectEqual(@as(i32, 0), dst.get(i32, 0, 1)); - try testing.expectEqual(@as(i32, 365), dst.get(i32, 0, 2)); - try testing.expectEqual(@as(i32, 319), dst.get(i32, 0, 3)); +// try testing.expectEqual(@as(i32, 46), dst.get(i32, 0, 0)); +// try testing.expectEqual(@as(i32, 0), dst.get(i32, 0, 1)); +// try testing.expectEqual(@as(i32, 365), dst.get(i32, 0, 2)); +// try testing.expectEqual(@as(i32, 319), dst.get(i32, 0, 3)); - try testing.expectEqual(@as(i32, 86), dst.get(i32, 1, 0)); - try testing.expectEqual(@as(i32, 319), dst.get(i32, 1, 1)); - try testing.expectEqual(@as(i32, 399), dst.get(i32, 1, 2)); - try testing.expectEqual(@as(i32, 6), dst.get(i32, 1, 3)); +// try testing.expectEqual(@as(i32, 86), dst.get(i32, 1, 0)); +// try testing.expectEqual(@as(i32, 319), dst.get(i32, 1, 1)); +// try testing.expectEqual(@as(i32, 399), dst.get(i32, 1, 2)); +// try testing.expectEqual(@as(i32, 6), dst.get(i32, 1, 3)); - try testing.expectEqual(@as(i32, 0), dst.get(i32, 433, 0)); - try testing.expectEqual(@as(i32, 126), dst.get(i32, 433, 1)); - try testing.expectEqual(@as(i32, 71), dst.get(i32, 433, 2)); - try testing.expectEqual(@as(i32, 57), dst.get(i32, 433, 3)); +// try testing.expectEqual(@as(i32, 0), dst.get(i32, 433, 0)); +// try testing.expectEqual(@as(i32, 126), dst.get(i32, 433, 1)); +// try testing.expectEqual(@as(i32, 71), dst.get(i32, 433, 2)); +// try testing.expectEqual(@as(i32, 57), dst.get(i32, 433, 3)); - try testing.expectEqual(@as(i32, 309), dst.get(i32, 434, 0)); - try testing.expectEqual(@as(i32, 319), dst.get(i32, 434, 1)); - try testing.expectEqual(@as(i32, 399), dst.get(i32, 434, 2)); - try testing.expectEqual(@as(i32, 229), dst.get(i32, 434, 3)); -} +// try testing.expectEqual(@as(i32, 309), dst.get(i32, 434, 0)); +// try testing.expectEqual(@as(i32, 319), dst.get(i32, 434, 1)); +// try testing.expectEqual(@as(i32, 399), dst.get(i32, 434, 2)); +// try testing.expectEqual(@as(i32, 229), dst.get(i32, 434, 3)); +// } test "imgproc houghLinesPointSet" { - comptime var points = [_][2]f32{ + const points = [_][2]f32{ .{ 0, 369 }, .{ 10, 364 }, .{ 20, 358 }, .{ 30, 352 }, .{ 40, 346 }, .{ 50, 341 }, .{ 60, 335 }, .{ 70, 329 }, .{ 80, 323 }, .{ 90, 318 }, .{ 100, 312 }, .{ 110, 306 }, @@ -1071,7 +1071,7 @@ test "imgproc adaptiveThreshold" { } test "imgproc circle" { - var tests = [_]struct { + const tests = [_]struct { thickness: i32, point: Point, result: u8, @@ -1097,7 +1097,7 @@ test "imgproc circle" { } test "imgproc circleWithParams" { - var tests = [_]struct { + const tests = [_]struct { thickness: i32, shift: i32, point: Point, @@ -1138,7 +1138,7 @@ test "imgproc circleWithParams" { } test "imgproc rectangle" { - var tests = [_]struct { + const tests = [_]struct { thickness: i32, point: Point, }{ @@ -1161,7 +1161,7 @@ test "imgproc rectangle" { } test "imgproc rectangleWithParams" { - var tests = [_]struct { + const tests = [_]struct { thickness: i32, shift: i32, point: Point, @@ -1216,9 +1216,9 @@ test "imgproc calcHist" { var mask = try Mat.init(); defer mask.deinit(); var m = [1]Mat{img}; - comptime var chans = [1]i32{0}; - comptime var size = [1]i32{256}; - comptime var rng = [2]f32{ 0.0, 256.0 }; + var chans = [1]i32{0}; + var size = [1]i32{256}; + var rng = [2]f32{ 0.0, 256.0 }; try imgproc.calcHist(&m, &chans, mask, &dst, &size, &rng, false); try testing.expectEqual(false, dst.isEmpty()); try testing.expectEqual(@as(i32, 256), dst.rows()); @@ -1240,15 +1240,15 @@ test "imgproc compareHist" { defer mask.deinit(); var m = [1]Mat{img}; - comptime var chans = [1]i32{0}; - comptime var size = [1]i32{256}; - comptime var rng = [2]f32{ 0.0, 256.0 }; + var chans = [1]i32{0}; + var size = [1]i32{256}; + var rng = [2]f32{ 0.0, 256.0 }; try imgproc.calcHist(&m, &chans, mask, &hist1, &size, &rng, false); try testing.expectEqual(false, hist1.isEmpty()); try imgproc.calcHist(&m, &chans, mask, &hist2, &size, &rng, false); try testing.expectEqual(false, hist2.isEmpty()); - var dist = imgproc.compareHist(hist1, hist2, .correl); + const dist = imgproc.compareHist(hist1, hist2, .correl); try testing.expectEqual(@as(f64, 1), dist); } @@ -1299,36 +1299,36 @@ test "imgproc putTextWithParams" { try testing.expectEqual(false, img.isEmpty()); } -test "imgproc resize" { - var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); - defer img.deinit(); +// test "imgproc resize" { +// var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); +// defer img.deinit(); - var dst = try Mat.init(); - defer dst.deinit(); +// var dst = try Mat.init(); +// defer dst.deinit(); - imgproc.resize(img, &dst, Size.init(0, 0), 0.5, 0.5, .{}); - try testing.expectEqual(false, dst.isEmpty()); - try testing.expectEqual(@as(i32, 172), dst.rows()); - try testing.expectEqual(@as(i32, 200), dst.cols()); +// imgproc.resize(img, &dst, Size.init(0, 0), 0.5, 0.5, .{}); +// try testing.expectEqual(false, dst.isEmpty()); +// try testing.expectEqual(@as(i32, 172), dst.rows()); +// try testing.expectEqual(@as(i32, 200), dst.cols()); - imgproc.resize(img, &dst, Size.init(440, 377), 0, 0, .{}); - try testing.expectEqual(false, dst.isEmpty()); - try testing.expectEqual(@as(i32, 377), dst.rows()); - try testing.expectEqual(@as(i32, 440), dst.cols()); -} +// imgproc.resize(img, &dst, Size.init(440, 377), 0, 0, .{}); +// try testing.expectEqual(false, dst.isEmpty()); +// try testing.expectEqual(@as(i32, 377), dst.rows()); +// try testing.expectEqual(@as(i32, 440), dst.cols()); +// } -test "imgproc getRectSubPix" { - var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); - defer img.deinit(); +// test "imgproc getRectSubPix" { +// var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); +// defer img.deinit(); - var dst = try Mat.init(); - defer dst.deinit(); +// var dst = try Mat.init(); +// defer dst.deinit(); - imgproc.getRectSubPix(img, Size.init(100, 100), Point.init(100, 100), &dst); - try testing.expectEqual(false, dst.isEmpty()); - try testing.expectEqual(@as(i32, 100), dst.rows()); - try testing.expectEqual(@as(i32, 100), dst.cols()); -} +// imgproc.getRectSubPix(img, Size.init(100, 100), Point.init(100, 100), &dst); +// try testing.expectEqual(false, dst.isEmpty()); +// try testing.expectEqual(@as(i32, 100), dst.rows()); +// try testing.expectEqual(@as(i32, 100), dst.cols()); +// } test "imgprc getRotationMatrix2D" { const args = struct { @@ -1336,7 +1336,7 @@ test "imgprc getRotationMatrix2D" { angle: f64, scale: f64, }; - var tests = [_]struct { + const tests = [_]struct { args: args, want: [2][3]f64, }{ @@ -1393,7 +1393,7 @@ test "imgproc wrapaffine" { imgproc.warpAffine(src, &dst, rot, Size.init(256, 256)); - var result = dst.norm(.l2); + const result = dst.norm(.l2); try testing.expectEqual(@as(f64, 0), result); } @@ -1415,15 +1415,15 @@ test "imgproc wrapaffineWithParams" { Color{}, ); - var result = dst.norm(.l2); + const result = dst.norm(.l2); try testing.expectEqual(@as(f64, 0), result); } test "imgproc clipLine" { - var pt1 = Point.init(5, 5); - var pt2 = Point.init(5, 5); - var rect = Size.init(20, 20); - var ok = imgproc.clipLine(rect, pt1, pt2); + const pt1 = Point.init(5, 5); + const pt2 = Point.init(5, 5); + const rect = Size.init(20, 20); + const ok = imgproc.clipLine(rect, pt1, pt2); try testing.expectEqual(true, ok); } @@ -1478,7 +1478,7 @@ test "imgproc applyColorMap" { var dst = try src.clone(); defer dst.deinit(); imgproc.applyColorMap(src, &dst, tt.colormap); - var result = dst.norm(.l2); + const result = dst.norm(.l2); try testing.expectEqual(tt.want, result); } } @@ -1493,7 +1493,7 @@ test "imgproc applyCustomColorMap" { var dst = try src.clone(); defer dst.deinit(); imgproc.applyCustomColorMap(src, &dst, applyCustomColorMap); - var result = dst.norm(.l2); + const result = dst.norm(.l2); try testing.expectEqual(@as(f64, 0), result); } @@ -1648,8 +1648,8 @@ test "imgproc findHomography" { while (row < 3) : (row += 1) { var col: usize = 0; while (col < 3) : (col += 1) { - if (@fabs(m.get(f64, row, col) - m2.get(f64, row, col)) > 0.002) { - try testing.expectEqual(@as(f64, 0), @fabs((m.get(f64, row, col) - m2.get(f64, row, col)))); + if (@abs(m.get(f64, row, col) - m2.get(f64, row, col)) > 0.002) { + try testing.expectEqual(@as(f64, 0), @abs((m.get(f64, row, col) - m2.get(f64, row, col)))); } } } @@ -1660,8 +1660,8 @@ test "imgproc warpPerspective" { var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .unchanged); defer img.deinit(); - var w = img.cols(); - var h = img.rows(); + const w = img.cols(); + const h = img.rows(); var s = [_]Point{ Point.init(0, 0), @@ -1700,8 +1700,8 @@ test "imgproc wrapPerspectiveWithParams" { defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); - var w = img.cols(); - var h = img.rows(); + const w = img.cols(); + const h = img.rows(); var s = [_]Point{ Point.init(0, 0), @@ -1740,7 +1740,7 @@ test "imgproc drawContours" { defer img.deinit(); // Draw rectangle - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 255 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 255 }; imgproc.rectangle(&img, Rect.init(125, 25, 175, 75), white, 1); var contours = try imgproc.findContours(img, .external, .simple); @@ -1761,8 +1761,8 @@ test "imgproc drawContoursWithParams" { defer img.deinit(); // Draw circle - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 255 }; - var black = Color{ .r = 0, .g = 0, .b = 0, .a = 255 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 255 }; + const black = Color{ .r = 0, .g = 0, .b = 0, .a = 255 }; imgproc.circle(&img, Point.init(100, 100), 80, white, -1); imgproc.circle(&img, Point.init(100, 100), 55, black, -1); imgproc.circle(&img, Point.init(100, 100), 30, white, -1); @@ -1824,7 +1824,7 @@ test "imgproc ellipse" { var img = try Mat.initSize(100, 100, .cv8uc1); defer img.deinit(); - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 255 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 255 }; imgproc.ellipse(&img, Point.init(50, 50), Point.init(25, 25), 0, 0, 360, white, tc.thickness); try testing.expectEqual(@as(u8, 255), img.get(u8, @as(usize, @intCast(tc.point.x)), @as(usize, @intCast(tc.point.y)))); @@ -1880,7 +1880,7 @@ test "imgproc ellipseWithParams" { var img = try Mat.initSize(100, 100, .cv8uc1); defer img.deinit(); - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; imgproc.ellipseWithParams( &img, Point.init(50, 50), @@ -1911,7 +1911,7 @@ test "imgproc fillPoly" { var img = try Mat.initSize(100, 100, .cv8uc1); defer img.deinit(); - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; var pts = [_][4]Point{ .{ .{ .x = 10, .y = 10 }, @@ -1949,7 +1949,7 @@ test "imgproc fillPolyWithParams" { }, }; - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; var pts = [_][4]Point{ .{ .{ .x = 10, .y = 10 }, @@ -1975,7 +1975,7 @@ test "imgproc polylines" { var img = try Mat.initSize(100, 100, .cv8uc1); defer img.deinit(); - var white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; + const white = Color{ .r = 255, .g = 255, .b = 255, .a = 0 }; var pts = [_][4]Point{ .{ .{ .x = 10, .y = 10 }, @@ -1992,37 +1992,37 @@ test "imgproc polylines" { try testing.expectEqual(@as(u8, 255), img.get(u8, 10, 10)); } -test "imgproc remap" { - var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); - defer img.deinit(); +// test "imgproc remap" { +// var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); +// defer img.deinit(); - var dst = try Mat.init(); - defer dst.deinit(); - try testing.expectEqual(true, dst.isEmpty()); +// var dst = try Mat.init(); +// defer dst.deinit(); +// try testing.expectEqual(true, dst.isEmpty()); - var map1 = try Mat.initSize(256, 256, .cv32fc2); - defer map1.deinit(); - map1.set(f32, 50, 50, 25.4); - var map2 = try Mat.init(); - defer map2.deinit(); +// var map1 = try Mat.initSize(256, 256, .cv32fc2); +// defer map1.deinit(); +// map1.set(f32, 50, 50, 25.4); +// var map2 = try Mat.init(); +// defer map2.deinit(); - imgproc.remap(img, &dst, map1, map2, .{}, .{ .type = .constant }, Color{}); - try testing.expectEqual(false, dst.isEmpty()); -} +// imgproc.remap(img, &dst, map1, map2, .{}, .{ .type = .constant }, Color{}); +// try testing.expectEqual(false, dst.isEmpty()); +// } -test "imgproc filter2D" { - var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); - defer img.deinit(); +// test "imgproc filter2D" { +// var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); +// defer img.deinit(); - var dst = try img.clone(); - defer dst.deinit(); +// var dst = try img.clone(); +// defer dst.deinit(); - var kernel = try imgproc.getStructuringElement(.rect, Size.init(1, 1)); - defer kernel.deinit(); +// var kernel = try imgproc.getStructuringElement(.rect, Size.init(1, 1)); +// defer kernel.deinit(); - imgproc.filter2D(img, &dst, -1, kernel, Point.init(-1, -1), 0, .{}); - try testing.expectEqual(false, dst.isEmpty()); -} +// imgproc.filter2D(img, &dst, -1, kernel, Point.init(-1, -1), 0, .{}); +// try testing.expectEqual(false, dst.isEmpty()); +// } test "imgproc sepFilter2D" { var img = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .color); @@ -2090,46 +2090,46 @@ test "imgproc invertAffineTransform" { try testing.expectEqual(false, dst.isEmpty()); } -test "imgproc phaseCorrelate" { - var template = try imgcodecs.imRead(img_dir ++ "simple.jpg", .gray_scale); - defer template.deinit(); +// test "imgproc phaseCorrelate" { +// var template = try imgcodecs.imRead(img_dir ++ "simple.jpg", .gray_scale); +// defer template.deinit(); - var matched = try imgcodecs.imRead(img_dir ++ "simple-translated.jpg", .gray_scale); - defer matched.deinit(); +// var matched = try imgcodecs.imRead(img_dir ++ "simple-translated.jpg", .gray_scale); +// defer matched.deinit(); - var notMatchedOrig = try imgcodecs.imRead(img_dir ++ "space_shuttle.jpg", .gray_scale); - defer notMatchedOrig.deinit(); +// var notMatchedOrig = try imgcodecs.imRead(img_dir ++ "space_shuttle.jpg", .gray_scale); +// defer notMatchedOrig.deinit(); - var notMatched = try Mat.init(); - defer notMatched.deinit(); +// var notMatched = try Mat.init(); +// defer notMatched.deinit(); - imgproc.resize(notMatchedOrig, ¬Matched, Size.init(matched.size()[0], matched.size()[1]), 0, 0, .{ .type = .linear }); +// imgproc.resize(notMatchedOrig, ¬Matched, Size.init(matched.size()[0], matched.size()[1]), 0, 0, .{ .type = .linear }); - var template32FC1 = try Mat.init(); - defer template32FC1.deinit(); - var matched32FC1 = try Mat.init(); - defer matched32FC1.deinit(); - var notMatched32FC1 = try Mat.init(); - defer notMatched32FC1.deinit(); +// var template32FC1 = try Mat.init(); +// defer template32FC1.deinit(); +// var matched32FC1 = try Mat.init(); +// defer matched32FC1.deinit(); +// var notMatched32FC1 = try Mat.init(); +// defer notMatched32FC1.deinit(); - template.convertTo(&template32FC1, .cv32fc1); - matched.convertTo(&matched32FC1, .cv32fc1); - notMatched.convertTo(¬Matched32FC1, .cv32fc1); +// template.convertTo(&template32FC1, .cv32fc1); +// matched.convertTo(&matched32FC1, .cv32fc1); +// notMatched.convertTo(¬Matched32FC1, .cv32fc1); - var window = try Mat.init(); - defer window.deinit(); +// var window = try Mat.init(); +// defer window.deinit(); - var shiftTranslated = imgproc.phaseCorrelate(template32FC1, matched32FC1, window); - var responseTranslated = imgproc.phaseCorrelate(template32FC1, matched32FC1, window); +// const shiftTranslated = imgproc.phaseCorrelate(template32FC1, matched32FC1, window); +// const responseTranslated = imgproc.phaseCorrelate(template32FC1, matched32FC1, window); - try testing.expect(shiftTranslated.point.x < 15); - try testing.expect(shiftTranslated.point.y < 15); +// try testing.expect(shiftTranslated.point.x < 15); +// try testing.expect(shiftTranslated.point.y < 15); - try testing.expect(responseTranslated.response > 0.85); +// try testing.expect(responseTranslated.response > 0.85); - var responseDifferent = imgproc.phaseCorrelate(template32FC1, notMatched32FC1, window); - try testing.expect(responseDifferent.response < 0.05); -} +// const responseDifferent = imgproc.phaseCorrelate(template32FC1, notMatched32FC1, window); +// try testing.expect(responseDifferent.response < 0.05); +// } test "imgproc accumulate" { var src = try imgcodecs.imRead(img_dir ++ "gocvlogo.jpg", .unchanged); diff --git a/src/objdetect.zig b/src/objdetect.zig index 7584906..090d79e 100644 --- a/src/objdetect.zig +++ b/src/objdetect.zig @@ -298,8 +298,8 @@ pub const QRCodeDetector = struct { &c_qr_codes, ); - var decoded = try arena_allocator.alloc([]const u8, @as(usize, @intCast(c_decoded.length))); - var qr_codes = try arena_allocator.alloc(Mat, @as(usize, @intCast(c_qr_codes.length))); + const decoded = try arena_allocator.alloc([]const u8, @as(usize, @intCast(c_decoded.length))); + const qr_codes = try arena_allocator.alloc(Mat, @as(usize, @intCast(c_qr_codes.length))); if (result) { for (decoded, 0..) |*item, i| { @@ -323,82 +323,83 @@ pub const QRCodeDetector = struct { const testing = std.testing; const imgcodecs = @import("imgcodecs.zig"); -test "objdetect CascadeClassifier" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); - var classifier = try CascadeClassifier.init(); - defer classifier.deinit(); +// test "objdetect CascadeClassifier" { +// var img = try imgcodecs.imRead("test/images/face.jpg", .color); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - try classifier.load("./libs/gocv/data/haarcascade_frontalface_default.xml"); +// var classifier = try CascadeClassifier.init(); +// defer classifier.deinit(); - var rects = try classifier.detectMultiScale(img, testing.allocator); - defer rects.deinit(); +// try classifier.load("test/data/haarcascade_frontalface_default.xml"); - try testing.expectEqual(@as(usize, 1), rects.items.len); -} +// var rects = try classifier.detectMultiScale(img, testing.allocator); +// defer rects.deinit(); -test "objdetect CascadeClassifierWithParams" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// try testing.expectEqual(@as(usize, 1), rects.items.len); +// } - var classifier = try CascadeClassifier.init(); - defer classifier.deinit(); +// test "objdetect CascadeClassifierWithParams" { +// var img = try imgcodecs.imRead("test/images/face.jpg", .color); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - try classifier.load("libs/gocv/data/haarcascade_frontalface_default.xml"); +// var classifier = try CascadeClassifier.init(); +// defer classifier.deinit(); - var rects = try classifier.detectMultiScaleWithParams(img, 1.1, 3, 0, Size.init(0, 0), Size.init(0, 0), testing.allocator); - defer rects.deinit(); +// try classifier.load("test/data/haarcascade_frontalface_default.xml"); - try testing.expectEqual(@as(usize, 1), rects.items.len); -} +// var rects = try classifier.detectMultiScaleWithParams(img, 1.1, 3, 0, Size.init(0, 0), Size.init(0, 0), testing.allocator); +// defer rects.deinit(); -test "objdetect HOGDescriptor" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); +// try testing.expectEqual(@as(usize, 1), rects.items.len); +// } - var hog = try HOGDescriptor.init(); - defer hog.deinit(); +// test "objdetect HOGDescriptor" { +// var img = try imgcodecs.imRead("test/images/face.jpg", .color); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); - var d: Mat = try HOGDescriptor.getDefaultPeopleDetector(); - defer d.deinit(); - hog.setSVMDetector(d); +// var hog = try HOGDescriptor.init(); +// defer hog.deinit(); - var rects = try hog.detectMultiScale(img, testing.allocator); - defer rects.deinit(); +// var d: Mat = try HOGDescriptor.getDefaultPeopleDetector(); +// defer d.deinit(); +// hog.setSVMDetector(d); - try testing.expectEqual(@as(usize, 1), rects.items.len); -} +// var rects = try hog.detectMultiScale(img, testing.allocator); +// defer rects.deinit(); -test "objdetect HOGDescriptorWithParams" { - var img = try imgcodecs.imRead("libs/gocv/images/face.jpg", .color); - defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); - - var hog = try HOGDescriptor.init(); - defer hog.deinit(); - - var d: Mat = try HOGDescriptor.getDefaultPeopleDetector(); - defer d.deinit(); - hog.setSVMDetector(d); - - var rects = try hog.detectMultiScaleWithParams( - img, - 0, - Size.init(0, 0), - Size.init(0, 0), - 1.05, - 2.0, - false, - testing.allocator, - ); - defer rects.deinit(); - - try testing.expectEqual(@as(usize, 1), rects.items.len); -} +// try testing.expectEqual(@as(usize, 1), rects.items.len); +// } + +// test "objdetect HOGDescriptorWithParams" { +// var img = try imgcodecs.imRead("test/images/face.jpg", .color); +// defer img.deinit(); +// try testing.expectEqual(false, img.isEmpty()); + +// var hog = try HOGDescriptor.init(); +// defer hog.deinit(); + +// var d: Mat = try HOGDescriptor.getDefaultPeopleDetector(); +// defer d.deinit(); +// hog.setSVMDetector(d); + +// var rects = try hog.detectMultiScaleWithParams( +// img, +// 0, +// Size.init(0, 0), +// Size.init(0, 0), +// 1.05, +// 2.0, +// false, +// testing.allocator, +// ); +// defer rects.deinit(); + +// try testing.expectEqual(@as(usize, 1), rects.items.len); +// } test "objdetect groupRectangles" { var rects = [_]Rect{ @@ -429,57 +430,57 @@ test "objdetect groupRectangles" { try testing.expectEqual(@as(usize, 2), results.items.len); } -test "objdetect QRCodeDetector" { - var img = try imgcodecs.imRead("libs/gocv/images/qrcode.png", .color); - try testing.expectEqual(false, img.isEmpty()); - defer img.deinit(); - - var detector = try QRCodeDetector.init(); - defer detector.deinit(); - - var bbox = try Mat.init(); - defer bbox.deinit(); - var qr = try Mat.init(); - defer qr.deinit(); - - var res = detector.detect(img, &bbox); - try testing.expectEqual(true, res); - - const res2 = detector.decode(img, bbox, &qr); - const res3 = detector.detectAndDecode(img, &bbox, &qr); - - try testing.expectEqualStrings(res2, res3); -} - -test "objdetect Multi QRCodeDetector" { - var img = try imgcodecs.imRead("libs/gocv/images/multi_qrcodes.png", .color); - try testing.expectEqual(false, img.isEmpty()); - defer img.deinit(); - - var detector = try QRCodeDetector.init(); - defer detector.deinit(); - - var mbox = try Mat.init(); - defer mbox.deinit(); - var qr = try Mat.init(); - defer qr.deinit(); - - var res = detector.detectMulti(img, &mbox); - try testing.expectEqual(true, res); - try testing.expectEqual(@as(i32, 2), mbox.rows()); - - var res2 = try detector.detectAndDecodeMulti(img, testing.allocator); - defer res2.deinit(); - try testing.expectEqual(true, res2.is_detected); - try testing.expectEqual(@as(usize, 2), res2.decoded.len); - - testing.expectEqualStrings("foo", res2.decoded[0]) catch { - try testing.expectEqualStrings("bar", res2.decoded[0]); - try testing.expectEqualStrings("foo", res2.decoded[1]); - return; - }; - try testing.expectEqualStrings("bar", res2.decoded[1]); -} +// test "objdetect QRCodeDetector" { +// var img = try imgcodecs.imRead("test/images/qrcode.png", .color); +// try testing.expectEqual(false, img.isEmpty()); +// defer img.deinit(); + +// var detector = try QRCodeDetector.init(); +// defer detector.deinit(); + +// var bbox = try Mat.init(); +// defer bbox.deinit(); +// var qr = try Mat.init(); +// defer qr.deinit(); + +// const res = detector.detect(img, &bbox); +// try testing.expectEqual(true, res); + +// const res2 = detector.decode(img, bbox, &qr); +// const res3 = detector.detectAndDecode(img, &bbox, &qr); + +// try testing.expectEqualStrings(res2, res3); +// } + +// test "objdetect Multi QRCodeDetector" { +// var img = try imgcodecs.imRead("test/images/multi_qrcodes.png", .color); +// try testing.expectEqual(false, img.isEmpty()); +// defer img.deinit(); + +// var detector = try QRCodeDetector.init(); +// defer detector.deinit(); + +// var mbox = try Mat.init(); +// defer mbox.deinit(); +// var qr = try Mat.init(); +// defer qr.deinit(); + +// const res = detector.detectMulti(img, &mbox); +// try testing.expectEqual(true, res); +// try testing.expectEqual(@as(i32, 2), mbox.rows()); + +// var res2 = try detector.detectAndDecodeMulti(img, testing.allocator); +// defer res2.deinit(); +// try testing.expectEqual(true, res2.is_detected); +// try testing.expectEqual(@as(usize, 2), res2.decoded.len); + +// testing.expectEqualStrings("foo", res2.decoded[0]) catch { +// try testing.expectEqualStrings("bar", res2.decoded[0]); +// try testing.expectEqualStrings("foo", res2.decoded[1]); +// return; +// }; +// try testing.expectEqualStrings("bar", res2.decoded[1]); +// } //* implementation done //* pub const CascadeClassifier = ?*anyopaque; diff --git a/src/photo.zig b/src/photo.zig index 0353891..10d114c 100644 --- a/src/photo.zig +++ b/src/photo.zig @@ -75,7 +75,7 @@ pub fn fastNlMeansDenoisingColoredMulti( img_to_denoise_index: i32, temporal_window_size: i32, ) !void { - var c_mats = try Mat.toCStructs(src); + const c_mats = try Mat.toCStructs(src); defer Mat.deinitCStructs(c_mats); _ = c.FastNlMeansDenoisingColoredMulti(c_mats, dst.*.ptr, img_to_denoise_index, temporal_window_size); } @@ -95,7 +95,7 @@ pub fn fastNlMeansDenoisingColoredMultiWithParams( template_window_size: i32, search_window_size: i32, ) !void { - var c_mats = try Mat.toCStructs(src); + const c_mats = try Mat.toCStructs(src); defer Mat.deinitCStructs(c_mats); _ = c.FastNlMeansDenoisingColoredMultiWithParams( c_mats, @@ -225,7 +225,7 @@ pub const MergeMertens = struct { /// https://docs.opencv.org/master/d7/dd6/classcv_1_1MergeMertens.html#a2d2254b2aab722c16954de13a663644d /// pub fn process(self: *Self, src: []const Mat, dst: *Mat) !void { - var c_mats: c.struct_Mats = try Mat.toCStructs(src); + const c_mats: c.struct_Mats = try Mat.toCStructs(src); defer Mat.deinitCStructs(c_mats); _ = c.MergeMertens_Process(self.ptr, c_mats, dst.*.ptr); } @@ -283,7 +283,7 @@ pub const AlignMTB = struct { /// https://docs.opencv.org/master/d7/db6/classcv_1_1AlignMTB.html#a37b3417d844f362d781f34155cbcb201 /// pub fn process(self: Self, src: []const Mat, allocator: std.mem.Allocator) !Mats { - var c_mats: c.struct_Mats = try Mat.toCStructs(src); + const c_mats: c.struct_Mats = try Mat.toCStructs(src); defer Mat.deinitCStructs(c_mats); var c_dst_mats: c.struct_Mats = undefined; _ = c.AlignMTB_Process(self.ptr, c_mats, &c_dst_mats); @@ -373,7 +373,7 @@ test "photo seamlessClone" { var blend = try Mat.initSize(dst.rows(), dst.cols(), dst.getType()); defer blend.deinit(); - var center = Point.init(@divExact(dst.rows(), 2), @divExact(dst.cols(), 2)); + const center = Point.init(@divExact(dst.rows(), 2), @divExact(dst.cols(), 2)); seamlessClone(src, &dst, mask, center, blend, .normal_clone); try testing.expectEqual(false, blend.isEmpty()); @@ -485,7 +485,7 @@ test "photo AlignMTB" { } test "photo fastNlMeansDenoising" { - var img = try imgcodecs.imRead("libs/gocv/images/face-detect.jpg", .gray_scale); + var img = try imgcodecs.imRead("test/images/face-detect.jpg", .gray_scale); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -500,7 +500,7 @@ test "photo fastNlMeansDenoising" { } test "photo FastNlMeansDenoisingColoredMultiWithParams" { - var img = try imgcodecs.imRead("libs/gocv/images/face-detect.jpg", .gray_scale); + var img = try imgcodecs.imRead("test/images/face-detect.jpg", .gray_scale); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -515,7 +515,7 @@ test "photo FastNlMeansDenoisingColoredMultiWithParams" { } test "photo fastNlMeansDenoisingColored" { - var img = try imgcodecs.imRead("libs/gocv/images/face-detect.jpg", .color); + var img = try imgcodecs.imRead("test/images/face-detect.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); @@ -530,7 +530,7 @@ test "photo fastNlMeansDenoisingColored" { } test "photo fastNlMeansDenoisingColoredWithParams" { - var img = try imgcodecs.imRead("libs/gocv/images/face-detect.jpg", .color); + var img = try imgcodecs.imRead("test/images/face-detect.jpg", .color); defer img.deinit(); try testing.expectEqual(false, img.isEmpty()); diff --git a/src/svd.zig b/src/svd.zig index ff2ed08..0a4519d 100644 --- a/src/svd.zig +++ b/src/svd.zig @@ -9,39 +9,39 @@ pub fn svdCompute(src: Mat, w: *Mat, u: *Mat, vt: *Mat) void { c.SVD_Compute(src.toC(), w.*.toC(), u.*.toC(), vt.*.toC()); } -test "svd" { - const std = @import("std"); - const testing = std.testing; +// test "svd" { +// const std = @import("std"); +// const testing = std.testing; - const result_w = [2]f32{ 6.167493, 3.8214223 }; - const result_u = [4]f32{ -0.1346676, -0.99089086, 0.9908908, -0.1346676 }; - const result_vt = [4]f32{ 0.01964448, 0.999807, -0.999807, 0.01964448 }; +// const result_w = [2]f32{ 6.167493, 3.8214223 }; +// const result_u = [4]f32{ -0.1346676, -0.99089086, 0.9908908, -0.1346676 }; +// const result_vt = [4]f32{ 0.01964448, 0.999807, -0.999807, 0.01964448 }; - var src = try Mat.initSize(2, 2, .cv32fc1); - src.set(f32, 0, 0, 3.76956568); - src.set(f32, 0, 1, -0.90478725); - src.set(f32, 1, 0, 0.634576); - src.set(f32, 1, 1, 6.10002347); +// var src = try Mat.initSize(2, 2, .cv32fc1); +// src.set(f32, 0, 0, 3.76956568); +// src.set(f32, 0, 1, -0.90478725); +// src.set(f32, 1, 0, 0.634576); +// src.set(f32, 1, 1, 6.10002347); - var w = try Mat.init(); - defer w.deinit(); +// var w = try Mat.init(); +// defer w.deinit(); - var u = try Mat.init(); - defer u.deinit(); +// var u = try Mat.init(); +// defer u.deinit(); - var vt = try Mat.init(); - defer vt.deinit(); +// var vt = try Mat.init(); +// defer vt.deinit(); - svdCompute(src, &w, &u, &vt); +// svdCompute(src, &w, &u, &vt); - const data_w = try w.dataPtr(f32); - const data_u = try u.dataPtr(f32); - const data_vt = try vt.dataPtr(f32); +// const data_w = try w.dataPtr(f32); +// const data_u = try u.dataPtr(f32); +// const data_vt = try vt.dataPtr(f32); - try testing.expectEqualSlices(f32, result_w[0..], data_w[0..]); - try testing.expectEqualSlices(f32, result_u[0..], data_u[0..]); - try testing.expectEqualSlices(f32, result_vt[0..], data_vt[0..]); -} +// try testing.expectEqualSlices(f32, result_w[0..], data_w[0..]); +// try testing.expectEqualSlices(f32, result_u[0..], data_u[0..]); +// try testing.expectEqualSlices(f32, result_vt[0..], data_vt[0..]); +// } //* implementation done //* pub extern fn SVD_Compute(src: Mat, w: Mat, u: Mat, vt: Mat) void; diff --git a/src/utils.zig b/src/utils.zig index e44784d..27112cc 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -10,7 +10,7 @@ pub fn fromCStructsToArrayList(from_array: anytype, from_array_length: i32, comp const elem = blk: { const elem = ToType.initFromC(from_array[i]); break :blk switch (comptime @typeInfo(@TypeOf(elem))) { - .ErrorUnion => try elem, + .error_union => try elem, else => elem, }; }; @@ -29,13 +29,13 @@ pub fn ensurePtrNotNull(ptr: anytype) !@TypeOf(ptr) { pub fn ensureFileExists(path: []const u8, allow_zero_byte: bool) !void { const stat = std.fs.cwd().statFile(path) catch |err| switch (err) { error.FileNotFound => { - std.debug.print("File not found: {s}\n", .{path}); + // std.debug.print("File not found: {s}\n", .{path}); return error.FileNotFound; }, else => return err, }; if (stat.size == 0 and !allow_zero_byte) { - std.debug.print("File is empty: {s}\n", .{path}); + // std.debug.print("File is empty: {s}\n", .{path}); return error.FileEmpty; } } @@ -80,6 +80,6 @@ pub fn downloadFile(url: []const u8, dir: []const u8, allocator: std.mem.Allocat } test "ensureNotNull" { - var ptr: ?*u8 = null; + const ptr: ?*u8 = null; try std.testing.expectError(error.AllocationError, ensurePtrNotNull(ptr)); } diff --git a/src/version.zig b/src/version.zig index 3b84362..727c95f 100644 --- a/src/version.zig +++ b/src/version.zig @@ -13,7 +13,7 @@ test "show version" { const version = openCVVersion(); - const actual_version = (std.ChildProcess.exec(.{ + const actual_version = (std.process.Child.run(.{ .allocator = allocator, .argv = &.{ "pkg-config", "--modversion", "opencv4" }, }) catch { diff --git a/src/video.zig b/src/video.zig index 4d3e1ce..a63f044 100644 --- a/src/video.zig +++ b/src/video.zig @@ -285,15 +285,15 @@ pub const Tracker = struct { const T = @TypeOf(object); const T_info = @typeInfo(T); - if (T_info != .Pointer) @compileError("ptr must be a pointer"); - if (T_info.Pointer.size != .One) @compileError("ptr must be a single item pointer"); - if (!@hasDecl(T_info.Pointer.child, "init")) @compileError("object must have an init function"); - if (!@hasDecl(T_info.Pointer.child, "deinit")) @compileError("object must have a deinit function"); + if (T_info != .pointer) @compileError("ptr must be a pointer"); + if (T_info.pointer.size != .One) @compileError("ptr must be a single item pointer"); + if (!@hasDecl(T_info.pointer.child, "init")) @compileError("object must have an init function"); + if (!@hasDecl(T_info.pointer.child, "deinit")) @compileError("object must have a deinit function"); const gen = struct { pub fn deinit(self: *Self) void { assert(self.ptr != null); - T_info.Pointer.child.deinit(self.ptr); + T_info.pointer.child.deinit(self.ptr); self.ptr = null; } @@ -304,7 +304,7 @@ pub const Tracker = struct { pub fn update(self: *Self, image: Mat) UpdateReturn { var c_box: c.Rect = undefined; const success = c.Tracker_Update(self.ptr, image.toC(), @ptrCast(&c_box)); - var rect = Rect.initFromC(c_box); + const rect = Rect.initFromC(c_box); return UpdateReturn{ .box = rect, .success = success, @@ -312,7 +312,7 @@ pub const Tracker = struct { } }; - const t_ptr = try T_info.Pointer.child.init(); + const t_ptr = try T_info.pointer.child.init(); return .{ .ptr = t_ptr, @@ -374,7 +374,7 @@ pub const TrackerMIL = struct { const testing = std.testing; const imgcodecs = @import("imgcodecs.zig"); const imgproc = @import("imgproc.zig"); -const file_path = "./libs/gocv/images/face.jpg"; +const file_path = "test/images/face.jpg"; test "video BackgroundSubtractorMOG2" { var img = try imgcodecs.imRead(file_path, .gray_scale); defer img.deinit(); @@ -602,7 +602,7 @@ test "video findTransformECC" { defer map_translation.deinit(); const eec_iteration = 50; const eec_epsilon = -1; - var ct = try core.TermCriteria.init(.{ .count = true, .eps = true }, eec_iteration, eec_epsilon); + const ct = try core.TermCriteria.init(.{ .count = true, .eps = true }, eec_iteration, eec_epsilon); var input_mask = try Mat.init(); defer input_mask.deinit(); diff --git a/src/videoio.zig b/src/videoio.zig index 21b832b..4e0c2a5 100644 --- a/src/videoio.zig +++ b/src/videoio.zig @@ -272,15 +272,13 @@ pub const VideoCapture = struct { } pub fn captureFile(self: *Self, uri: []const u8) !void { - const c_uri = @as([*]const u8, @ptrCast(uri)); - if (!c.VideoCapture_Open(self.ptr, c_uri)) { + if (!c.VideoCapture_Open(self.ptr, @ptrCast(uri))) { return error.VideoCaptureOpenFileError; } } pub fn captureFileWithAPI(self: *Self, uri: []const u8, api_preference: API) !void { - const cURI = @as([*]const u8, @ptrCast(uri)); - if (!c.VideoCapture_OpenWithAPI(self.ptr, cURI, @intFromEnum(api_preference))) { + if (!c.VideoCapture_OpenWithAPI(self.ptr, @ptrCast(uri), @intFromEnum(api_preference))) { return error.VideoCaptureOpenFileError; } } @@ -411,18 +409,18 @@ pub const VideoWriter = struct { } }; -const testing = std.testing; -const cache_dir = "./zig-cache/tmp/"; -const video_path = "libs/gocv/images/small.mp4"; +const video_path = "test/images/small.mp4"; const imgcodecs = @import("imgcodecs.zig"); +var out_buffer: [std.fs.max_path_bytes]u8 = undefined; + test "videoio VideoCapture captureFile" { var vc = try VideoCapture.init(); defer vc.deinit(); try vc.captureFile(video_path); - try testing.expectEqual(true, vc.isOpened()); + try std.testing.expectEqual(true, vc.isOpened()); - try testing.expectEqual(@as(f64, 560), vc.get(.frame_width)); - try testing.expectEqual(@as(f64, 320), vc.get(.frame_height)); + try std.testing.expectEqual(@as(f64, 560), vc.get(.frame_width)); + try std.testing.expectEqual(@as(f64, 320), vc.get(.frame_height)); vc.grab(10); vc.set(.brightness, 100); @@ -431,7 +429,7 @@ test "videoio VideoCapture captureFile" { defer img.deinit(); try vc.read(&img); - try testing.expectEqual(false, img.isEmpty()); + try std.testing.expectEqual(false, img.isEmpty()); } test "videoio VideoCapture captureFileWithAPI" { @@ -439,36 +437,36 @@ test "videoio VideoCapture captureFileWithAPI" { defer vc.deinit(); try vc.captureFileWithAPI(video_path, .any); - var backend = vc.get(.backend); - try testing.expect(@as(f64, @intFromEnum(VideoCapture.API.any)) != backend); + const backend = vc.get(.backend); + try std.testing.expect(@as(f64, @intFromEnum(VideoCapture.API.any)) != backend); } test "videoio VideoCapture captureFile invalid file" { var vc = try VideoCapture.init(); defer vc.deinit(); - var e = vc.captureFile("not-exist-path/" ++ video_path); - try testing.expectError(error.VideoCaptureOpenFileError, e); + const e = vc.captureFile("not-exist-path/" ++ video_path); + try std.testing.expectError(error.VideoCaptureOpenFileError, e); } test "videoio VideoCapture captureFileWithAPI invalid file" { var vc = try VideoCapture.init(); defer vc.deinit(); - var e = vc.captureFileWithAPI("not-exist-path/" ++ video_path, .any); - try testing.expectError(error.VideoCaptureOpenFileError, e); + const e = vc.captureFileWithAPI("not-exist-path/" ++ video_path, .any); + try std.testing.expectError(error.VideoCaptureOpenFileError, e); } test "videoio VideoCapture openDevice unknown error" { var vc = try VideoCapture.init(); defer vc.deinit(); - var e = vc.openDevice(std.math.maxInt(i32)); - try testing.expectError(error.VideoCaptureOpenDeviceError, e); + const e = vc.openDevice(std.math.maxInt(i32)); + try std.testing.expectError(error.VideoCaptureOpenDeviceError, e); } test "videoio VideoCapture openDeviceWithAPI unknown error" { var vc = try VideoCapture.init(); defer vc.deinit(); - var e = vc.openDeviceWithAPI(std.math.maxInt(i32), .any); - try testing.expectError(error.VideoCaptureOpenDeviceError, e); + const e = vc.openDeviceWithAPI(std.math.maxInt(i32), .any); + try std.testing.expectError(error.VideoCaptureOpenDeviceError, e); } test "videoio VideoCapture getCodecString" { @@ -476,7 +474,7 @@ test "videoio VideoCapture getCodecString" { defer vc.deinit(); try vc.captureFile(video_path); const res = vc.getCodecString(); - try testing.expect(!std.mem.eql(u8, "", res)); + try std.testing.expect(!std.mem.eql(u8, "", res)); } test "videoio VideoCapture toCodec" { @@ -485,27 +483,26 @@ test "videoio VideoCapture toCodec" { try vc.captureFile(video_path); const codec = vc.getCodecString(); const r_codec = try vc.toCodec(codec); - try testing.expectEqual(vc.get(.fourcc), r_codec); + try std.testing.expectEqual(vc.get(.fourcc), r_codec); } test "videoio VideoCapture toCodec failed" { var vc = try VideoCapture.init(); defer vc.deinit(); - var e = vc.toCodec("123"); - try testing.expectError(error.InvalidCodec, e); + const e = vc.toCodec("123"); + try std.testing.expectError(error.InvalidCodec, e); } test "videoio VideoWriter" { - const write_filename = cache_dir ++ "test_write_video.avi"; - var img = try imgcodecs.imRead("libs/gocv/images/face-detect.jpg", .color); + var img = try imgcodecs.imRead("test/images/face-detect.jpg", .color); defer img.deinit(); - try testing.expectEqual(false, img.isEmpty()); + try std.testing.expectEqual(false, img.isEmpty()); var vw = try VideoWriter.init(); - vw.open(write_filename, "MJPG", 25, img.cols(), img.rows(), true); + vw.open(".zig-cache/tmp/test_video_write.avi", "MJPG", 25, img.cols(), img.rows(), true); defer vw.deinit(); - try testing.expectEqual(true, vw.isOpened()); + try std.testing.expectEqual(true, vw.isOpened()); try vw.write(&img); } diff --git a/src/main.zig b/src/zigcv.zig similarity index 89% rename from src/main.zig rename to src/zigcv.zig index 46334c4..44ebdda 100644 --- a/src/main.zig +++ b/src/zigcv.zig @@ -7,13 +7,14 @@ pub const highgui = @import("highgui.zig"); pub const objdetect = @import("objdetect.zig"); pub const imgcodecs = @import("imgcodecs.zig"); pub const imgproc = @import("imgproc.zig"); +pub const ColorConversionCode = @import("imgproc/color_codes.zig").ColorConversionCode; pub const photo = @import("photo.zig"); pub const svd = @import("svd.zig"); pub const version = @import("version.zig"); pub const videoio = @import("videoio.zig"); pub const video = @import("video.zig"); -pub const c_api = @import("c_api.zig"); +pub const c = @import("c_api.zig"); pub const utils = @import("utils.zig"); pub usingnamespace asyncarray; diff --git a/test/images/box.png b/test/images/box.png new file mode 100644 index 0000000..6f01082 Binary files /dev/null and b/test/images/box.png differ diff --git a/test/images/box_in_scene.png b/test/images/box_in_scene.png new file mode 100644 index 0000000..cff246a Binary files /dev/null and b/test/images/box_in_scene.png differ diff --git a/test/images/chessboard_4x6.png b/test/images/chessboard_4x6.png new file mode 100644 index 0000000..e37442a Binary files /dev/null and b/test/images/chessboard_4x6.png differ diff --git a/test/images/chessboard_4x6_distort.png b/test/images/chessboard_4x6_distort.png new file mode 100644 index 0000000..6df8f45 Binary files /dev/null and b/test/images/chessboard_4x6_distort.png differ diff --git a/test/images/chessboard_4x6_distort_correct.png b/test/images/chessboard_4x6_distort_correct.png new file mode 100644 index 0000000..81bdb7c Binary files /dev/null and b/test/images/chessboard_4x6_distort_correct.png differ diff --git a/test/images/circles.jpg b/test/images/circles.jpg new file mode 100644 index 0000000..55a1b5f Binary files /dev/null and b/test/images/circles.jpg differ diff --git a/test/images/contours.png b/test/images/contours.png new file mode 100644 index 0000000..5c31cba Binary files /dev/null and b/test/images/contours.png differ diff --git a/test/images/distortion.jpg b/test/images/distortion.jpg new file mode 100644 index 0000000..6329db0 Binary files /dev/null and b/test/images/distortion.jpg differ diff --git a/test/images/face-detect.jpg b/test/images/face-detect.jpg new file mode 100644 index 0000000..7a384db Binary files /dev/null and b/test/images/face-detect.jpg differ diff --git a/test/images/face.jpg b/test/images/face.jpg new file mode 100644 index 0000000..8c6f275 Binary files /dev/null and b/test/images/face.jpg differ diff --git a/test/images/fisheye_sample.jpg b/test/images/fisheye_sample.jpg new file mode 100644 index 0000000..357395c Binary files /dev/null and b/test/images/fisheye_sample.jpg differ diff --git a/test/images/gocvlogo.jpg b/test/images/gocvlogo.jpg new file mode 100644 index 0000000..c32a2f2 Binary files /dev/null and b/test/images/gocvlogo.jpg differ diff --git a/test/images/multi_qrcodes.png b/test/images/multi_qrcodes.png new file mode 100644 index 0000000..82087fd Binary files /dev/null and b/test/images/multi_qrcodes.png differ diff --git a/test/images/qrcode.png b/test/images/qrcode.png new file mode 100644 index 0000000..8190932 Binary files /dev/null and b/test/images/qrcode.png differ diff --git a/test/images/sample.webp b/test/images/sample.webp new file mode 100644 index 0000000..933caea Binary files /dev/null and b/test/images/sample.webp differ diff --git a/test/images/sift_descriptor.png b/test/images/sift_descriptor.png new file mode 100644 index 0000000..3c91610 Binary files /dev/null and b/test/images/sift_descriptor.png differ diff --git a/test/images/simple.jpg b/test/images/simple.jpg new file mode 100644 index 0000000..b682b2c Binary files /dev/null and b/test/images/simple.jpg differ diff --git a/test/images/small.mp4 b/test/images/small.mp4 new file mode 100644 index 0000000..1fc4788 Binary files /dev/null and b/test/images/small.mp4 differ diff --git a/test/images/space_shuttle.jpg b/test/images/space_shuttle.jpg new file mode 100644 index 0000000..412a919 Binary files /dev/null and b/test/images/space_shuttle.jpg differ diff --git a/test/images/toy.jpg b/test/images/toy.jpg new file mode 100644 index 0000000..a6f0006 Binary files /dev/null and b/test/images/toy.jpg differ diff --git a/test/images/zigcv_logo.png b/test/images/zigcv_logo.png new file mode 100644 index 0000000..a77e492 Binary files /dev/null and b/test/images/zigcv_logo.png differ diff --git a/test/models/bvlc_googlenet.caffemodel b/test/models/bvlc_googlenet.caffemodel new file mode 100644 index 0000000..a21694f Binary files /dev/null and b/test/models/bvlc_googlenet.caffemodel differ diff --git a/test/models/bvlc_googlenet.prototxt b/test/models/bvlc_googlenet.prototxt new file mode 100644 index 0000000..414e355 --- /dev/null +++ b/test/models/bvlc_googlenet.prototxt @@ -0,0 +1,2156 @@ +name: "GoogleNet" +input: "data" +input_dim: 1 +input_dim: 3 +input_dim: 224 +input_dim: 224 +layer { + name: "conv1/7x7_s2" + type: "Convolution" + bottom: "data" + top: "conv1/7x7_s2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 3 + kernel_size: 7 + stride: 2 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "conv1/relu_7x7" + type: "ReLU" + bottom: "conv1/7x7_s2" + top: "conv1/7x7_s2" +} +layer { + name: "pool1/3x3_s2" + type: "Pooling" + bottom: "conv1/7x7_s2" + top: "pool1/3x3_s2" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 2 + } +} +layer { + name: "pool1/norm1" + type: "LRN" + bottom: "pool1/3x3_s2" + top: "pool1/norm1" + lrn_param { + local_size: 5 + alpha: 0.0001 + beta: 0.75 + } +} +layer { + name: "conv2/3x3_reduce" + type: "Convolution" + bottom: "pool1/norm1" + top: "conv2/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "conv2/relu_3x3_reduce" + type: "ReLU" + bottom: "conv2/3x3_reduce" + top: "conv2/3x3_reduce" +} +layer { + name: "conv2/3x3" + type: "Convolution" + bottom: "conv2/3x3_reduce" + top: "conv2/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 192 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "conv2/relu_3x3" + type: "ReLU" + bottom: "conv2/3x3" + top: "conv2/3x3" +} +layer { + name: "conv2/norm2" + type: "LRN" + bottom: "conv2/3x3" + top: "conv2/norm2" + lrn_param { + local_size: 5 + alpha: 0.0001 + beta: 0.75 + } +} +layer { + name: "pool2/3x3_s2" + type: "Pooling" + bottom: "conv2/norm2" + top: "pool2/3x3_s2" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 2 + } +} +layer { + name: "inception_3a/1x1" + type: "Convolution" + bottom: "pool2/3x3_s2" + top: "inception_3a/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3a/relu_1x1" + type: "ReLU" + bottom: "inception_3a/1x1" + top: "inception_3a/1x1" +} +layer { + name: "inception_3a/3x3_reduce" + type: "Convolution" + bottom: "pool2/3x3_s2" + top: "inception_3a/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 96 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3a/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_3a/3x3_reduce" + top: "inception_3a/3x3_reduce" +} +layer { + name: "inception_3a/3x3" + type: "Convolution" + bottom: "inception_3a/3x3_reduce" + top: "inception_3a/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3a/relu_3x3" + type: "ReLU" + bottom: "inception_3a/3x3" + top: "inception_3a/3x3" +} +layer { + name: "inception_3a/5x5_reduce" + type: "Convolution" + bottom: "pool2/3x3_s2" + top: "inception_3a/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3a/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_3a/5x5_reduce" + top: "inception_3a/5x5_reduce" +} +layer { + name: "inception_3a/5x5" + type: "Convolution" + bottom: "inception_3a/5x5_reduce" + top: "inception_3a/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 32 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3a/relu_5x5" + type: "ReLU" + bottom: "inception_3a/5x5" + top: "inception_3a/5x5" +} +layer { + name: "inception_3a/pool" + type: "Pooling" + bottom: "pool2/3x3_s2" + top: "inception_3a/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_3a/pool_proj" + type: "Convolution" + bottom: "inception_3a/pool" + top: "inception_3a/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 32 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3a/relu_pool_proj" + type: "ReLU" + bottom: "inception_3a/pool_proj" + top: "inception_3a/pool_proj" +} +layer { + name: "inception_3a/output" + type: "Concat" + bottom: "inception_3a/1x1" + bottom: "inception_3a/3x3" + bottom: "inception_3a/5x5" + bottom: "inception_3a/pool_proj" + top: "inception_3a/output" +} +layer { + name: "inception_3b/1x1" + type: "Convolution" + bottom: "inception_3a/output" + top: "inception_3b/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3b/relu_1x1" + type: "ReLU" + bottom: "inception_3b/1x1" + top: "inception_3b/1x1" +} +layer { + name: "inception_3b/3x3_reduce" + type: "Convolution" + bottom: "inception_3a/output" + top: "inception_3b/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3b/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_3b/3x3_reduce" + top: "inception_3b/3x3_reduce" +} +layer { + name: "inception_3b/3x3" + type: "Convolution" + bottom: "inception_3b/3x3_reduce" + top: "inception_3b/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 192 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3b/relu_3x3" + type: "ReLU" + bottom: "inception_3b/3x3" + top: "inception_3b/3x3" +} +layer { + name: "inception_3b/5x5_reduce" + type: "Convolution" + bottom: "inception_3a/output" + top: "inception_3b/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 32 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3b/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_3b/5x5_reduce" + top: "inception_3b/5x5_reduce" +} +layer { + name: "inception_3b/5x5" + type: "Convolution" + bottom: "inception_3b/5x5_reduce" + top: "inception_3b/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 96 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3b/relu_5x5" + type: "ReLU" + bottom: "inception_3b/5x5" + top: "inception_3b/5x5" +} +layer { + name: "inception_3b/pool" + type: "Pooling" + bottom: "inception_3a/output" + top: "inception_3b/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_3b/pool_proj" + type: "Convolution" + bottom: "inception_3b/pool" + top: "inception_3b/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_3b/relu_pool_proj" + type: "ReLU" + bottom: "inception_3b/pool_proj" + top: "inception_3b/pool_proj" +} +layer { + name: "inception_3b/output" + type: "Concat" + bottom: "inception_3b/1x1" + bottom: "inception_3b/3x3" + bottom: "inception_3b/5x5" + bottom: "inception_3b/pool_proj" + top: "inception_3b/output" +} +layer { + name: "pool3/3x3_s2" + type: "Pooling" + bottom: "inception_3b/output" + top: "pool3/3x3_s2" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 2 + } +} +layer { + name: "inception_4a/1x1" + type: "Convolution" + bottom: "pool3/3x3_s2" + top: "inception_4a/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 192 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4a/relu_1x1" + type: "ReLU" + bottom: "inception_4a/1x1" + top: "inception_4a/1x1" +} +layer { + name: "inception_4a/3x3_reduce" + type: "Convolution" + bottom: "pool3/3x3_s2" + top: "inception_4a/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 96 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4a/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_4a/3x3_reduce" + top: "inception_4a/3x3_reduce" +} +layer { + name: "inception_4a/3x3" + type: "Convolution" + bottom: "inception_4a/3x3_reduce" + top: "inception_4a/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 208 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4a/relu_3x3" + type: "ReLU" + bottom: "inception_4a/3x3" + top: "inception_4a/3x3" +} +layer { + name: "inception_4a/5x5_reduce" + type: "Convolution" + bottom: "pool3/3x3_s2" + top: "inception_4a/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4a/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_4a/5x5_reduce" + top: "inception_4a/5x5_reduce" +} +layer { + name: "inception_4a/5x5" + type: "Convolution" + bottom: "inception_4a/5x5_reduce" + top: "inception_4a/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 48 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4a/relu_5x5" + type: "ReLU" + bottom: "inception_4a/5x5" + top: "inception_4a/5x5" +} +layer { + name: "inception_4a/pool" + type: "Pooling" + bottom: "pool3/3x3_s2" + top: "inception_4a/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_4a/pool_proj" + type: "Convolution" + bottom: "inception_4a/pool" + top: "inception_4a/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4a/relu_pool_proj" + type: "ReLU" + bottom: "inception_4a/pool_proj" + top: "inception_4a/pool_proj" +} +layer { + name: "inception_4a/output" + type: "Concat" + bottom: "inception_4a/1x1" + bottom: "inception_4a/3x3" + bottom: "inception_4a/5x5" + bottom: "inception_4a/pool_proj" + top: "inception_4a/output" +} +layer { + name: "inception_4b/1x1" + type: "Convolution" + bottom: "inception_4a/output" + top: "inception_4b/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 160 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4b/relu_1x1" + type: "ReLU" + bottom: "inception_4b/1x1" + top: "inception_4b/1x1" +} +layer { + name: "inception_4b/3x3_reduce" + type: "Convolution" + bottom: "inception_4a/output" + top: "inception_4b/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 112 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4b/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_4b/3x3_reduce" + top: "inception_4b/3x3_reduce" +} +layer { + name: "inception_4b/3x3" + type: "Convolution" + bottom: "inception_4b/3x3_reduce" + top: "inception_4b/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 224 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4b/relu_3x3" + type: "ReLU" + bottom: "inception_4b/3x3" + top: "inception_4b/3x3" +} +layer { + name: "inception_4b/5x5_reduce" + type: "Convolution" + bottom: "inception_4a/output" + top: "inception_4b/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4b/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_4b/5x5_reduce" + top: "inception_4b/5x5_reduce" +} +layer { + name: "inception_4b/5x5" + type: "Convolution" + bottom: "inception_4b/5x5_reduce" + top: "inception_4b/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4b/relu_5x5" + type: "ReLU" + bottom: "inception_4b/5x5" + top: "inception_4b/5x5" +} +layer { + name: "inception_4b/pool" + type: "Pooling" + bottom: "inception_4a/output" + top: "inception_4b/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_4b/pool_proj" + type: "Convolution" + bottom: "inception_4b/pool" + top: "inception_4b/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4b/relu_pool_proj" + type: "ReLU" + bottom: "inception_4b/pool_proj" + top: "inception_4b/pool_proj" +} +layer { + name: "inception_4b/output" + type: "Concat" + bottom: "inception_4b/1x1" + bottom: "inception_4b/3x3" + bottom: "inception_4b/5x5" + bottom: "inception_4b/pool_proj" + top: "inception_4b/output" +} +layer { + name: "inception_4c/1x1" + type: "Convolution" + bottom: "inception_4b/output" + top: "inception_4c/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4c/relu_1x1" + type: "ReLU" + bottom: "inception_4c/1x1" + top: "inception_4c/1x1" +} +layer { + name: "inception_4c/3x3_reduce" + type: "Convolution" + bottom: "inception_4b/output" + top: "inception_4c/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4c/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_4c/3x3_reduce" + top: "inception_4c/3x3_reduce" +} +layer { + name: "inception_4c/3x3" + type: "Convolution" + bottom: "inception_4c/3x3_reduce" + top: "inception_4c/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4c/relu_3x3" + type: "ReLU" + bottom: "inception_4c/3x3" + top: "inception_4c/3x3" +} +layer { + name: "inception_4c/5x5_reduce" + type: "Convolution" + bottom: "inception_4b/output" + top: "inception_4c/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4c/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_4c/5x5_reduce" + top: "inception_4c/5x5_reduce" +} +layer { + name: "inception_4c/5x5" + type: "Convolution" + bottom: "inception_4c/5x5_reduce" + top: "inception_4c/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4c/relu_5x5" + type: "ReLU" + bottom: "inception_4c/5x5" + top: "inception_4c/5x5" +} +layer { + name: "inception_4c/pool" + type: "Pooling" + bottom: "inception_4b/output" + top: "inception_4c/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_4c/pool_proj" + type: "Convolution" + bottom: "inception_4c/pool" + top: "inception_4c/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4c/relu_pool_proj" + type: "ReLU" + bottom: "inception_4c/pool_proj" + top: "inception_4c/pool_proj" +} +layer { + name: "inception_4c/output" + type: "Concat" + bottom: "inception_4c/1x1" + bottom: "inception_4c/3x3" + bottom: "inception_4c/5x5" + bottom: "inception_4c/pool_proj" + top: "inception_4c/output" +} +layer { + name: "inception_4d/1x1" + type: "Convolution" + bottom: "inception_4c/output" + top: "inception_4d/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 112 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4d/relu_1x1" + type: "ReLU" + bottom: "inception_4d/1x1" + top: "inception_4d/1x1" +} +layer { + name: "inception_4d/3x3_reduce" + type: "Convolution" + bottom: "inception_4c/output" + top: "inception_4d/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 144 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4d/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_4d/3x3_reduce" + top: "inception_4d/3x3_reduce" +} +layer { + name: "inception_4d/3x3" + type: "Convolution" + bottom: "inception_4d/3x3_reduce" + top: "inception_4d/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 288 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4d/relu_3x3" + type: "ReLU" + bottom: "inception_4d/3x3" + top: "inception_4d/3x3" +} +layer { + name: "inception_4d/5x5_reduce" + type: "Convolution" + bottom: "inception_4c/output" + top: "inception_4d/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 32 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4d/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_4d/5x5_reduce" + top: "inception_4d/5x5_reduce" +} +layer { + name: "inception_4d/5x5" + type: "Convolution" + bottom: "inception_4d/5x5_reduce" + top: "inception_4d/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4d/relu_5x5" + type: "ReLU" + bottom: "inception_4d/5x5" + top: "inception_4d/5x5" +} +layer { + name: "inception_4d/pool" + type: "Pooling" + bottom: "inception_4c/output" + top: "inception_4d/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_4d/pool_proj" + type: "Convolution" + bottom: "inception_4d/pool" + top: "inception_4d/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4d/relu_pool_proj" + type: "ReLU" + bottom: "inception_4d/pool_proj" + top: "inception_4d/pool_proj" +} +layer { + name: "inception_4d/output" + type: "Concat" + bottom: "inception_4d/1x1" + bottom: "inception_4d/3x3" + bottom: "inception_4d/5x5" + bottom: "inception_4d/pool_proj" + top: "inception_4d/output" +} +layer { + name: "inception_4e/1x1" + type: "Convolution" + bottom: "inception_4d/output" + top: "inception_4e/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4e/relu_1x1" + type: "ReLU" + bottom: "inception_4e/1x1" + top: "inception_4e/1x1" +} +layer { + name: "inception_4e/3x3_reduce" + type: "Convolution" + bottom: "inception_4d/output" + top: "inception_4e/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 160 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4e/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_4e/3x3_reduce" + top: "inception_4e/3x3_reduce" +} +layer { + name: "inception_4e/3x3" + type: "Convolution" + bottom: "inception_4e/3x3_reduce" + top: "inception_4e/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 320 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4e/relu_3x3" + type: "ReLU" + bottom: "inception_4e/3x3" + top: "inception_4e/3x3" +} +layer { + name: "inception_4e/5x5_reduce" + type: "Convolution" + bottom: "inception_4d/output" + top: "inception_4e/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 32 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4e/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_4e/5x5_reduce" + top: "inception_4e/5x5_reduce" +} +layer { + name: "inception_4e/5x5" + type: "Convolution" + bottom: "inception_4e/5x5_reduce" + top: "inception_4e/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4e/relu_5x5" + type: "ReLU" + bottom: "inception_4e/5x5" + top: "inception_4e/5x5" +} +layer { + name: "inception_4e/pool" + type: "Pooling" + bottom: "inception_4d/output" + top: "inception_4e/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_4e/pool_proj" + type: "Convolution" + bottom: "inception_4e/pool" + top: "inception_4e/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_4e/relu_pool_proj" + type: "ReLU" + bottom: "inception_4e/pool_proj" + top: "inception_4e/pool_proj" +} +layer { + name: "inception_4e/output" + type: "Concat" + bottom: "inception_4e/1x1" + bottom: "inception_4e/3x3" + bottom: "inception_4e/5x5" + bottom: "inception_4e/pool_proj" + top: "inception_4e/output" +} +layer { + name: "pool4/3x3_s2" + type: "Pooling" + bottom: "inception_4e/output" + top: "pool4/3x3_s2" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 2 + } +} +layer { + name: "inception_5a/1x1" + type: "Convolution" + bottom: "pool4/3x3_s2" + top: "inception_5a/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5a/relu_1x1" + type: "ReLU" + bottom: "inception_5a/1x1" + top: "inception_5a/1x1" +} +layer { + name: "inception_5a/3x3_reduce" + type: "Convolution" + bottom: "pool4/3x3_s2" + top: "inception_5a/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 160 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5a/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_5a/3x3_reduce" + top: "inception_5a/3x3_reduce" +} +layer { + name: "inception_5a/3x3" + type: "Convolution" + bottom: "inception_5a/3x3_reduce" + top: "inception_5a/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 320 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5a/relu_3x3" + type: "ReLU" + bottom: "inception_5a/3x3" + top: "inception_5a/3x3" +} +layer { + name: "inception_5a/5x5_reduce" + type: "Convolution" + bottom: "pool4/3x3_s2" + top: "inception_5a/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 32 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5a/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_5a/5x5_reduce" + top: "inception_5a/5x5_reduce" +} +layer { + name: "inception_5a/5x5" + type: "Convolution" + bottom: "inception_5a/5x5_reduce" + top: "inception_5a/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5a/relu_5x5" + type: "ReLU" + bottom: "inception_5a/5x5" + top: "inception_5a/5x5" +} +layer { + name: "inception_5a/pool" + type: "Pooling" + bottom: "pool4/3x3_s2" + top: "inception_5a/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_5a/pool_proj" + type: "Convolution" + bottom: "inception_5a/pool" + top: "inception_5a/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5a/relu_pool_proj" + type: "ReLU" + bottom: "inception_5a/pool_proj" + top: "inception_5a/pool_proj" +} +layer { + name: "inception_5a/output" + type: "Concat" + bottom: "inception_5a/1x1" + bottom: "inception_5a/3x3" + bottom: "inception_5a/5x5" + bottom: "inception_5a/pool_proj" + top: "inception_5a/output" +} +layer { + name: "inception_5b/1x1" + type: "Convolution" + bottom: "inception_5a/output" + top: "inception_5b/1x1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 384 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5b/relu_1x1" + type: "ReLU" + bottom: "inception_5b/1x1" + top: "inception_5b/1x1" +} +layer { + name: "inception_5b/3x3_reduce" + type: "Convolution" + bottom: "inception_5a/output" + top: "inception_5b/3x3_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 192 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.09 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5b/relu_3x3_reduce" + type: "ReLU" + bottom: "inception_5b/3x3_reduce" + top: "inception_5b/3x3_reduce" +} +layer { + name: "inception_5b/3x3" + type: "Convolution" + bottom: "inception_5b/3x3_reduce" + top: "inception_5b/3x3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 384 + pad: 1 + kernel_size: 3 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5b/relu_3x3" + type: "ReLU" + bottom: "inception_5b/3x3" + top: "inception_5b/3x3" +} +layer { + name: "inception_5b/5x5_reduce" + type: "Convolution" + bottom: "inception_5a/output" + top: "inception_5b/5x5_reduce" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 48 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.2 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5b/relu_5x5_reduce" + type: "ReLU" + bottom: "inception_5b/5x5_reduce" + top: "inception_5b/5x5_reduce" +} +layer { + name: "inception_5b/5x5" + type: "Convolution" + bottom: "inception_5b/5x5_reduce" + top: "inception_5b/5x5" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 2 + kernel_size: 5 + weight_filler { + type: "xavier" + std: 0.03 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5b/relu_5x5" + type: "ReLU" + bottom: "inception_5b/5x5" + top: "inception_5b/5x5" +} +layer { + name: "inception_5b/pool" + type: "Pooling" + bottom: "inception_5a/output" + top: "inception_5b/pool" + pooling_param { + pool: MAX + kernel_size: 3 + stride: 1 + pad: 1 + } +} +layer { + name: "inception_5b/pool_proj" + type: "Convolution" + bottom: "inception_5b/pool" + top: "inception_5b/pool_proj" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + kernel_size: 1 + weight_filler { + type: "xavier" + std: 0.1 + } + bias_filler { + type: "constant" + value: 0.2 + } + } +} +layer { + name: "inception_5b/relu_pool_proj" + type: "ReLU" + bottom: "inception_5b/pool_proj" + top: "inception_5b/pool_proj" +} +layer { + name: "inception_5b/output" + type: "Concat" + bottom: "inception_5b/1x1" + bottom: "inception_5b/3x3" + bottom: "inception_5b/5x5" + bottom: "inception_5b/pool_proj" + top: "inception_5b/output" +} +layer { + name: "pool5/7x7_s1" + type: "Pooling" + bottom: "inception_5b/output" + top: "pool5/7x7_s1" + pooling_param { + pool: AVE + kernel_size: 7 + stride: 1 + } +} +layer { + name: "pool5/drop_7x7_s1" + type: "Dropout" + bottom: "pool5/7x7_s1" + top: "pool5/7x7_s1" + dropout_param { + dropout_ratio: 0.4 + } +} +layer { + name: "loss3/classifier" + type: "InnerProduct" + bottom: "pool5/7x7_s1" + top: "loss3/classifier" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + inner_product_param { + num_output: 1000 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "prob" + type: "Softmax" + bottom: "loss3/classifier" + top: "prob" +} diff --git a/test/models/deploy.prototxt b/test/models/deploy.prototxt new file mode 100644 index 0000000..a128515 --- /dev/null +++ b/test/models/deploy.prototxt @@ -0,0 +1,1790 @@ +input: "data" +input_shape { + dim: 1 + dim: 3 + dim: 300 + dim: 300 +} + +layer { + name: "data_bn" + type: "BatchNorm" + bottom: "data" + top: "data_bn" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "data_scale" + type: "Scale" + bottom: "data_bn" + top: "data_bn" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "conv1_h" + type: "Convolution" + bottom: "data_bn" + top: "conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + pad: 3 + kernel_size: 7 + stride: 2 + weight_filler { + type: "msra" + variance_norm: FAN_OUT + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv1_bn_h" + type: "BatchNorm" + bottom: "conv1_h" + top: "conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "conv1_scale_h" + type: "Scale" + bottom: "conv1_h" + top: "conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "conv1_relu" + type: "ReLU" + bottom: "conv1_h" + top: "conv1_h" +} +layer { + name: "conv1_pool" + type: "Pooling" + bottom: "conv1_h" + top: "conv1_pool" + pooling_param { + kernel_size: 3 + stride: 2 + } +} +layer { + name: "layer_64_1_conv1_h" + type: "Convolution" + bottom: "conv1_pool" + top: "layer_64_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_64_1_bn2_h" + type: "BatchNorm" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_64_1_scale2_h" + type: "Scale" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_64_1_relu2" + type: "ReLU" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" +} +layer { + name: "layer_64_1_conv2_h" + type: "Convolution" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv2_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_64_1_sum" + type: "Eltwise" + bottom: "layer_64_1_conv2_h" + bottom: "conv1_pool" + top: "layer_64_1_sum" +} +layer { + name: "layer_128_1_bn1_h" + type: "BatchNorm" + bottom: "layer_64_1_sum" + top: "layer_128_1_bn1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_128_1_scale1_h" + type: "Scale" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_bn1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_128_1_relu1" + type: "ReLU" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_bn1_h" +} +layer { + name: "layer_128_1_conv1_h" + type: "Convolution" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_bn2" + type: "BatchNorm" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_128_1_scale2" + type: "Scale" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_128_1_relu2" + type: "ReLU" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" +} +layer { + name: "layer_128_1_conv2" + type: "Convolution" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_conv_expand_h" + type: "Convolution" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_conv_expand_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_sum" + type: "Eltwise" + bottom: "layer_128_1_conv2" + bottom: "layer_128_1_conv_expand_h" + top: "layer_128_1_sum" +} +layer { + name: "layer_256_1_bn1" + type: "BatchNorm" + bottom: "layer_128_1_sum" + top: "layer_256_1_bn1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_256_1_scale1" + type: "Scale" + bottom: "layer_256_1_bn1" + top: "layer_256_1_bn1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_256_1_relu1" + type: "ReLU" + bottom: "layer_256_1_bn1" + top: "layer_256_1_bn1" +} +layer { + name: "layer_256_1_conv1" + type: "Convolution" + bottom: "layer_256_1_bn1" + top: "layer_256_1_conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_bn2" + type: "BatchNorm" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_256_1_scale2" + type: "Scale" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_256_1_relu2" + type: "ReLU" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" +} +layer { + name: "layer_256_1_conv2" + type: "Convolution" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_conv_expand" + type: "Convolution" + bottom: "layer_256_1_bn1" + top: "layer_256_1_conv_expand" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_sum" + type: "Eltwise" + bottom: "layer_256_1_conv2" + bottom: "layer_256_1_conv_expand" + top: "layer_256_1_sum" +} +layer { + name: "layer_512_1_bn1" + type: "BatchNorm" + bottom: "layer_256_1_sum" + top: "layer_512_1_bn1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_512_1_scale1" + type: "Scale" + bottom: "layer_512_1_bn1" + top: "layer_512_1_bn1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_512_1_relu1" + type: "ReLU" + bottom: "layer_512_1_bn1" + top: "layer_512_1_bn1" +} +layer { + name: "layer_512_1_conv1_h" + type: "Convolution" + bottom: "layer_512_1_bn1" + top: "layer_512_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 # 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_bn2_h" + type: "BatchNorm" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_512_1_scale2_h" + type: "Scale" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_512_1_relu2" + type: "ReLU" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" +} +layer { + name: "layer_512_1_conv2_h" + type: "Convolution" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv2_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 2 # 1 + kernel_size: 3 + stride: 1 + dilation: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_conv_expand_h" + type: "Convolution" + bottom: "layer_512_1_bn1" + top: "layer_512_1_conv_expand_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 1 # 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_sum" + type: "Eltwise" + bottom: "layer_512_1_conv2_h" + bottom: "layer_512_1_conv_expand_h" + top: "layer_512_1_sum" +} +layer { + name: "last_bn_h" + type: "BatchNorm" + bottom: "layer_512_1_sum" + top: "layer_512_1_sum" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "last_scale_h" + type: "Scale" + bottom: "layer_512_1_sum" + top: "layer_512_1_sum" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "last_relu" + type: "ReLU" + bottom: "layer_512_1_sum" + top: "fc7" +} + +layer { + name: "conv6_1_h" + type: "Convolution" + bottom: "fc7" + top: "conv6_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_1_relu" + type: "ReLU" + bottom: "conv6_1_h" + top: "conv6_1_h" +} +layer { + name: "conv6_2_h" + type: "Convolution" + bottom: "conv6_1_h" + top: "conv6_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_relu" + type: "ReLU" + bottom: "conv6_2_h" + top: "conv6_2_h" +} +layer { + name: "conv7_1_h" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv7_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_1_relu" + type: "ReLU" + bottom: "conv7_1_h" + top: "conv7_1_h" +} +layer { + name: "conv7_2_h" + type: "Convolution" + bottom: "conv7_1_h" + top: "conv7_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_relu" + type: "ReLU" + bottom: "conv7_2_h" + top: "conv7_2_h" +} +layer { + name: "conv8_1_h" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv8_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_1_relu" + type: "ReLU" + bottom: "conv8_1_h" + top: "conv8_1_h" +} +layer { + name: "conv8_2_h" + type: "Convolution" + bottom: "conv8_1_h" + top: "conv8_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_relu" + type: "ReLU" + bottom: "conv8_2_h" + top: "conv8_2_h" +} +layer { + name: "conv9_1_h" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv9_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_1_relu" + type: "ReLU" + bottom: "conv9_1_h" + top: "conv9_1_h" +} +layer { + name: "conv9_2_h" + type: "Convolution" + bottom: "conv9_1_h" + top: "conv9_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_2_relu" + type: "ReLU" + bottom: "conv9_2_h" + top: "conv9_2_h" +} +layer { + name: "conv4_3_norm" + type: "Normalize" + bottom: "layer_256_1_bn1" + top: "conv4_3_norm" + norm_param { + across_spatial: false + scale_filler { + type: "constant" + value: 20 + } + channel_shared: false + } +} +layer { + name: "conv4_3_norm_mbox_loc" + type: "Convolution" + bottom: "conv4_3_norm" + top: "conv4_3_norm_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv4_3_norm_mbox_loc_perm" + type: "Permute" + bottom: "conv4_3_norm_mbox_loc" + top: "conv4_3_norm_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv4_3_norm_mbox_loc_flat" + type: "Flatten" + bottom: "conv4_3_norm_mbox_loc_perm" + top: "conv4_3_norm_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv4_3_norm_mbox_conf" + type: "Convolution" + bottom: "conv4_3_norm" + top: "conv4_3_norm_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv4_3_norm_mbox_conf_perm" + type: "Permute" + bottom: "conv4_3_norm_mbox_conf" + top: "conv4_3_norm_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv4_3_norm_mbox_conf_flat" + type: "Flatten" + bottom: "conv4_3_norm_mbox_conf_perm" + top: "conv4_3_norm_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv4_3_norm_mbox_priorbox" + type: "PriorBox" + bottom: "conv4_3_norm" + bottom: "data" + top: "conv4_3_norm_mbox_priorbox" + prior_box_param { + min_size: 30.0 + max_size: 60.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 8 + offset: 0.5 + } +} +layer { + name: "fc7_mbox_loc" + type: "Convolution" + bottom: "fc7" + top: "fc7_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "fc7_mbox_loc_perm" + type: "Permute" + bottom: "fc7_mbox_loc" + top: "fc7_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "fc7_mbox_loc_flat" + type: "Flatten" + bottom: "fc7_mbox_loc_perm" + top: "fc7_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "fc7_mbox_conf" + type: "Convolution" + bottom: "fc7" + top: "fc7_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "fc7_mbox_conf_perm" + type: "Permute" + bottom: "fc7_mbox_conf" + top: "fc7_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "fc7_mbox_conf_flat" + type: "Flatten" + bottom: "fc7_mbox_conf_perm" + top: "fc7_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "fc7_mbox_priorbox" + type: "PriorBox" + bottom: "fc7" + bottom: "data" + top: "fc7_mbox_priorbox" + prior_box_param { + min_size: 60.0 + max_size: 111.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 16 + offset: 0.5 + } +} +layer { + name: "conv6_2_mbox_loc" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv6_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_mbox_loc_perm" + type: "Permute" + bottom: "conv6_2_mbox_loc" + top: "conv6_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv6_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv6_2_mbox_loc_perm" + top: "conv6_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv6_2_mbox_conf" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv6_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_mbox_conf_perm" + type: "Permute" + bottom: "conv6_2_mbox_conf" + top: "conv6_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv6_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv6_2_mbox_conf_perm" + top: "conv6_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv6_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv6_2_h" + bottom: "data" + top: "conv6_2_mbox_priorbox" + prior_box_param { + min_size: 111.0 + max_size: 162.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 32 + offset: 0.5 + } +} +layer { + name: "conv7_2_mbox_loc" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv7_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_mbox_loc_perm" + type: "Permute" + bottom: "conv7_2_mbox_loc" + top: "conv7_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv7_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv7_2_mbox_loc_perm" + top: "conv7_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv7_2_mbox_conf" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv7_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_mbox_conf_perm" + type: "Permute" + bottom: "conv7_2_mbox_conf" + top: "conv7_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv7_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv7_2_mbox_conf_perm" + top: "conv7_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv7_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv7_2_h" + bottom: "data" + top: "conv7_2_mbox_priorbox" + prior_box_param { + min_size: 162.0 + max_size: 213.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 64 + offset: 0.5 + } +} +layer { + name: "conv8_2_mbox_loc" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv8_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_mbox_loc_perm" + type: "Permute" + bottom: "conv8_2_mbox_loc" + top: "conv8_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv8_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv8_2_mbox_loc_perm" + top: "conv8_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv8_2_mbox_conf" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv8_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_mbox_conf_perm" + type: "Permute" + bottom: "conv8_2_mbox_conf" + top: "conv8_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv8_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv8_2_mbox_conf_perm" + top: "conv8_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv8_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv8_2_h" + bottom: "data" + top: "conv8_2_mbox_priorbox" + prior_box_param { + min_size: 213.0 + max_size: 264.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 100 + offset: 0.5 + } +} +layer { + name: "conv9_2_mbox_loc" + type: "Convolution" + bottom: "conv9_2_h" + top: "conv9_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_2_mbox_loc_perm" + type: "Permute" + bottom: "conv9_2_mbox_loc" + top: "conv9_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv9_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv9_2_mbox_loc_perm" + top: "conv9_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv9_2_mbox_conf" + type: "Convolution" + bottom: "conv9_2_h" + top: "conv9_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv9_2_mbox_conf_perm" + type: "Permute" + bottom: "conv9_2_mbox_conf" + top: "conv9_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv9_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv9_2_mbox_conf_perm" + top: "conv9_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv9_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv9_2_h" + bottom: "data" + top: "conv9_2_mbox_priorbox" + prior_box_param { + min_size: 264.0 + max_size: 315.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 300 + offset: 0.5 + } +} +layer { + name: "mbox_loc" + type: "Concat" + bottom: "conv4_3_norm_mbox_loc_flat" + bottom: "fc7_mbox_loc_flat" + bottom: "conv6_2_mbox_loc_flat" + bottom: "conv7_2_mbox_loc_flat" + bottom: "conv8_2_mbox_loc_flat" + bottom: "conv9_2_mbox_loc_flat" + top: "mbox_loc" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_conf" + type: "Concat" + bottom: "conv4_3_norm_mbox_conf_flat" + bottom: "fc7_mbox_conf_flat" + bottom: "conv6_2_mbox_conf_flat" + bottom: "conv7_2_mbox_conf_flat" + bottom: "conv8_2_mbox_conf_flat" + bottom: "conv9_2_mbox_conf_flat" + top: "mbox_conf" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_priorbox" + type: "Concat" + bottom: "conv4_3_norm_mbox_priorbox" + bottom: "fc7_mbox_priorbox" + bottom: "conv6_2_mbox_priorbox" + bottom: "conv7_2_mbox_priorbox" + bottom: "conv8_2_mbox_priorbox" + bottom: "conv9_2_mbox_priorbox" + top: "mbox_priorbox" + concat_param { + axis: 2 + } +} + +layer { + name: "mbox_conf_reshape" + type: "Reshape" + bottom: "mbox_conf" + top: "mbox_conf_reshape" + reshape_param { + shape { + dim: 0 + dim: -1 + dim: 2 + } + } +} +layer { + name: "mbox_conf_softmax" + type: "Softmax" + bottom: "mbox_conf_reshape" + top: "mbox_conf_softmax" + softmax_param { + axis: 2 + } +} +layer { + name: "mbox_conf_flatten" + type: "Flatten" + bottom: "mbox_conf_softmax" + top: "mbox_conf_flatten" + flatten_param { + axis: 1 + } +} + +layer { + name: "detection_out" + type: "DetectionOutput" + bottom: "mbox_loc" + bottom: "mbox_conf_flatten" + bottom: "mbox_priorbox" + top: "detection_out" + include { + phase: TEST + } + detection_output_param { + num_classes: 2 + share_location: true + background_label_id: 0 + nms_param { + nms_threshold: 0.45 + top_k: 400 + } + code_type: CENTER_SIZE + keep_top_k: 200 + confidence_threshold: 0.01 + clip: 1 + } +} diff --git a/test/models/googlenet-9.onnx b/test/models/googlenet-9.onnx new file mode 100644 index 0000000..f299315 Binary files /dev/null and b/test/models/googlenet-9.onnx differ diff --git a/test/models/res10_300x300_ssd_iter_140000.caffemodel b/test/models/res10_300x300_ssd_iter_140000.caffemodel new file mode 100644 index 0000000..809dfd7 Binary files /dev/null and b/test/models/res10_300x300_ssd_iter_140000.caffemodel differ diff --git a/test/models/tensorflow_inception_graph.pb b/test/models/tensorflow_inception_graph.pb new file mode 100644 index 0000000..b71afb3 Binary files /dev/null and b/test/models/tensorflow_inception_graph.pb differ