我们都知道为什么 Rust 如此出色。然而,与 C/C++ 等老巨头相比,它有点过于新颖和闪亮,我们经常需要在没有适当文档的情况下使用 C++ 绑定。
背景
现在,让我们首先回答这个问题,我们为什么要关心在 Rust 中运行 OpenCV?为什么不直接使用 C++、Java 或 Python?
C++ 是相当古老的冠军,与 Rust 或 Go 相比,编译 C++ 代码并不有趣。对于在 Python 中长大的年轻一代来说,用 C++ 安装包似乎很中世纪。
谁愿意花时间安装软件包?尤其是今天有这么多优秀和强大的人。Rust 的包管理器 Cargo 非常棒。
在 Python 中使用 OpenCV 很容易。易于安装,易于在庞大的社区中使用。如果你真的想把事情做好,Python 就是你要走的路。尽管 Python 语言速度非常慢,但实际上,很少的代码行是 Python 代码的一大特点。
如果你只是想做一些需要 for 循环的额外功能呢? 或者如果你想并行运行这些东西呢? Python可以做,只是不太好用。
Rust 的 OpenCV
入门 - 安装 (MacOS)
Linux 用户通常足够聪明,可以弄清楚如何在他们的机器上安装 OpenCV,否则请按照此处的指南进行操作:https://github.com/twistedfall/opencv-rust
Windows 用户可以按照本指南进行操作:https://github.com/twistedfall/opencv-rust
对于 Mac 用户,你可以按照下面的超短教程进行操作。
让我们从安装 OpenCV 开始。不幸的是,OpenCV 不是另一个 Rust 包。它需要在你的计算机上安装 OpenCV (C++)。
然而,在 Rust 中,不需要痛苦的链接和编写 CMake 文件。Rust 中的 OpenCV 实际上比使用 C++ 更容易,并且当你想要引入许多依赖项(大量 CMake 文件的 gulp)时不会让你头疼。
在 macOS 上安装它非常容易。假设你有 brew,那么只需要运行:
brew install opencv
然后在你的 cargo.toml 添加
[dependencies]
opencv = "0.63.0" # or whatever version is the latest
你可以按照 opencv-rust 存储库获取完整的安装帮助:https://github.com/twistedfall/opencv-rust
当安装它时,在编译时遇到了问题,但可以按照故障排除部分轻松修复。因此,如果你遇到问题,请确保在抓头发之前检查该部分。
这个 OpenCV Rust 绑定到 C++ API(这很好,因为 C 已经被废弃了)。
由于 Rust 可以直接与 C 接口,C++ 被包装在一个额外的 C 层中,然后暴露给 Rust。
简单代码
第一个示例将基于 Makeitnow 的视频教程:
https://www.youtube.com/watch?v=zcfixnuJFXg
对于有经验的 OpenCV 用户来说,这非常简单。
使用 anyhow 来处理结果:https://docs.rs/anyhow/latest/anyhow/
所以将使用它而不是 opencv::Result。
让我们写代码吧!
use anyhow::Result; // Automatically handle the error types
use opencv::{
prelude::*,
videoio,
highgui
}; // Note, the namespace of OpenCV is changed (to better or worse). It is no longer one enormous.
fn main() -> Result<()> { // Note, this is anyhow::Result
// Open a GUI window
highgui::named_window("window", highgui::WINDOW_FULLSCREEN)?;
// Open the web-camera (assuming you have one)
let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?;
let mut frame = Mat::default(); // This array will store the web-cam data
// Read the camera
// and display in the window
loop {
cam.read(&mut frame)?;
highgui::imshow("window", &frame)?;
let key = highgui::wait_key(1)?;
if key == 113 { // quit with q
break;
}
}
Ok(())
}
太棒了