Download classical_baseline.py from psidharth567/personal_math: direct link, hf CLI and curl.
- Browser
- Download file 3.32 kB
-
https://huggingface.co/psidharth567/personal_math/resolve/main/classical_baseline.py
- Command line
-
hf download hf://psidharth567/personal_math/classical_baseline.py
-
curl -L -o classical_baseline.py https://huggingface.co/psidharth567/personal_math/resolve/main/classical_baseline.py
3.32 kB
| import os | |
| import glob | |
| import torch | |
| import torch.nn.functional as F | |
| import math | |
| from PIL import Image | |
| from torchvision import transforms | |
| from torch.utils.data import Dataset, DataLoader | |
| # --- Configuration --- | |
| DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| _SIGMAS = (15.0 / 255.0, 50.0 / 255.0, 75.0 / 255.0) | |
| def _testset_root(name): | |
| return os.path.join( | |
| _SCRIPT_DIR, | |
| "datasets", | |
| "Test_Datasets", | |
| "FFDNet-master", | |
| "testsets", | |
| name, | |
| ) | |
| class TestDataset(Dataset): | |
| def __init__(self, root_dir, sigma): | |
| self.sigma = sigma | |
| self.image_paths = glob.glob(os.path.join(root_dir, "*.png")) + glob.glob( | |
| os.path.join(root_dir, "*.jpg") | |
| ) | |
| self.transform = transforms.Compose( | |
| [transforms.Grayscale(num_output_channels=1), transforms.ToTensor()] | |
| ) | |
| def __len__(self): | |
| return len(self.image_paths) | |
| def __getitem__(self, idx): | |
| img = Image.open(self.image_paths[idx]) | |
| clean = self.transform(img) | |
| noisy = clean + torch.randn_like(clean) * self.sigma | |
| return clean, torch.clamp(noisy, 0.0, 1.0) | |
| def calculate_psnr(img1, img2): | |
| mse = torch.mean((img1 - img2) ** 2) | |
| if mse == 0: | |
| return float("inf") | |
| return 20 * math.log10(1.0 / math.sqrt(mse)) | |
| def classical_telegraph_step(u_n, u_n_minus_1, tau=0.2, gamma=1.0): | |
| kx = torch.tensor([[0, 0, 0], [-0.5, 0, 0.5], [0, 0, 0]], device=DEVICE).view( | |
| 1, 1, 3, 3 | |
| ) | |
| ky = torch.tensor([[0, -0.5, 0], [0, 0, 0], [0, 0.5, 0]], device=DEVICE).view( | |
| 1, 1, 3, 3 | |
| ) | |
| grad_x = F.conv2d(u_n, kx, padding=1) | |
| grad_y = F.conv2d(u_n, ky, padding=1) | |
| grad_mag = torch.sqrt(grad_x**2 + grad_y**2 + 1e-8) | |
| c = 1.0 / (1.0 + (grad_mag / 0.1) ** 2) | |
| divergence = F.conv2d(c * grad_x, kx, padding=1) + F.conv2d( | |
| c * grad_y, ky, padding=1 | |
| ) | |
| alpha = (2 + gamma * tau) / (1 + gamma * tau) | |
| beta = -1 / (1 + gamma * tau) | |
| lam = (tau**2) / (1 + gamma * tau) | |
| return alpha * u_n + beta * u_n_minus_1 + lam * divergence | |
| def run_eval(dataset_name, sigma): | |
| root = _testset_root(dataset_name) | |
| dataset = TestDataset(root, sigma) | |
| if len(dataset) == 0: | |
| print(f"[!] Skip {dataset_name}: no images in {os.path.abspath(root)}") | |
| return None | |
| dataloader = DataLoader(dataset, batch_size=1, shuffle=False) | |
| total_psnr = 0.0 | |
| for clean, noisy in dataloader: | |
| clean, noisy = clean.to(DEVICE), noisy.to(DEVICE) | |
| u_n_minus_1, u_n = noisy.clone(), noisy.clone() | |
| for _ in range(20): | |
| u_next = classical_telegraph_step(u_n, u_n_minus_1) | |
| u_n_minus_1, u_n = u_n, u_next | |
| total_psnr += calculate_psnr(clean, u_n) | |
| avg_psnr = total_psnr / len(dataset) | |
| sigma_int = int(round(sigma * 255.0)) | |
| print( | |
| f"[+] {dataset_name} sigma={sigma_int}/255 PSNR: {avg_psnr:.2f} dB " | |
| f"({len(dataset)} images)" | |
| ) | |
| return avg_psnr | |
| def main(): | |
| print("[*] Classical Majee 2020 baseline — Set12 & BSD68") | |
| for dataset_name in ("Set12", "BSD68"): | |
| for sigma in _SIGMAS: | |
| run_eval(dataset_name, sigma) | |
| print() | |
| if __name__ == "__main__": | |
| main() | |