画像・動画・カメラ入力を扱うインターフェイスのライブラリをRustで作って公開した
概要
- 動画像処理において、カメラinput・mp4動画・1枚の画像を使いながらデバッグすることが多いと思う(特にロボット系は)
- 画像処理は共通で扱わないとバグるので各々のインターフェイスに合わせて画像処理に食わせるまで実装することが多い
- それらを共通のinterfaceで扱えるようにして、argとかで簡単に切り替えて使えるようにしたcrateを公開した
simple-image-interface-rs について
if args.len() < 2 || &args[1] == "pic" {
interface = SimpleImageInterface::new_picture("./data/from_raw.png");
} else if &args[1] == "video" {
interface = SimpleImageInterface::new_video("./data/random_ball.mp4");
} else {
interface = SimpleImageInterface::new_camera("/dev/video0", 640, 360, 330);
// width, height, fps
}
let mut frame_index = 0;
loop {
frame_index += 1;
let input_image = interface.get_frame();
if input_image.is_none() {
break;
}
my_image_proc(&input_image.unwrap(), frame_index);
}
利用するCrateのsurvey
rscam
camera
.start(&rscam::Config {
interval: (1, 50), // fps.
resolution: (width, height),
format: b"RGB3",
..Default::default()
})
.unwrap();
let frame = camera.capture().unwrap();
- frame to image::RGBImageにはto_vecを用いる
let rgb_image_2 = image::RgbImage::from_vec(width, height, (&frame[..]).to_vec()).unwrap();
その他crate検討 for カメラ
rust-ffmpeg
// ラムダ式
let mut receive_and_process_decoded_frames =
|decoder: &mut ffmpeg::decoder::Video| -> Result<(), ffmpeg::Error> {
let mut decoded = Video::empty();
// 有効フレームかどうか
// 最初数フレームは落ちていることもある
// frame : ffmpeg::util::frame::video::Video
while decoder.receive_frame(&mut decoded).is_ok() {
let mut rgb_frame = Video::empty();
// frameの取り出し
scaler.run(&decoded, &mut rgb_frame)?;
save_file(&rgb_frame, frame_index).unwrap();
frame_index += 1;
}
Ok(())
};
let mut packet_index = 0;
for (stream, packet) in ictx.packets() {
packet_index += 1;
println!("packet {}", packet_index);
// ビデオの終わりかを判定
if stream.index() == video_stream_index {
decoder.send_packet(&packet)?;
// ラムダ式に受け渡し
receive_and_process_decoded_frames(&mut decoder)?;
} else {
println!("End of video");
}
}
decoder.send_eof()?;
receive_and_process_decoded_frames(&mut decoder)?;
その他crate検討 for 動画
- rust-ffmpeg-frame-grabber
- mp4parse-rust
作る時につまずいたところ
publishする時のアップロードサイズ制限
- テスト用にサンプル動画を置いてあったんだけど、どうやら cargo publish のとき、10M以上のファイルがあるとエラーを吐く
error: failed to publish to registry at https://crates.io
Caused by:
the remote server responded with an error: max upload size is: 10485760
- ので動画の長さを1/5くらいにする必要があった
- 2021/09/07 追記
include = ["src/lib.rs", "LICENSE", "README.md"]
最後に