From 4401f681d33f534a7d7ef8f4f940bd54b60710c3 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sun, 18 Sep 2022 01:52:26 -0400 Subject: Move stuff around to accommodate new family members. --- xsig/include/signature.hpp | 83 +++++++++++++++++++++++++++ xsig/include/signature_db.hpp | 109 ++++++++++++++++++++++++++++++++++++ xsig/include/subslice_signature.hpp | 36 ++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 xsig/include/signature.hpp create mode 100644 xsig/include/signature_db.hpp create mode 100644 xsig/include/subslice_signature.hpp (limited to 'xsig/include') diff --git a/xsig/include/signature.hpp b/xsig/include/signature.hpp new file mode 100644 index 0000000..b655e73 --- /dev/null +++ b/xsig/include/signature.hpp @@ -0,0 +1,83 @@ +//Chris Xiong 2022 +//License: MPL-2.0 +#ifndef SIGNATURE_HPP +#define SIGNATURE_HPP + +#include +#include +#include + +struct signature_config +{ + int slices; + int blur_window; + int min_window; + bool crop; + bool compress; + double pr; + double noise_threshold; + double contrast_threshold; + double max_cropping; +}; + +namespace cv +{ + class Mat; +}; + +class signature_priv; +class signature +{ +private: + std::shared_ptr p; + signature(signature_priv* _p); + signature(const signature&)=default; + signature& operator=(const signature&)=default; +public: + signature(); + ~signature(); + signature(signature&&)=default; + signature& operator=(signature&&)=default; + signature clone() const;//do not use unless absolutely needed + void dump() const; + bool valid() const; + double length() const; + double distance(const signature &o) const; + bool operator ==(const signature &o) const; + std::string to_string() const; + + static signature from_string(std::string &&s); + + static signature from_path(const std::filesystem::path &path, const signature_config &cfg); + + static signature from_file(const char *fn, const signature_config &cfg); + + /* + * Input will be stripped of alpha channel (by blending with white), + * converted to single channel (rgb2gray). + * Then it will be passed to from_preprocessed_matrix. + * The matrix doesn't have to be continuous. + */ + static signature from_cvmatrix(cv::Mat *m, const signature_config &cfg); + + /* + * Input must be a single channel, floating point matrix + * (values clamped to 0-1) + * The matrix must be continuous if cropping is used + * STILL *Will* be cropped if config().crop == true + * STILL *Will* be blurred if config().blur_window > 1 + */ + static signature from_preprocessed_matrix(cv::Mat *m, const signature_config &cfg); + + static signature_config default_cfg(); + + friend class signature_priv; + friend struct signature_hash; +}; + +struct signature_hash +{ + size_t operator()(signature const& sig) const noexcept; +}; + +#endif diff --git a/xsig/include/signature_db.hpp b/xsig/include/signature_db.hpp new file mode 100644 index 0000000..b37cf0a --- /dev/null +++ b/xsig/include/signature_db.hpp @@ -0,0 +1,109 @@ +//Chris Xiong 2022 +//License: MPL-2.0 +#ifndef SIGNATURE_DB_HPP +#define SIGNATURE_DB_HPP + +#include +#include +#include + +#include "signature.hpp" + +namespace fs = std::filesystem; + +struct subslice_t {size_t id; size_t slice;}; + +struct dupe_t {size_t id1, id2; double distance;}; + +struct populate_cfg_t +{ + size_t nsliceh; + size_t nslicev; + signature_config scfg_full; + signature_config scfg_subslice; + double threshold; + std::function callback; + int njobs; +}; + +struct signature_db_priv; + +class signature_db +{ +private: + signature_db_priv *p; +public: + //open a signature database + //if dbpath is an empty path (default), the database will reside in RAM + //and will be automatically initialized + //otherwise it opens the database specified by dbpath + //if the database specified by dbpath doesn't exist, it will be created + //and initialized + //if the database file exists but is not a valid signature database, it + //will be immediately closed and any subsequent calls to this signature db + //object will do nothing. The object will be marked invalid. + signature_db(const fs::path &dbpath = fs::path()); + ~signature_db(); + + bool valid(); + + //insert image signature into database + //if id is omitted, it's assigned automatically and returned + //if specificted, id must be unique + //treat automatically assigned id as arbitrary opaque integers + size_t put_signature(const fs::path &path, const signature &sig, size_t id = ~size_t(0)); + void batch_get_signature_begin(); + //get image signature from database + std::pair get_signature(size_t id); + void batch_get_signature_end(); + + //place batch_put_subslice_begin() and batch_put_subslice_end() around a group of + //put_subslice() calls to improve performance + void batch_put_subslice_begin(); + //insert subslice into database + //(id, slice) must be unique + //calling put_subslice_begin() before this is NOT required, but + //will improve performance + void put_subslice(size_t id, size_t slice, const signature &slicesig); + void batch_put_subslice_end(); + + //same thing as put_subslice_begin() + void batch_find_subslice_begin(); + //find identical subslices from database + std::vector find_subslice(const signature &slicesig); + void batch_find_subslice_end(); + + void put_dupe_pair(size_t ida, size_t idb, double dist); + std::vector dupe_pairs(); + + void lock(); + void unlock(); + + bool to_db_file(const fs::path &path); + bool from_db_file(const fs::path &path); + + void populate(const std::vector &paths, const populate_cfg_t &cfg); + + //disjoint set for keeping similar images in the same group + //some of these probably shouldn't be public. TBD... + void ds_init(); + + void batch_ds_get_parent_begin(); + size_t ds_get_parent(size_t id); + void batch_ds_get_parent_end(); + + void batch_ds_set_parent_begin(); + size_t ds_set_parent(size_t id, size_t par); + void batch_ds_set_parent_end(); + + size_t ds_find(size_t id); + void ds_merge(size_t id1, size_t id2); + + //group similar images together using results from dupe_pairs() + //usually very fast, unless you have a crack ton of duplicates... + void group_similar(); + //get all groups, each countained in their own lists. + std::vector> groups_get(); +}; + +#endif diff --git a/xsig/include/subslice_signature.hpp b/xsig/include/subslice_signature.hpp new file mode 100644 index 0000000..928d396 --- /dev/null +++ b/xsig/include/subslice_signature.hpp @@ -0,0 +1,36 @@ +//Chris Xiong 2022 +//License: MPL-2.0 +#ifndef SUBSLICE_SIGNATURE_HPP +#define SUBSLICE_SIGNATURE_HPP +#include "signature.hpp" + +#include +#include + +namespace cv +{ + class Mat; +}; + +class subsliced_signature +{ +public: + signature full; + std::vector subslices; + size_t nhslices, nvslices; + + static subsliced_signature from_path(const std::filesystem::path &path, + size_t nhslices, size_t nvslices, + const signature_config &fcfg, + const signature_config &scfg); + static subsliced_signature from_file(const char *fn, + size_t nhslices, size_t nvslices, + const signature_config &fcfg, + const signature_config &scfg); + static subsliced_signature from_cvmatrix(cv::Mat *m, + size_t nhslices, size_t nvslices, + const signature_config &fcfg, + const signature_config &scfg); +}; + +#endif -- cgit v1.2.3