#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_imports)]
#![allow(unused_mut)]
#![allow(unused_assignments)]
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#![allow(rustdoc::missing_crate_level_docs)]
#![allow(unsafe_code)]
#![allow(clippy::undocumented_unsafe_blocks)]
#![allow(unused_must_use)]
#![allow(non_snake_case)]
use image::{
open, ImageBuffer, Rgb, DynamicImage
};
use imageproc::{
drawing::draw_cross_mut, drawing::draw_line_segment_mut
};
use bye_orb_rs::{
orb, fast, common::Matchable
};
use std::time::Instant;
fn main() {
let img1_path = "./assets/test/167.png";
let img2_path = "./assets/test/189.png";
main_orb(img1_path, img2_path);
}
fn main_orb(img1_path: &str, img2_path: &str) {
let mut img1 = open(img1_path).unwrap();
let mut img2 = open(img2_path).unwrap();
let n_keypoints = 20;
let start_time = Instant::now();
let img1_keypoints = orb::orb(&mut img1, n_keypoints).unwrap();
let img2_keypoints = orb::orb(&mut img2, n_keypoints).unwrap();
let end_time = Instant::now();
println!("提取ORB特征点耗时: {:?} 秒", end_time - start_time);
let start_time = Instant::now();
let pair_indices = orb::match_brief(&img1_keypoints, &img2_keypoints);
let end_time = Instant::now();
println!("匹配ORB特征点耗时: {:?} 秒", end_time - start_time);
let mut matches: Vec<(usize, usize, f32)> = pair_indices.iter()
.map(|&(i, j)| (i, j, img1_keypoints[i].distance(&img2_keypoints[j]) as f32))
.collect();
matches.sort_by(|a, b| a.2.partial_cmp(&b.2).unwrap());
let min_dist = matches[0].2;
let max_dist = matches[matches.len() - 1].2;
println!("-- 最大距离: {}", max_dist);
println!("-- 最小距离: {}", min_dist);
let good_matches: Vec<(usize, usize, f32)> = matches.iter()
.filter(|&&(_, _, dist)| dist <= (2.0 * min_dist).max(30.0))
.cloned()
.collect();
let mut img1_rgb = img1.to_rgb8();
let mut img2_rgb = img2.to_rgb8();
for &(i, j, _) in &matches {
let kp1 = (img1_keypoints[i].x, img1_keypoints[i].y);
let kp2 = (img2_keypoints[j].x, img2_keypoints[j].y);
let color = Rgb([0, 255, 0]);
draw_cross_mut(&mut img1_rgb, color, kp1.0 as i32, kp1.1 as i32);
draw_cross_mut(&mut img2_rgb, color, kp2.0 as i32, kp2.1 as i32);
}
img1_rgb.save("./result/all_matches.png").unwrap();
img2_rgb.save("./result/all_matches2.png").unwrap();
let mut img1_rgb_good = img1.to_rgb8();
let mut img2_rgb_good = img2.to_rgb8();
for &(i, j, _) in &good_matches {
let kp1 = (img1_keypoints[i].x, img1_keypoints[i].y);
let kp2 = (img2_keypoints[j].x, img2_keypoints[j].y);
let color = Rgb([0, 255, 0]);
draw_cross_mut(&mut img1_rgb_good, color, kp1.0 as i32, kp1.1 as i32);
draw_cross_mut(&mut img2_rgb_good, color, kp2.0 as i32, kp2.1 as i32);
}
img1_rgb_good.save("./result/good_matches.png").unwrap();
img2_rgb_good.save("./result/good_matches2.png").unwrap();
let (width1, height1) = img1_rgb.dimensions();
let (width2, height2) = img2_rgb.dimensions();
let total_width = width1 + width2;
let max_height = height1.max(height2);
let mut combined_image = ImageBuffer::new(total_width, max_height);
for y in 0..height1 {
for x in 0..width1 {
combined_image.put_pixel(x, y, *img1_rgb.get_pixel(x, y));
}
}
for y in 0..height2 {
for x in 0..width2 {
combined_image.put_pixel(width1 + x, y, *img2_rgb.get_pixel(x, y));
}
}
for &(i, j, _) in &good_matches {
let kp1 = (img1_keypoints[i].x, img1_keypoints[i].y);
let kp2 = (img2_keypoints[j].x, img2_keypoints[j].y);
let color = Rgb([0, 255, 0]);
draw_line_segment_mut(
&mut combined_image,
(kp1.0 as f32, kp1.1 as f32),
((width1 as f32 + kp2.0 as f32), kp2.1 as f32),
color,
);
}
combined_image.save("./result/combined_matches.png").unwrap();
}