Skip to content

Commit

Permalink
dev(narugo): add adversarial clean
Browse files Browse the repository at this point in the history
  • Loading branch information
narugo1992 committed Dec 18, 2023
1 parent d218fbf commit 0ecef94
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 0 deletions.
14 changes: 14 additions & 0 deletions docs/source/api_doc/restore/adversarial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
imgutils.restore.adversarial
====================================

.. currentmodule:: imgutils.restore.adversarial

.. automodule:: imgutils.restore.adversarial


remove_adversarial_noise
-----------------------------------

.. autofunction:: remove_adversarial_noise


28 changes: 28 additions & 0 deletions docs/source/api_doc/restore/adversarial_benchmark.plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import random

from benchmark import BaseBenchmark, create_plot_cli
from imgutils.restore.adversarial import remove_adversarial_noise


class AdversarialRemovalBenchmark(BaseBenchmark):
def load(self):
pass

def unload(self):
pass

def run(self):
image_file = random.choice(self.all_images)

_ = remove_adversarial_noise(image_file)


if __name__ == '__main__':
create_plot_cli(
[
('Adversarial Removal', AdversarialRemovalBenchmark()),
],
title='Benchmark for Adversarial Removal Algorithm',
run_times=5,
try_times=10,
)()
18 changes: 18 additions & 0 deletions docs/source/api_doc/restore/adversarial_demo.plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os

from imgutils.data import load_image
from imgutils.restore import remove_adversarial_noise
from plot import image_plot

sample_dir = 'sample'

if __name__ == '__main__':
image = load_image(os.path.join(sample_dir, 'adversarial_input.png'))
image_plot(
[
(image, 'Adversarial Noised'),
(remove_adversarial_noise(image), 'Cleaned')
],
columns=2,
figsize=(10, 6),
)
1 change: 1 addition & 0 deletions docs/source/api_doc/restore/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ imgutils.restore

nafnet
scunet
adversarial

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions imgutils/restore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
:align: center
"""
from .adversarial import remove_adversarial_noise
from .nafnet import restore_with_nafnet
from .scunet import restore_with_scunet
66 changes: 66 additions & 0 deletions imgutils/restore/adversarial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
Overview:
Useful tools to remove adversarial noises, just using opencv library without any models.
.. image:: adversarial_demo.plot.py.svg
:align: center
This is an overall benchmark of all the adversarial denoising:
.. image:: adversarial_benchmark.plot.py.svg
:align: center
.. note::
This tool is inspired from `Github - lllyasviel/AdverseCleaner <https://github.com/lllyasviel/AdverseCleaner>`_.
"""
import cv2
import numpy as np
from PIL import Image
from cv2.ximgproc import guidedFilter

from ..data import load_image, ImageTyping


def remove_adversarial_noise(image: ImageTyping, diameter: int = 5, sigma_color: float = 8.0,
sigma_space: float = 8.0, radius: int = 4, eps: float = 16.0) -> Image.Image:
"""
Remove adversarial noise from an image using bilateral and guided filtering.
This function applies bilateral filtering and guided filtering to reduce adversarial noise in the input image.
:param image: The input image.
:type image: ImageTyping
:param diameter: Diameter of each pixel neighborhood for bilateral filtering.
:type diameter: int, optional
:param sigma_color: Filter sigma in the color space for bilateral filtering.
:type sigma_color: float, optional
:param sigma_space: Filter sigma in the coordinate space for bilateral filtering.
:type sigma_space: float, optional
:param radius: Radius of Guided Filter.
:type radius: float, optional
:param eps: Guided Filter regularization term.
:type eps: int, optional
:return: Image with adversarial noise removed.
:rtype: Image.Image
"""
image = load_image(image, mode='RGB', force_background='white')
img = np.array(image).astype(np.float32)
y = img.copy()

# Apply bilateral filtering iteratively
for _ in range(64):
y = cv2.bilateralFilter(y, diameter, sigma_color, sigma_space)

# Apply guided filtering iteratively
for _ in range(4):
y = guidedFilter(img, y, radius, eps)

# Clip the values and convert back to uint8 for PIL Image
output_image = Image.fromarray(y.clip(0, 255).astype(np.uint8))
return output_image
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ scikit-learn
huggingface_hub
tqdm
opencv-python
opencv-contrib-python
pandas
scipy
emoji>=2.5.0
Expand Down
25 changes: 25 additions & 0 deletions test/restore/test_adversarial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest

from imgutils.data import load_image
from imgutils.restore import remove_adversarial_noise
from test.testings import get_testfile


@pytest.fixture()
def adversarial_input():
return get_testfile('adversarial', 'adversarial_input.png')


@pytest.fixture()
def adversarial_output_pil():
return load_image(get_testfile('adversarial', 'adversarial_output.png'))


@pytest.mark.unittest
class TestRestoreAdversarial:
def test_remove_adversarial_noises(self, adversarial_input, adversarial_output_pil, image_diff):
assert image_diff(
remove_adversarial_noise(adversarial_input),
adversarial_output_pil,
throw_exception=False
) < 1e-3
Binary file added test/testfile/adversarial/adversarial_input.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/testfile/adversarial/adversarial_output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0ecef94

Please sign in to comment.