Skip to content
This repository was archived by the owner on Aug 20, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions Final2x_core/SRclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

import cv2
import numpy as np
from ccrestoration import AutoModel, SRBaseModel
from cccv import AutoModel, SRBaseModel
from loguru import logger

from Final2x_core.config import SRConfig
from Final2x_core.util import PrintProgressLog, get_device


class CCRestoration:
class SRWrapper:
"""
Super-resolution class for processing images, using ccrestoration.
Super-resolution class for processing images, using cccv.

:param config: SRConfig
"""
Expand All @@ -24,7 +24,7 @@ def __init__(self, config: SRConfig) -> None:
PrintProgressLog().set(len(self.config.input_path), 1)

self._SR_class: SRBaseModel = AutoModel.from_pretrained(
pretrained_model_name=self.config.pretrained_model_name,
self.config.pretrained_model_name,
device=get_device(self.config.device),
fp16=False,
tile=tile,
Expand All @@ -41,6 +41,8 @@ def process(self, img: np.ndarray) -> np.ndarray:
:return:
"""

_origin_size = (img.shape[1], img.shape[0])
Comment thread
Tohrusky marked this conversation as resolved.

_target_size = (
math.ceil(img.shape[1] * self.config.target_scale),
math.ceil(img.shape[0] * self.config.target_scale),
Expand All @@ -49,9 +51,10 @@ def process(self, img: np.ndarray) -> np.ndarray:
img = self._SR_class.inference_image(img)
PrintProgressLog().printProgress()

if abs(float(self.config.target_scale) - float(self.config.cc_model_scale)) < 1e-3: # type: ignore
return img
# calculate current size
_current_size = (img.shape[1], img.shape[0])

img = cv2.resize(img, _target_size, interpolation=cv2.INTER_LINEAR)
if _current_size != _target_size:
img = cv2.resize(img, _target_size, interpolation=cv2.INTER_LINEAR)

return img
4 changes: 2 additions & 2 deletions Final2x_core/SRqueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from loguru import logger

from Final2x_core.config import SRConfig
from Final2x_core.SRclass import CCRestoration
from Final2x_core.SRclass import SRWrapper
from Final2x_core.util import PrintProgressLog


Expand All @@ -20,7 +20,7 @@ def sr_queue(config: SRConfig) -> None:
input_path: List[Path] = config.input_path
output_path: Path = config.output_path / "outputs"
output_path.mkdir(parents=True, exist_ok=True) # create output folder
sr = CCRestoration(config)
sr = SRWrapper(config)

logger.info("Processing------[ 0.0% ]")

Expand Down
6 changes: 3 additions & 3 deletions Final2x_core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from Final2x_core.SRqueue import sr_queue # noqa
from Final2x_core.SRclass import CCRestoration # noqa
from Final2x_core.config import SRConfig # noqa
from Final2x_core.config import SRConfig
from Final2x_core.SRclass import SRWrapper
from Final2x_core.SRqueue import sr_queue
13 changes: 3 additions & 10 deletions Final2x_core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Any, List, Optional, Union

import yaml
from ccrestoration import AutoConfig, BaseConfig, ConfigType
from cccv import ConfigType
from pydantic import BaseModel, DirectoryPath, FilePath, field_validator


Expand All @@ -17,7 +17,6 @@ class SRConfig(BaseModel):
output_path: DirectoryPath
input_path: List[FilePath]
save_format: Optional[str] = ".png"
cc_model_scale: Optional[int] = None

@classmethod
def from_yaml(cls, yaml_path: Union[Path, str]) -> Any:
Expand All @@ -28,11 +27,8 @@ def from_yaml(cls, yaml_path: Union[Path, str]) -> Any:
raise ValueError(f"Error loading config: {e}")

cfg = cls(**config)
c: BaseConfig = AutoConfig.from_pretrained(pretrained_model_name=cfg.pretrained_model_name)

cfg.cc_model_scale = c.scale
if cfg.target_scale is None or cfg.target_scale <= 0:
cfg.target_scale = c.scale
cfg.target_scale = 2
Comment thread
Tohrusky marked this conversation as resolved.
return cfg

@classmethod
Expand All @@ -43,11 +39,8 @@ def from_json_str(cls, json_str: str) -> Any:
raise ValueError(f"Error loading config: {e}")

cfg = cls(**config)
c: BaseConfig = AutoConfig.from_pretrained(pretrained_model_name=cfg.pretrained_model_name)

cfg.cc_model_scale = c.scale
if cfg.target_scale is None or cfg.target_scale <= 0:
cfg.target_scale = c.scale
cfg.target_scale = 2
Comment thread
Tohrusky marked this conversation as resolved.
return cfg

@classmethod
Expand Down
6 changes: 3 additions & 3 deletions Final2x_core/util/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from Final2x_core.util.progressLog import PrintProgressLog # noqa
from Final2x_core.util.singleton import singleton # noqa
from Final2x_core.util.device import get_device # noqa
from Final2x_core.util.device import get_device
from Final2x_core.util.progressLog import PrintProgressLog
from Final2x_core.util.singleton import singleton
7 changes: 3 additions & 4 deletions Final2x_core/util/device.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Union

import torch
from ccrestoration.util.device import default_device
from cccv.util.device import DEFAULT_DEVICE


def get_device(device: str) -> Union[torch.device, str]:
Expand All @@ -13,7 +13,7 @@ def get_device(device: str) -> Union[torch.device, str]:
device = device.lower()

if device.startswith("auto"):
return default_device()
return DEFAULT_DEVICE
elif device.startswith("cpu"):
return torch.device("cpu")
elif device.startswith("cuda"):
Expand All @@ -27,5 +27,4 @@ def get_device(device: str) -> Union[torch.device, str]:
elif device.startswith("xpu"):
return torch.device("xpu")
else:
print(f"Unknown device: {device}, use auto instead.")
return default_device()
return DEFAULT_DEVICE
Comment thread
Tohrusky marked this conversation as resolved.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Final2x-core is a cross-platform image super-resolution CLI tool for [Final2x](h

Download in [Release](https://github.com/EutropicAI/Final2x-core/releases) or use pip to install (Linux User).

Make sure you have Python >= 3.9 and PyTorch >= 1.13 installed
Make sure you have Python >= 3.9 and PyTorch >= 2.0 installed

```shell
pip install Final2x-core
Expand Down Expand Up @@ -50,6 +50,12 @@ make gen

The following references were used in the development of this project:

After v4.0.0, we use cccv as the algorithm implementation, which implemented most of the features from ccrestoration

- [cccv](https://github.com/EutropicAI/cccv)

---

After v3.0.0, ncnn will be deprecated, and the project will use ccrestoration(PyTorch) as the algorithm implementation.

- [ccrestoration](https://github.com/EutropicAI/ccrestoration)
Expand Down
18 changes: 15 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ requires = ["hatchling"]
[dependency-groups]
dev = [
"numpy~=1.26.4",
"ccrestoration==0.2.2",
"opencv-python~=4.10.0.84",
"torch~=2.7.1",
"torchvision~=0.22.1",
Expand Down Expand Up @@ -34,7 +33,7 @@ classifiers = [
]
dependencies = [
"PyYAML",
"ccrestoration==0.2.2",
"cccv==0.0.4",
"loguru",
"pydantic"
]
Expand Down Expand Up @@ -94,7 +93,17 @@ quote-style = "double"
skip-magic-trailing-comma = false

[tool.ruff.lint]
extend-ignore = ["B018", "B019", "RUF001", "PGH003", "PGH004", "RUF003", "E402", "RUF002", "B904"]
extend-ignore = [
"B018",
"B019",
"RUF001",
"PGH003",
"PGH004",
"RUF003",
"E402",
"RUF002",
"B904"
]
extend-select = [
"I", # isort
"B", # flake8-bugbear
Expand All @@ -112,6 +121,9 @@ combine-as-imports = true
[tool.ruff.lint.mccabe]
max-complexity = 10

[tool.ruff.lint.per-file-ignores]
"**/__init__.py" = ["F401", "F403"]

[tool.uv]
default-groups = [
"dev",
Expand Down
2 changes: 1 addition & 1 deletion scripts/gen_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pathlib import Path

import yaml
from ccrestoration import ConfigType
from cccv import ConfigType

projectPATH = Path(__file__).resolve().parent.parent.absolute()

Expand Down
2 changes: 1 addition & 1 deletion scripts/gen_pretrained_model_name.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pathlib import Path
from typing import List

from ccrestoration import ConfigType, ModelType
from cccv import ConfigType, ModelType

projectPATH = Path(__file__).resolve().parent.parent.absolute()

Expand Down
2 changes: 1 addition & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from Final2x_core.config import SRConfig
from Final2x_core import SRConfig

from .util import CONFIG_PATH

Expand Down
6 changes: 3 additions & 3 deletions tests/test_targetscale.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ccrestoration import ConfigType
from cccv import ConfigType

from Final2x_core import CCRestoration, SRConfig
from Final2x_core import SRConfig, SRWrapper

from .util import CONFIG_PATH, calculate_image_similarity, compare_image_size, load_image

Expand All @@ -11,7 +11,7 @@ def test_case_targetscale_positive(self) -> None:
config.pretrained_model_name = ConfigType.RealESRGAN_AnimeJaNai_HD_V3_Compact_2x
for t in [7.99999, 1, 2, 2.5, 4, 5.6619, 8, 0.673]:
config.target_scale = t
SR = CCRestoration(config=config)
SR = SRWrapper(config=config)
img1 = load_image()
img2 = SR.process(img1)
assert calculate_image_similarity(img1, img2)
Expand Down
12 changes: 5 additions & 7 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading