Honwhy Wang
Honwhy Wang

Reputation: 118

use opencv-rust to do flip

I am new to opencv, just manage to follow opencv-rust api, compose these codes to do flip, but somehow it won't work. any suggestion?

Cargo.toml

[package]
name = "op"
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.62"
bytes = "1"
anyhow = "1"

main.rs

use anyhow::Result;
use opencv::{
    core::{self, Mat, Vector},
    imgcodecs,
    prelude::*,
};

use bytes::Bytes;
fn main() -> Result<()> {
    let data = include_bytes!("../rust-logo.png");
    let src = Mat::from_slice::<u8>(data.as_ref())?;
    let dest = imgcodecs::imdecode(&src, imgcodecs::IMREAD_COLOR);
    //flip
    let mut dest = Mat::default();
    core::flip(&src, &mut dest, 0);
    let mut params: Vector<i32> = Vector::new();
    params.push(imgcodecs::ImwriteFlags::IMWRITE_JPEG_QUALITY as i32);
    imgcodecs::imwrite(&"rust-logo-flip.png", &dest, &params)?;
    Ok(())
}

to run the code, first install opencv llvm, eg. brew install opencv llvm ; export environment pathexport DYLD_FALLBACK_LIBRARY_PATH="$(xcode-select --print-path)/usr/lib/"

Upvotes: 0

Views: 875

Answers (1)

frankenapps
frankenapps

Reputation: 8241

As already mentioned in the comments you are hiding the first dest variable. Apart from that imgcodecs::imdecode() returns a result, that you will have to unwrap first.

This is a version of your code with as little changes as needed to make it work:

use anyhow::Result;
use opencv::{
    core::{self, Mat, Vector},
    imgcodecs,
};

fn main() -> Result<()> {
    let data = include_bytes!("../rust-logo.png");
    let src = Mat::from_slice::<u8>(data.as_ref())?;
    let src_decoded = imgcodecs::imdecode(&src, imgcodecs::IMREAD_COLOR)?;
    //flip
    let mut dest = Mat::default();
    core::flip(&src_decoded, &mut dest, 0)?;
    let mut params: Vector<i32> = Vector::new();
    params.push(imgcodecs::ImwriteFlags::IMWRITE_JPEG_QUALITY as i32);
    imgcodecs::imwrite(&"rust-logo-flip.png", &dest, &params)?;
    Ok(())
}

However there is a catch. If you use the rust logo, it will probably have the black logo on a transparent background. This will result in an all black image, if you write to a PNG without transparency as you currently do. However this has nothing to do with the flip operation, it is just some maybe unintuitive behaviour.

For this reason I would suggest flipping the image as shown below:

use anyhow::Result;
use opencv::{
    core::{self, Mat, Vector},
    imgcodecs,
};

fn main() -> Result<()> {
    let src_decoded = imgcodecs::imread("rust-logo.png", imgcodecs::IMREAD_UNCHANGED)?;

    // Flip image
    let mut dest = Mat::default();
    core::flip(&src_decoded, &mut dest, 0)?;

    let params: Vector<i32> = Vector::new();
    imgcodecs::imwrite("rust-logo-flip.png", &dest, &params)?;
    Ok(())
}

Upvotes: 3

Related Questions