1
0
Fork 0
mirror of synced 2024-04-28 17:42:26 +12:00

Add very small similarity level to finding similar images, add option to choose level from CLI, fix bug with duplicated entries in similar pictures (#104)

This commit is contained in:
Rafał Mikrut 2020-11-09 12:55:27 +01:00 committed by GitHub
parent 2815692205
commit 29a0716be5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 55 additions and 8 deletions

View file

@ -1,5 +1,6 @@
use czkawka_core::duplicate::{CheckingMethod, DeleteMethod};
use czkawka_core::same_music::MusicSimilarity;
use czkawka_core::similar_images::Similarity;
use std::path::PathBuf;
use structopt::StructOpt;
@ -99,6 +100,8 @@ pub enum Commands {
excluded_directories: ExcludedDirectories,
#[structopt(short, long, parse(try_from_str = parse_minimal_file_size), default_value = "16384", help = "Minimum size in bytes", long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching")]
minimal_file_size: u64,
#[structopt(short, long, default_value = "High", parse(try_from_str = parse_similar_images_similarity), help = "Similairty level (VerySmall, Small, Medium, High, Very High)", long_help = "Methods to choose similarity level of images which will be considered as duplicated.")]
similarity: Similarity,
#[structopt(flatten)]
excluded_items: ExcludedItems,
#[structopt(flatten)]
@ -218,6 +221,17 @@ fn parse_delete_method(src: &str) -> Result<DeleteMethod, &'static str> {
}
}
fn parse_similar_images_similarity(src: &str) -> Result<Similarity, &'static str> {
match src.to_ascii_lowercase().replace('_', "").as_str() {
"verysmall" => Ok(Similarity::VerySmall),
"small" => Ok(Similarity::Small),
"medium" => Ok(Similarity::Medium),
"high" => Ok(Similarity::High),
"veryhigh" => Ok(Similarity::VeryHigh),
_ => Err("Couldn't parse the delete method (allowed: verysmall, small, medium, high, veryhigh)"),
}
}
fn parse_minimal_file_size(src: &str) -> Result<u64, String> {
match src.parse::<u64>() {
Ok(minimal_file_size) => {

View file

@ -199,6 +199,7 @@ fn main() {
excluded_items,
file_to_save,
minimal_file_size,
similarity,
not_recursive,
} => {
let mut sf = SimilarImages::new();
@ -208,6 +209,7 @@ fn main() {
sf.set_excluded_items(path_list_to_str(excluded_items.excluded_items));
sf.set_minimal_file_size(minimal_file_size);
sf.set_recursive_search(!not_recursive.not_recursive);
sf.set_similarity(similarity);
sf.find_similar_images(None);

View file

@ -16,9 +16,10 @@ use std::io::Write;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub enum Similarity {
None,
VerySmall,
Small,
Medium,
High,
@ -320,7 +321,8 @@ impl SimilarImages {
Similarity::High => 1,
Similarity::Medium => 2,
Similarity::Small => 3,
_ => panic!("0-3 similarity levels are allowed, check if not added more."),
Similarity::VerySmall => 4,
_ => panic!("0-4 similarity levels are allowed, check if not added more."),
};
// TODO
@ -336,6 +338,11 @@ impl SimilarImages {
if stop_receiver.is_some() && stop_receiver.unwrap().try_recv().is_ok() {
return false;
}
if !hashes_to_check.contains_key(hash) {
continue;
}
hashes_to_check.remove(hash);
let vector_with_found_similar_hashes = self.bktree.find(hash, similarity).collect::<Vec<_>>();
if vector_with_found_similar_hashes.len() == 1 && vec_file_entry.len() == 1 {
// This one picture doesn't have similar pictures, so there is no go
@ -375,7 +382,8 @@ impl SimilarImages {
1 => Similarity::High,
2 => Similarity::Medium,
3 => Similarity::Small,
_ => panic!("0-3 similarity levels are allowed, check if not added more."),
4 => Similarity::VerySmall,
_ => panic!("0-4 similarity levels are allowed, check if not added more."),
},
})
.collect::<Vec<_>>()),
@ -503,6 +511,7 @@ impl PrintResults for SimilarImages {
fn get_string_from_similarity(similarity: &Similarity) -> &str {
match similarity {
Similarity::VerySmall => "Very Small",
Similarity::Small => "Small",
Similarity::Medium => "Medium",
Similarity::High => "High",

View file

@ -1131,6 +1131,21 @@ Author: Rafał Mikrut
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radio_button_similar_images_very_small">
<property name="label" translatable="yes">Very Small</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">radio_button_similar_images_very_high</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radio_button_similar_images_small">
<property name="label" translatable="yes">Small</property>
@ -1143,7 +1158,7 @@ Author: Rafał Mikrut
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
<child>
@ -1158,7 +1173,7 @@ Author: Rafał Mikrut
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
<child>
@ -1174,7 +1189,7 @@ Author: Rafał Mikrut
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
<child>
@ -1189,7 +1204,7 @@ Author: Rafał Mikrut
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
<property name="position">5</property>
</packing>
</child>
</object>

View file

@ -32,6 +32,7 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender<Message>) {
let radio_button_duplicates_size = gui_data.radio_button_duplicates_size.clone();
let radio_button_duplicates_hashmb = gui_data.radio_button_duplicates_hashmb.clone();
let radio_button_duplicates_hash = gui_data.radio_button_duplicates_hash.clone();
let radio_button_similar_images_very_small = gui_data.radio_button_similar_images_very_small.clone();
let radio_button_similar_images_small = gui_data.radio_button_similar_images_small.clone();
let radio_button_similar_images_medium = gui_data.radio_button_similar_images_medium.clone();
let radio_button_similar_images_high = gui_data.radio_button_similar_images_high.clone();
@ -203,7 +204,9 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender<Message>) {
};
let similarity;
if radio_button_similar_images_small.get_active() {
if radio_button_similar_images_very_small.get_active() {
similarity = similar_images::Similarity::VerySmall;
} else if radio_button_similar_images_small.get_active() {
similarity = similar_images::Similarity::Small;
} else if radio_button_similar_images_medium.get_active() {
similarity = similar_images::Similarity::Medium;

View file

@ -103,6 +103,7 @@ pub struct GuiData {
pub radio_button_duplicates_hashmb: gtk::RadioButton,
pub radio_button_duplicates_hash: gtk::RadioButton,
pub radio_button_similar_images_very_small: gtk::RadioButton,
pub radio_button_similar_images_small: gtk::RadioButton,
pub radio_button_similar_images_medium: gtk::RadioButton,
pub radio_button_similar_images_high: gtk::RadioButton,
@ -286,6 +287,7 @@ impl GuiData {
let radio_button_duplicates_hashmb: gtk::RadioButton = builder.get_object("radio_button_duplicates_hashmb").unwrap();
let radio_button_duplicates_hash: gtk::RadioButton = builder.get_object("radio_button_duplicates_hash").unwrap();
let radio_button_similar_images_very_small: gtk::RadioButton = builder.get_object("radio_button_similar_images_very_small").unwrap();
let radio_button_similar_images_small: gtk::RadioButton = builder.get_object("radio_button_similar_images_small").unwrap();
let radio_button_similar_images_medium: gtk::RadioButton = builder.get_object("radio_button_similar_images_medium").unwrap();
let radio_button_similar_images_high: gtk::RadioButton = builder.get_object("radio_button_similar_images_high").unwrap();
@ -391,6 +393,7 @@ impl GuiData {
radio_button_duplicates_size,
radio_button_duplicates_hashmb,
radio_button_duplicates_hash,
radio_button_similar_images_very_small,
radio_button_similar_images_small,
radio_button_similar_images_medium,
radio_button_similar_images_high,

View file

@ -221,6 +221,7 @@ pub fn hide_all_buttons_except(except_name: &str, buttons_array: &[gtk::Button],
pub fn get_text_from_similarity(similarity: &Similarity) -> &str {
match similarity {
Similarity::None => "Original",
Similarity::VerySmall => "Very Small",
Similarity::Small => "Small",
Similarity::Medium => "Medium",
Similarity::High => "High",