Spaces:
Runtime error
Runtime error
| #!/usr/bin/env python | |
| from __future__ import annotations | |
| import io | |
| import tarfile | |
| import gradio as gr | |
| import numpy as np | |
| import PIL.Image | |
| from huggingface_hub import hf_hub_download | |
| TITLE = "TADNE (This Anime Does Not Exist) Image Selector" | |
| DESCRIPTION = """The original TADNE site is https://thisanimedoesnotexist.ai/. | |
| You can view images generated by the TADNE model with seed 0-99999. | |
| You can filter images based on predictions by the [DeepDanbooru](https://github.com/KichangKim/DeepDanbooru) model. | |
| The resolution of the output images in this app is 128x128, but you can | |
| check the original 512x512 images from URLs like | |
| https://thisanimedoesnotexist.ai/slider.html?seed=10000 using the output seeds. | |
| Expected execution time on Hugging Face Spaces: 4s | |
| Related Apps: | |
| - [TADNE](https://huggingface.co/spaces/hysts/TADNE) | |
| - [TADNE Image Viewer](https://huggingface.co/spaces/hysts/TADNE-image-viewer) | |
| - [TADNE Interpolation](https://huggingface.co/spaces/hysts/TADNE-interpolation) | |
| - [TADNE Image Search with DeepDanbooru](https://huggingface.co/spaces/hysts/TADNE-image-search-with-DeepDanbooru) | |
| - [DeepDanbooru](https://huggingface.co/spaces/hysts/DeepDanbooru) | |
| """ | |
| def load_deepdanbooru_tag_dict() -> dict[str, int]: | |
| path = hf_hub_download("public-data/DeepDanbooru", "tags.txt") | |
| with open(path) as f: | |
| tags = [line.strip() for line in f.readlines()] | |
| return {tag: i for i, tag in enumerate(tags)} | |
| def load_deepdanbooru_predictions(dirname: str) -> np.ndarray: | |
| path = hf_hub_download( | |
| "hysts/TADNE-sample-images", | |
| f"prediction_results/deepdanbooru/{dirname}.npy", | |
| repo_type="dataset", | |
| ) | |
| return np.load(path) | |
| image_size = 128 | |
| min_seed = 0 | |
| max_seed = 99999 | |
| dirname = "0-99999" | |
| tarball_path = hf_hub_download("hysts/TADNE-sample-images", f"{image_size}/{dirname}.tar", repo_type="dataset") | |
| deepdanbooru_tag_dict = load_deepdanbooru_tag_dict() | |
| deepdanbooru_predictions = load_deepdanbooru_predictions(dirname) | |
| def run( | |
| general_tags: list[str], | |
| hair_color_tags: list[str], | |
| hair_style_tags: list[str], | |
| eye_color_tags: list[str], | |
| image_color_tags: list[str], | |
| other_tags: list[str], | |
| additional_tags_str: str, | |
| score_threshold: float, | |
| start_index: int, | |
| nrows: int, | |
| ncols: int, | |
| ) -> tuple[int, np.ndarray, np.ndarray, str]: | |
| hair_color_tags = [f"{color}_hair" for color in hair_color_tags] | |
| eye_color_tags = [f"{color}_eyes" for color in eye_color_tags] | |
| additional_tags = additional_tags_str.split(",") | |
| tags = ( | |
| general_tags | |
| + hair_color_tags | |
| + hair_style_tags | |
| + eye_color_tags | |
| + image_color_tags | |
| + other_tags | |
| + additional_tags | |
| ) | |
| missing_tags = [tag for tag in tags if tag not in deepdanbooru_tag_dict] | |
| tag_indices = [deepdanbooru_tag_dict[tag] for tag in tags if tag in deepdanbooru_tag_dict] | |
| conditions = deepdanbooru_predictions[:, tag_indices] > score_threshold | |
| image_indices = np.arange(len(deepdanbooru_predictions)) | |
| image_indices = image_indices[conditions.all(axis=1)] | |
| start_index = int(start_index) | |
| num = nrows * ncols | |
| seeds = [] | |
| images = [] | |
| dummy = np.ones((image_size, image_size, 3), dtype=np.uint8) * 255 | |
| with tarfile.TarFile(tarball_path) as tar_file: | |
| for index in range(start_index, start_index + num): | |
| if index >= len(image_indices): | |
| seeds.append(np.nan) | |
| images.append(dummy) | |
| continue | |
| image_index = image_indices[index] | |
| seeds.append(image_index) | |
| member = tar_file.getmember(f"{dirname}/{image_index:07d}.jpg") | |
| with tar_file.extractfile(member) as f: # type: ignore | |
| data = io.BytesIO(f.read()) | |
| image = PIL.Image.open(data) | |
| image = np.asarray(image) | |
| images.append(image) | |
| res = ( | |
| np.asarray(images) | |
| .reshape(nrows, ncols, image_size, image_size, 3) | |
| .transpose(0, 2, 1, 3, 4) | |
| .reshape(nrows * image_size, ncols * image_size, 3) | |
| ) | |
| seeds = np.asarray(seeds).reshape(nrows, ncols) | |
| return len(image_indices), res, seeds, ",".join(missing_tags) | |
| demo = gr.Interface( | |
| fn=run, | |
| inputs=[ | |
| gr.CheckboxGroup( | |
| label="General", | |
| choices=[ | |
| "1girl", | |
| "1boy", | |
| "multiple_girls", | |
| "multiple_boys", | |
| "looking_at_viewer", | |
| ], | |
| ), | |
| gr.CheckboxGroup( | |
| label="Hair Color", | |
| choices=[ | |
| "aqua", | |
| "black", | |
| "blonde", | |
| "blue", | |
| "brown", | |
| "green", | |
| "grey", | |
| "orange", | |
| "pink", | |
| "purple", | |
| "red", | |
| "silver", | |
| "white", | |
| ], | |
| ), | |
| gr.CheckboxGroup( | |
| label="Hair Style", | |
| choices=[ | |
| "bangs", | |
| "curly_hair", | |
| "long_hair", | |
| "medium_hair", | |
| "messy_hair", | |
| "ponytail", | |
| "short_hair", | |
| "straight_hair", | |
| "twintails", | |
| ], | |
| ), | |
| gr.CheckboxGroup( | |
| label="Eye Color", | |
| choices=[ | |
| "aqua", | |
| "black", | |
| "blue", | |
| "brown", | |
| "green", | |
| "grey", | |
| "orange", | |
| "pink", | |
| "purple", | |
| "red", | |
| "white", | |
| "yellow", | |
| ], | |
| ), | |
| gr.CheckboxGroup( | |
| label="Image Color", | |
| choices=[ | |
| "greyscale", | |
| "monochrome", | |
| ], | |
| ), | |
| gr.CheckboxGroup( | |
| label="Others", | |
| choices=[ | |
| "animal_ears", | |
| "closed_eyes", | |
| "full_body", | |
| "hat", | |
| "smile", | |
| ], | |
| ), | |
| gr.Textbox(label="Additional Tags"), | |
| gr.Slider(label="DeepDanbooru Score Threshold", minimum=0, maximum=1, step=0.1, value=0.5), | |
| gr.Number(label="Start Index", value=0), | |
| gr.Slider(label="Number of Rows", minimum=0, maximum=10, step=1, value=2), | |
| gr.Slider(label="Number of Columns", minimum=0, maximum=10, step=1, value=5), | |
| ], | |
| outputs=[ | |
| gr.Textbox(label="Number of Found Images"), | |
| gr.Image(label="Output"), | |
| gr.Dataframe(label="Seed"), | |
| gr.Textbox(label="Missing Tags"), | |
| ], | |
| title=TITLE, | |
| description=DESCRIPTION, | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue().launch() | |