Rust-OpenCV binding

因為無聊開始研究如何在 Rust 中呼叫 OpenCV 的 C++ API。使用 Rust 呼叫 C++ 函式可以減少 memory leak, core dumped 發生的機率,並且可以使用 Rust 的套件建置 REST API。

1. opencv-rust:

本篇使用 opencv-rust,在 Cargo.toml 中加入 opencv 依賴:

[package]
name = "rust_test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
opencv = "0.66"

2. 設定環境變數:

opencv-rust 需要設定環境變數 OPENCV_LINK_LIBS, OPENCV_LINK_PATHS 及 OPENCV_INCLUDE_PATHS 才能呼叫對應的 API。

這些變數通常在用 CMake Build C++ 時也常常會用到,例如:

find_package(OpenCV 4 REQUIRED)
message(STATUS "** OpenCV status **")
message(STATUS "OpenCV version: ${OpenCV_VERSION}")
message(STATUS "OpenCV lib path: ${OpenCV_LIBS}")
message(STATUS "OpenCV include path: ${OpenCV_INCLUDE_DIRS}")
message(STATUS "OpenCV CUDA version: ${OpenCV_CUDA_VERSION}")

建立一個 build.sh,依照安裝的路徑設定環境變數 OPENCV_LINK_LIBS, OPENCV_LINK_PATHS 及 OPENCV_INCLUDE_PATHS:

#!/bin/sh

export OPENCV_LINK_LIBS=opencv_calib3d,opencv_core,opencv_dnn,opencv_features2d,opencv_flann,opencv_gapi,opencv_highgui,opencv_imgcodecs,opencv_imgproc,opencv_ml,opencv_objdetect,opencv_photo,opencv_stitching,opencv_video,opencv_videoio,opencv_alphamat,opencv_aruco,opencv_barcode,opencv_bgsegm,opencv_bioinspired,opencv_ccalib,opencv_datasets,opencv_dnn_objdetect,opencv_dnn_superres,opencv_dpm,opencv_face,opencv_freetype,opencv_fuzzy,opencv_hfs,opencv_img_hash,opencv_intensity_transform,opencv_line_descriptor,opencv_mcc,opencv_optflow,opencv_phase_unwrapping,opencv_plot,opencv_quality,opencv_rapid,opencv_reg,opencv_rgbd,opencv_saliency,opencv_shape,opencv_stereo,opencv_structured_light,opencv_superres,opencv_surface_matching,opencv_text,opencv_tracking,opencv_videostab,opencv_wechat_qrcode,opencv_xfeatures2d,opencv_ximgproc,opencv_xobjdetect,opencv_xphoto
export OPENCV_LINK_PATHS=/usr/local/lib
export OPENCV_INCLUDE_PATHS=/usr/local/include/opencv4

cargo build
cargo run

3. 使用範例:

main.rs 範例如下,opencv-rust 利用 Rust 的 null check 及 borrow 機制提高程式的安全性 (C++ 也可以做 null check,但工程師有時候會忽略就會不小心使用空指標)。

use opencv::{
    prelude::*,
    highgui,
    imgcodecs
};

fn main() {
    let image = imgcodecs::imread("kanahei.png", 1);
    if let Ok(img) = image {
        highgui::imshow("Hello CV", &img);
        highgui::wait_key(0);
    }
}

Ref:

  1. Github for opencv-rust: opencv-rust 使用說明及環境變數設定。
  2. Crate opencv: OpenCV Rust API 的使用說明書。

留言

熱門文章