Loading docs/source/api_doc/metrics/ccip.benchmark.py +4 −4 Original line number Diff line number Diff line import random from benchmark import BaseBenchmark, create_plot_cli from imgutils.metrics.ccip import get_ccip_features, get_ccip_similarity, _VALID_MODEL_NAMES from imgutils.metrics.ccip import batch_ccip_features, get_ccip_difference, _VALID_MODEL_NAMES class CCIPFeatureBenchmark(BaseBenchmark): Loading @@ -19,7 +19,7 @@ class CCIPFeatureBenchmark(BaseBenchmark): def run(self): image_file = random.choice(self.all_images) _ = get_ccip_features([image_file], model_name=self.model_name) _ = batch_ccip_features([image_file], model_name=self.model_name) class CCIPDiffBenchmark(BaseBenchmark): Loading @@ -28,7 +28,7 @@ class CCIPDiffBenchmark(BaseBenchmark): self.model_name = model_name def prepare(self): self.feats = list(get_ccip_features(random.sample(self.all_images, k=30), model_name=self.model_name)) self.feats = list(batch_ccip_features(random.sample(self.all_images, k=30), model_name=self.model_name)) def load(self): from imgutils.metrics.ccip import _open_metric_model Loading @@ -41,7 +41,7 @@ class CCIPDiffBenchmark(BaseBenchmark): def run(self): feat1 = random.choice(self.feats) feat2 = random.choice(self.feats) _ = get_ccip_similarity(feat1, feat2, model_name=self.model_name) _ = get_ccip_difference(feat1, feat2, model_name=self.model_name) if __name__ == '__main__': Loading imgutils/metrics/__init__.py +1 −0 Original line number Diff line number Diff line Loading @@ -3,5 +3,6 @@ Overview: Tools for computing visual metrics. """ from .aesthetic import * from .ccip import * from .lpips import * from .psnr_ import * imgutils/metrics/ccip.py +34 −45 Original line number Diff line number Diff line import json from functools import lru_cache from typing import Union, List import numpy as np from PIL import Image from huggingface_hub import hf_hub_download from sklearn.cluster import DBSCAN from tqdm.auto import tqdm from ..data import MultiImagesTyping, load_images, ImageTyping from ..utils import open_onnx_model __all__ = [ 'get_ccip_features', 'get_ccip_similarity', 'batch_ccip_similarity', 'ccip_clustering', 'get_ccip_feature', 'batch_ccip_features', 'get_ccip_difference', 'batch_ccip_differences', ] Loading @@ -35,29 +34,39 @@ def _preprocess_image(image: Image.Image, size: int = 384): @lru_cache() def _open_feat_model(model_name): return open_onnx_model(hf_hub_download( f'deepghs/imgutils-models', f'ccip/{model_name}_feat.onnx', f'deepghs/ccip_onnx', f'{model_name}/model_feat.onnx', )) @lru_cache() def _open_metric_model(model_name, safe: bool = False): def _open_metric_model(model_name): return open_onnx_model(hf_hub_download( f'deepghs/imgutils-models', f'ccip/{model_name}_{"safe_" if safe else ""}metrics.onnx', f'deepghs/ccip_onnx', f'{model_name}/model_metrics.onnx', )) _VALID_MODEL_NAMES = [ # 'ccip-caformer-23_randaug_fp32', 'ccip-caformer-5_fp32', 'ccip-caformer-4_fp32', 'ccip-caformer-2_fp32', ] _DEFAULT_MODEL_NAMES = _VALID_MODEL_NAMES[0] @lru_cache() def _open_metrics(model_name): with open(hf_hub_download(f'deepghs/ccip_onnx', f'{model_name}/metrics.json'), 'r') as f: return json.load(f) @lru_cache() def _open_cluster_metrics(model_name): with open(hf_hub_download(f'deepghs/ccip_onnx', f'{model_name}/cluster.json'), 'r') as f: return json.load(f) _DEFAULT_MODEL_NAMES = 'ccip-caformer-24-randaug-pruned' def get_ccip_feature(image: ImageTyping, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): return batch_ccip_features([image], size, model_name)[0] def get_ccip_features(images: MultiImagesTyping, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): def batch_ccip_features(images: MultiImagesTyping, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): images = load_images(images, mode='RGB') data = np.stack([_preprocess_image(item, size=size) for item in images]).astype(np.float32) output, = _open_feat_model(model_name).run(['output'], {'input': data}) Loading @@ -73,7 +82,7 @@ def _preprocess_feats(x, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES if isinstance(item, np.ndarray): feats.append(item) else: feats.append(get_ccip_features(load_images([item]), size, model_name)[0]) feats.append(batch_ccip_features(load_images([item]), size, model_name)[0]) return np.stack(feats) else: Loading @@ -83,33 +92,13 @@ def _preprocess_feats(x, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES _FeatureOrImage = Union[ImageTyping, np.ndarray] def get_ccip_similarity(x: _FeatureOrImage, y: _FeatureOrImage, safe: bool = False, def get_ccip_difference(x: _FeatureOrImage, y: _FeatureOrImage, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES) -> float: return batch_ccip_similarity([x, y], safe, size, model_name)[0, 1].item() return batch_ccip_differences([x, y], size, model_name)[0, 1].item() def batch_ccip_similarity(images: Union[np.ndarray, List[_FeatureOrImage]], safe: bool = False, def batch_ccip_differences(images: Union[np.ndarray, List[_FeatureOrImage]], size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): input_ = _preprocess_feats(images, size, model_name).astype(np.float32) output, = _open_metric_model(model_name, safe=safe).run(['output'], {'input': input_}) output, = _open_metric_model(model_name).run(['output'], {'input': input_}) return output def ccip_clustering(images: MultiImagesTyping, threshold: float = 0.6, min_samples: int = 2, safe: bool = True, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): images = load_images(images, mode='RGB') features = [] for image in tqdm(images, desc='Feature Extract'): features.append(get_ccip_features([image], size, model_name)[0]) if not features: return [] feats = np.stack(features) differences = 1 - batch_ccip_similarity(feats, safe, size, model_name) def _metric(x, y): return differences[int(x), int(y)] samples = np.array(range(len(images))).reshape(-1, 1) clustering = DBSCAN(eps=1 - threshold, min_samples=min_samples, metric=_metric).fit(samples) return clustering.labels_.tolist() requirements-zoo.txt +2 −1 Original line number Diff line number Diff line Loading @@ -21,3 +21,4 @@ ultralytics controlnet_aux lighttuner natsort tabulate No newline at end of file zoo/ccip/plot.py +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ def plt_confusion_matrix(ax, y_true, y_pred, title: str = 'Confusion Matrix', cm = confusion_matrix(y_true, y_pred, normalize=normalize) disp = ConfusionMatrixDisplay( confusion_matrix=cm, display_labels=['Similar', 'Diff'], display_labels=['Diff', 'Similar'], ) disp.plot(ax=ax, cmap=cmap or plt.cm.Blues) ax.set_yticklabels(ax.get_yticklabels(), rotation=90) Loading Loading
docs/source/api_doc/metrics/ccip.benchmark.py +4 −4 Original line number Diff line number Diff line import random from benchmark import BaseBenchmark, create_plot_cli from imgutils.metrics.ccip import get_ccip_features, get_ccip_similarity, _VALID_MODEL_NAMES from imgutils.metrics.ccip import batch_ccip_features, get_ccip_difference, _VALID_MODEL_NAMES class CCIPFeatureBenchmark(BaseBenchmark): Loading @@ -19,7 +19,7 @@ class CCIPFeatureBenchmark(BaseBenchmark): def run(self): image_file = random.choice(self.all_images) _ = get_ccip_features([image_file], model_name=self.model_name) _ = batch_ccip_features([image_file], model_name=self.model_name) class CCIPDiffBenchmark(BaseBenchmark): Loading @@ -28,7 +28,7 @@ class CCIPDiffBenchmark(BaseBenchmark): self.model_name = model_name def prepare(self): self.feats = list(get_ccip_features(random.sample(self.all_images, k=30), model_name=self.model_name)) self.feats = list(batch_ccip_features(random.sample(self.all_images, k=30), model_name=self.model_name)) def load(self): from imgutils.metrics.ccip import _open_metric_model Loading @@ -41,7 +41,7 @@ class CCIPDiffBenchmark(BaseBenchmark): def run(self): feat1 = random.choice(self.feats) feat2 = random.choice(self.feats) _ = get_ccip_similarity(feat1, feat2, model_name=self.model_name) _ = get_ccip_difference(feat1, feat2, model_name=self.model_name) if __name__ == '__main__': Loading
imgutils/metrics/__init__.py +1 −0 Original line number Diff line number Diff line Loading @@ -3,5 +3,6 @@ Overview: Tools for computing visual metrics. """ from .aesthetic import * from .ccip import * from .lpips import * from .psnr_ import *
imgutils/metrics/ccip.py +34 −45 Original line number Diff line number Diff line import json from functools import lru_cache from typing import Union, List import numpy as np from PIL import Image from huggingface_hub import hf_hub_download from sklearn.cluster import DBSCAN from tqdm.auto import tqdm from ..data import MultiImagesTyping, load_images, ImageTyping from ..utils import open_onnx_model __all__ = [ 'get_ccip_features', 'get_ccip_similarity', 'batch_ccip_similarity', 'ccip_clustering', 'get_ccip_feature', 'batch_ccip_features', 'get_ccip_difference', 'batch_ccip_differences', ] Loading @@ -35,29 +34,39 @@ def _preprocess_image(image: Image.Image, size: int = 384): @lru_cache() def _open_feat_model(model_name): return open_onnx_model(hf_hub_download( f'deepghs/imgutils-models', f'ccip/{model_name}_feat.onnx', f'deepghs/ccip_onnx', f'{model_name}/model_feat.onnx', )) @lru_cache() def _open_metric_model(model_name, safe: bool = False): def _open_metric_model(model_name): return open_onnx_model(hf_hub_download( f'deepghs/imgutils-models', f'ccip/{model_name}_{"safe_" if safe else ""}metrics.onnx', f'deepghs/ccip_onnx', f'{model_name}/model_metrics.onnx', )) _VALID_MODEL_NAMES = [ # 'ccip-caformer-23_randaug_fp32', 'ccip-caformer-5_fp32', 'ccip-caformer-4_fp32', 'ccip-caformer-2_fp32', ] _DEFAULT_MODEL_NAMES = _VALID_MODEL_NAMES[0] @lru_cache() def _open_metrics(model_name): with open(hf_hub_download(f'deepghs/ccip_onnx', f'{model_name}/metrics.json'), 'r') as f: return json.load(f) @lru_cache() def _open_cluster_metrics(model_name): with open(hf_hub_download(f'deepghs/ccip_onnx', f'{model_name}/cluster.json'), 'r') as f: return json.load(f) _DEFAULT_MODEL_NAMES = 'ccip-caformer-24-randaug-pruned' def get_ccip_feature(image: ImageTyping, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): return batch_ccip_features([image], size, model_name)[0] def get_ccip_features(images: MultiImagesTyping, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): def batch_ccip_features(images: MultiImagesTyping, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): images = load_images(images, mode='RGB') data = np.stack([_preprocess_image(item, size=size) for item in images]).astype(np.float32) output, = _open_feat_model(model_name).run(['output'], {'input': data}) Loading @@ -73,7 +82,7 @@ def _preprocess_feats(x, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES if isinstance(item, np.ndarray): feats.append(item) else: feats.append(get_ccip_features(load_images([item]), size, model_name)[0]) feats.append(batch_ccip_features(load_images([item]), size, model_name)[0]) return np.stack(feats) else: Loading @@ -83,33 +92,13 @@ def _preprocess_feats(x, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES _FeatureOrImage = Union[ImageTyping, np.ndarray] def get_ccip_similarity(x: _FeatureOrImage, y: _FeatureOrImage, safe: bool = False, def get_ccip_difference(x: _FeatureOrImage, y: _FeatureOrImage, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES) -> float: return batch_ccip_similarity([x, y], safe, size, model_name)[0, 1].item() return batch_ccip_differences([x, y], size, model_name)[0, 1].item() def batch_ccip_similarity(images: Union[np.ndarray, List[_FeatureOrImage]], safe: bool = False, def batch_ccip_differences(images: Union[np.ndarray, List[_FeatureOrImage]], size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): input_ = _preprocess_feats(images, size, model_name).astype(np.float32) output, = _open_metric_model(model_name, safe=safe).run(['output'], {'input': input_}) output, = _open_metric_model(model_name).run(['output'], {'input': input_}) return output def ccip_clustering(images: MultiImagesTyping, threshold: float = 0.6, min_samples: int = 2, safe: bool = True, size: int = 384, model_name: str = _DEFAULT_MODEL_NAMES): images = load_images(images, mode='RGB') features = [] for image in tqdm(images, desc='Feature Extract'): features.append(get_ccip_features([image], size, model_name)[0]) if not features: return [] feats = np.stack(features) differences = 1 - batch_ccip_similarity(feats, safe, size, model_name) def _metric(x, y): return differences[int(x), int(y)] samples = np.array(range(len(images))).reshape(-1, 1) clustering = DBSCAN(eps=1 - threshold, min_samples=min_samples, metric=_metric).fit(samples) return clustering.labels_.tolist()
requirements-zoo.txt +2 −1 Original line number Diff line number Diff line Loading @@ -21,3 +21,4 @@ ultralytics controlnet_aux lighttuner natsort tabulate No newline at end of file
zoo/ccip/plot.py +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ def plt_confusion_matrix(ax, y_true, y_pred, title: str = 'Confusion Matrix', cm = confusion_matrix(y_true, y_pred, normalize=normalize) disp = ConfusionMatrixDisplay( confusion_matrix=cm, display_labels=['Similar', 'Diff'], display_labels=['Diff', 'Similar'], ) disp.plot(ax=ax, cmap=cmap or plt.cm.Blues) ax.set_yticklabels(ax.get_yticklabels(), rotation=90) Loading