Compare commits
5 Commits
8c972c0c7a
...
822c90599b
Author | SHA1 | Date | |
---|---|---|---|
822c90599b | |||
7d7bf73a7f | |||
e151067e57 | |||
831b137f8d | |||
28debaf267 |
105
DanbooruTagger/DanbooruTagger.py
Normal file
105
DanbooruTagger/DanbooruTagger.py
Normal file
@ -0,0 +1,105 @@
|
||||
import warnings
|
||||
from deepdanbooru_onnx import DeepDanbooru
|
||||
from PIL import Image
|
||||
import argparse
|
||||
import cv2
|
||||
import os
|
||||
from multiprocessing import Process, Queue
|
||||
import json
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
image_ext_ocv = [".bmp", ".jpeg", ".jpg", ".png"]
|
||||
|
||||
|
||||
def find_image_files(path: str) -> list[str]:
|
||||
paths = list()
|
||||
for root, dirs, files in os.walk(path):
|
||||
for filename in files:
|
||||
name, extension = os.path.splitext(filename)
|
||||
if extension.lower() in image_ext_ocv:
|
||||
paths.append(os.path.join(root, filename))
|
||||
return paths
|
||||
|
||||
|
||||
def image_loader(paths: list[str]):
|
||||
for path in paths:
|
||||
name, extension = os.path.splitext(path)
|
||||
extension = extension.lower()
|
||||
imagebgr = cv2.imread(path)
|
||||
image = cv2.cvtColor(imagebgr, cv2.COLOR_BGR2RGB)
|
||||
if image is None:
|
||||
print(f"Warning: could not load {path}")
|
||||
else:
|
||||
image_pil = Image.fromarray(image)
|
||||
yield image_pil, path
|
||||
|
||||
|
||||
def pipeline(queue: Queue, image_paths: list[str], device: int):
|
||||
danbooru = DeepDanbooru()
|
||||
|
||||
for path in image_paths:
|
||||
imageprompt = ""
|
||||
tags = danbooru(path)
|
||||
for tag in tags:
|
||||
imageprompt = imageprompt + ", " + tag
|
||||
|
||||
queue.put({"file_name": path, "text": imageprompt})
|
||||
|
||||
|
||||
def split_list(input_list, count):
|
||||
target_length = int(len(input_list) / count)
|
||||
for i in range(0, count - 1):
|
||||
yield input_list[i * target_length: (i + 1) * target_length]
|
||||
yield input_list[(count - 1) * target_length: len(input_list)]
|
||||
|
||||
|
||||
def save_meta(meta_file, meta, reldir, common_description):
|
||||
meta["file_name"] = os.path.relpath(meta["file_name"], reldir)
|
||||
if common_description is not None:
|
||||
meta["text"] = common_description + meta["text"]
|
||||
meta_file.write(json.dumps(meta) + '\n')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser("A script to tag images via DeepDanbooru")
|
||||
parser.add_argument('--batch', '-b', default=4, type=int, help="Batch size to use for inference")
|
||||
parser.add_argument('--common_description', '-c', help="An optional description that will be preended to the ai generated one")
|
||||
parser.add_argument('--image_dir', '-i', help="A directory containg the images to tag")
|
||||
args = parser.parse_args()
|
||||
|
||||
nparalell = 2
|
||||
|
||||
image_paths = find_image_files(args.image_dir)
|
||||
image_path_chunks = list(split_list(image_paths, nparalell))
|
||||
|
||||
print(f"Will use {nparalell} processies to create tags")
|
||||
|
||||
queue = Queue()
|
||||
processies = list()
|
||||
for i in range(0, nparalell):
|
||||
processies.append(Process(target=pipeline, args=(queue, image_path_chunks[i], i)))
|
||||
processies[-1].start()
|
||||
|
||||
progress = tqdm(desc="Generateing tags", total=len(image_paths))
|
||||
exit = False
|
||||
with open(os.path.join(args.image_dir, "metadata.jsonl"), mode='w') as output_file:
|
||||
while not exit:
|
||||
if not queue.empty():
|
||||
meta = queue.get()
|
||||
save_meta(output_file, meta, args.image_dir, args.common_description)
|
||||
progress.update()
|
||||
exit = True
|
||||
for process in processies:
|
||||
if process.is_alive():
|
||||
exit = False
|
||||
break
|
||||
|
||||
while not queue.empty():
|
||||
meta = queue.get()
|
||||
save_meta(output_file, meta, args.image_dir, args.common_description)
|
||||
progress.update()
|
||||
|
||||
for process in processies:
|
||||
process.join()
|
||||
|
3
DanbooruTagger/deepdanbooru_onnx/__init__.py
Normal file
3
DanbooruTagger/deepdanbooru_onnx/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .deepdanbooru_onnx import DeepDanbooru
|
||||
from .deepdanbooru_onnx import process_image
|
||||
__version__ = '0.0.8'
|
244
DanbooruTagger/deepdanbooru_onnx/deepdanbooru_onnx.py
Normal file
244
DanbooruTagger/deepdanbooru_onnx/deepdanbooru_onnx.py
Normal file
@ -0,0 +1,244 @@
|
||||
import onnxruntime as ort
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
import os
|
||||
from tqdm import tqdm
|
||||
import requests
|
||||
import hashlib
|
||||
from typing import List, Union
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def process_image(image: Image.Image) -> np.ndarray:
|
||||
"""
|
||||
Convert an image to a numpy array.
|
||||
:param image: the image to convert
|
||||
:return: the numpy array
|
||||
"""
|
||||
|
||||
image = image.convert("RGB").resize((512, 512))
|
||||
image = np.array(image).astype(np.float32) / 255
|
||||
image = image.transpose((2, 0, 1)).reshape(1, 3, 512, 512).transpose((0, 2, 3, 1))
|
||||
return image
|
||||
|
||||
|
||||
def download(url: str, save_path: str, md5: str, length: str) -> bool:
|
||||
"""
|
||||
Download a file from url to save_path.
|
||||
If the file already exists, check its md5.
|
||||
If the md5 matches, return True,if the md5 doesn't match, return False.
|
||||
:param url: the url of the file to download
|
||||
:param save_path: the path to save the file
|
||||
:param md5: the md5 of the file
|
||||
:param length: the length of the file
|
||||
:return: True if the file is downloaded successfully, False otherwise
|
||||
"""
|
||||
|
||||
try:
|
||||
response = requests.get(url=url, stream=True)
|
||||
with open(save_path, "wb") as f:
|
||||
with tqdm.wrapattr(
|
||||
response.raw, "read", total=length, desc="Downloading"
|
||||
) as r_raw:
|
||||
shutil.copyfileobj(r_raw, f)
|
||||
return (
|
||||
True
|
||||
if hashlib.md5(open(save_path, "rb").read()).hexdigest() == md5
|
||||
else False
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
|
||||
def download_model():
|
||||
"""
|
||||
Download the model and tags file from the server.
|
||||
:return: the path to the model and tags file
|
||||
"""
|
||||
|
||||
model_url = (
|
||||
"https://huggingface.co/chinoll/deepdanbooru/resolve/main/deepdanbooru.onnx"
|
||||
)
|
||||
tags_url = "https://huggingface.co/chinoll/deepdanbooru/resolve/main/tags.txt"
|
||||
model_md5 = "16be4e40ebcc0b1d1915bbf31f00969f"
|
||||
tags_md5 = "a3f764de985cdeba89f1d232a4204402"
|
||||
model_length = 643993025
|
||||
tags_length = 133810
|
||||
|
||||
home = str(Path.home()) + "/.deepdanbooru_onnx/"
|
||||
if not os.path.exists(home):
|
||||
os.mkdir(home)
|
||||
|
||||
model_name = "deepdanbooru.onnx"
|
||||
tags_name = "tags.txt"
|
||||
|
||||
model_path = home + model_name
|
||||
tags_path = home + tags_name
|
||||
if os.path.exists(model_path):
|
||||
if hashlib.md5(open(model_path, "rb").read()).hexdigest() != model_md5:
|
||||
os.remove(model_path)
|
||||
if not download(model_url, model_path, model_md5, model_length):
|
||||
raise ValueError("Model download failed")
|
||||
|
||||
else:
|
||||
if not download(model_url, model_path, model_md5, model_length):
|
||||
raise ValueError("Model download failed")
|
||||
|
||||
if os.path.exists(tags_path):
|
||||
if hashlib.md5(open(tags_path, "rb").read()).hexdigest() != tags_md5:
|
||||
os.remove(tags_path)
|
||||
if not download(tags_url, tags_path, tags_md5, tags_length):
|
||||
raise ValueError("Tags download failed")
|
||||
else:
|
||||
if not download(tags_url, tags_path, tags_md5, tags_length):
|
||||
raise ValueError("Tags download failed")
|
||||
return model_path, tags_path
|
||||
|
||||
|
||||
class DeepDanbooru:
|
||||
def __init__(
|
||||
self,
|
||||
mode: str = "auto",
|
||||
model_path: Union[str, None] = None,
|
||||
tags_path: Union[str, None] = None,
|
||||
threshold: Union[float, int] = 0.6,
|
||||
pin_memory: bool = False,
|
||||
batch_size: int = 1,
|
||||
):
|
||||
"""
|
||||
Initialize the DeepDanbooru class.
|
||||
:param mode: the mode of the model, "cpu" or "gpu" or "auto"
|
||||
:param model_path: the path to the model file
|
||||
:param tags_path: the path to the tags file
|
||||
:param threshold: the threshold of the model
|
||||
:param pin_memory: whether to use pin memory
|
||||
:param batch_size: the batch size of the model
|
||||
"""
|
||||
|
||||
providers = {
|
||||
"cpu": "CPUExecutionProvider",
|
||||
"gpu": "CUDAExecutionProvider",
|
||||
"tensorrt": "TensorrtExecutionProvider",
|
||||
"auto": (
|
||||
"CUDAExecutionProvider"
|
||||
if "CUDAExecutionProvider" in ort.get_available_providers()
|
||||
else "CPUExecutionProvider"
|
||||
),
|
||||
}
|
||||
|
||||
if not (isinstance(threshold, float) or isinstance(threshold, int)):
|
||||
raise TypeError("threshold must be float or int")
|
||||
if threshold < 0 or threshold > 1:
|
||||
raise ValueError("threshold must be between 0 and 1")
|
||||
if mode not in providers:
|
||||
raise ValueError(
|
||||
"Mode not supported. Please choose from: cpu, gpu, tensorrt"
|
||||
)
|
||||
if providers[mode] not in ort.get_available_providers():
|
||||
raise ValueError(
|
||||
f"Your device is not supported {mode}. Please choose from: cpu"
|
||||
)
|
||||
if model_path is not None and not os.path.exists(model_path):
|
||||
raise FileNotFoundError("Model file not found")
|
||||
if tags_path is not None and not os.path.exists(tags_path):
|
||||
raise FileNotFoundError("Tags file not found")
|
||||
|
||||
if model_path is None or tags_path is None:
|
||||
model_path, tags_path = download_model()
|
||||
|
||||
self.session = ort.InferenceSession(model_path, providers=[providers[mode]])
|
||||
self.tags = [i.replace("\n", "") for i in open(tags_path, "r").readlines()]
|
||||
|
||||
self.input_name = self.session.get_inputs()[0].name
|
||||
self.output_name = [output.name for output in self.session.get_outputs()]
|
||||
self.threshold = threshold
|
||||
self.pin_memory = pin_memory
|
||||
self.batch_size = batch_size
|
||||
self.mode = mode
|
||||
self.cache = {}
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"DeepDanbooru(mode={self.mode}, threshold={self.threshold}, pin_memory={self.pin_memory}, batch_size={self.batch_size})"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.__str__()
|
||||
|
||||
def from_image_inference(self, image: Image.Image) -> dict:
|
||||
image = process_image(image)
|
||||
return self.predict(image)
|
||||
|
||||
def from_ndarray_inferece(self, image: np.ndarray) -> dict:
|
||||
if image.shape != (1, 512, 512, 3):
|
||||
raise ValueError(f"Image must be {(1, 512, 512, 3)}")
|
||||
return self.predict(image)
|
||||
|
||||
def from_file_inference(self, image: str) -> dict:
|
||||
return self.from_image_inference(Image.open(image))
|
||||
|
||||
def from_list_inference(self, image: Union[list, tuple]) -> List[dict]:
|
||||
if self.pin_memory:
|
||||
image = [process_image(Image.open(i)) for i in image]
|
||||
for i in [
|
||||
image[i : i + self.batch_size]
|
||||
for i in range(0, len(image), self.batch_size)
|
||||
]:
|
||||
imagelist = i
|
||||
bs = len(i)
|
||||
_imagelist, idx, hashlist = [], [], []
|
||||
for j in range(len(i)):
|
||||
img = Image.open(i[j]) if not self.pin_memory else imagelist[j]
|
||||
image_hash = hashlib.md5(np.array(img).astype(np.uint8)).hexdigest()
|
||||
hashlist.append(image_hash)
|
||||
if image_hash in self.cache:
|
||||
continue
|
||||
if not self.pin_memory:
|
||||
_imagelist.append(process_image(img))
|
||||
else:
|
||||
_imagelist.append(imagelist[j])
|
||||
idx.append(j)
|
||||
|
||||
imagelist = _imagelist
|
||||
if len(imagelist) != 0:
|
||||
_image = np.vstack(imagelist)
|
||||
results = self.inference(_image)
|
||||
results_idx = 0
|
||||
else:
|
||||
results = []
|
||||
|
||||
for i in range(bs):
|
||||
image_tag = {}
|
||||
if i in idx:
|
||||
hash = hashlist[i]
|
||||
for tag, score in zip(self.tags, results[results_idx]):
|
||||
if score >= self.threshold:
|
||||
image_tag[tag] = score
|
||||
results_idx += 1
|
||||
self.cache[hash] = image_tag
|
||||
yield image_tag
|
||||
else:
|
||||
yield self.cache[hashlist[i]]
|
||||
|
||||
def inference(self, image):
|
||||
return self.session.run(self.output_name, {self.input_name: image})[0]
|
||||
|
||||
def predict(self, image):
|
||||
result = self.inference(image)
|
||||
image_tag = {}
|
||||
for tag, score in zip(self.tags, result[0]):
|
||||
if score >= self.threshold:
|
||||
image_tag[tag] = score
|
||||
return image_tag
|
||||
|
||||
def __call__(self, image) -> Union[dict, List[dict]]:
|
||||
if isinstance(image, str):
|
||||
return self.from_file_inference(image)
|
||||
elif isinstance(image, np.ndarray):
|
||||
return self.from_ndarray_inferece(image)
|
||||
elif isinstance(image, list) or isinstance(image, tuple):
|
||||
return self.from_list_inference(image)
|
||||
elif isinstance(image, Image.Image):
|
||||
return self.from_image_inference(image)
|
||||
else:
|
||||
raise ValueError("Image must be a file path or a numpy array or list/tuple")
|
11
LLavaTagger/requirements.txt
Normal file
11
LLavaTagger/requirements.txt
Normal file
@ -0,0 +1,11 @@
|
||||
accelerate==0.29.0
|
||||
bitsandbytes
|
||||
huggingface-hub==0.22.2
|
||||
ninja==1.11.1.1
|
||||
safetensors==0.4.2
|
||||
tokenizers==0.15.2
|
||||
transformers
|
||||
pytorch
|
||||
opencv-python
|
||||
numpy
|
||||
tqdm
|
@ -1,4 +1,24 @@
|
||||
#!/bin/python3
|
||||
|
||||
# PersonDatasetAssembler - A tool to assmble images of a specific person from a
|
||||
# directory of images or from a video file
|
||||
# Copyright (C) 2024 Carl Philipp Klemm
|
||||
#
|
||||
# This file is part of PersonDatasetAssembler.
|
||||
#
|
||||
# PersonDatasetAssembler is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# PersonDatasetAssembler is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with PersonDatasetAssembler. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from typing import Iterator
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "facerecognizer.h"
|
||||
#include <filesystem>
|
||||
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <exception>
|
||||
#include <opencv2/core/mat.hpp>
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file incbin.h
|
||||
* @author Dale Weiler
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "intelligentroi.h"
|
||||
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <opencv2/core.hpp>
|
||||
@ -430,7 +450,7 @@ int main(int argc, char* argv[])
|
||||
std::vector<std::thread> threads;
|
||||
std::vector<std::vector<std::filesystem::path>> imagePathParts = splitVector(imagePaths, std::thread::hardware_concurrency());
|
||||
|
||||
for(size_t i = 0; i < std::thread::hardware_concurrency(); ++i)
|
||||
for(size_t i = 0; i < imagePathParts.size(); ++i)
|
||||
threads.push_back(std::thread(threadFn, imagePathParts[i], std::ref(config), recognizer, std::ref(recognizerMutex), std::ref(debugOutputPath)));
|
||||
|
||||
for(std::thread& thread : threads)
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "seamcarving.h"
|
||||
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "tokenize.h"
|
||||
|
||||
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
@ -1,3 +1,23 @@
|
||||
//
|
||||
// SmartCrop - A tool for content aware croping of images
|
||||
// Copyright (C) 2024 Carl Philipp Klemm
|
||||
//
|
||||
// This file is part of SmartCrop.
|
||||
//
|
||||
// SmartCrop is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// SmartCrop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <opencv2/dnn/dnn.hpp>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
@ -1,3 +1,22 @@
|
||||
/* * SmartCrop - A tool for content aware croping of images
|
||||
* Copyright (C) 2024 Carl Philipp Klemm
|
||||
*
|
||||
* This file is part of SmartCrop.
|
||||
*
|
||||
* SmartCrop is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SmartCrop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with SmartCrop. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
|
Loading…
x
Reference in New Issue
Block a user