[
  {
    "path": ".gitignore",
    "content": "# Add by user\n.vscode/\nresult/\ndata/\nsave_model/\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# celery beat schedule file\ncelerybeat-schedule\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 IDKiro\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# CBDNet-pytorch\n\nIt's an unofficial PyTorch implementation of CBDNet.\n\nWe used higher quality real and synthetic datasets for training and achieved better performance on DND.\n\n[CBDNet in MATLAB](https://github.com/GuoShi28/CBDNet)\n\n[CBDNet in Tensorflow](https://github.com/IDKiro/CBDNet-tensorflow)\n\n## Quick Start\n\nDownload the dataset and pretrained model from [GoogleDrive](https://drive.google.com/drive/folders/1-e2nPCr_eP1cTDhFFes27Rjj-QXzMk5u?usp=sharing).\n\nExtract the files to `data` folder and `save_model` folder as follow:\n\n```\n~/\n  data/\n    SIDD_train/\n      ... (scene id)\n    Syn_train/\n      ... (id)\n    DND/\n      images_srgb/\n        ... (mat files)\n      ... (mat files)\n  save_model/\n    checkpoint.pth.tar\n```\n\nTrain the model:\n\n```\npython train.py\n```\n\nPredict using the trained model:\n\n```\npython predict.py input_filename output_filename\n```\n\n## Network Structure\n\n![Image of Network](imgs/CBDNet_v13.png)\n\n## Realistic Noise Model\nGiven a clean image `x`, the realistic noise model can be represented as:\n\n![](http://latex.codecogs.com/gif.latex?\\\\textbf{y}=f(\\\\textbf{DM}(\\\\textbf{L}+n(\\\\textbf{L}))))\n\n![](http://latex.codecogs.com/gif.latex?n(\\\\textbf{L})=n_s(\\\\textbf{L})+n_c)\n\nWhere `y` is the noisy image, `f(.)` is the CRF function and the irradiance ![](http://latex.codecogs.com/gif.latex?\\\\textbf{L}=\\\\textbf{M}f^{-1}(\\\\textbf{x})) , `M(.)` represents the function that convert sRGB image to Bayer image and `DM(.)` represents the demosaicing function.\n\nIf considering denosing on compressed images, \n\n![](http://latex.codecogs.com/gif.latex?\\\\textbf{y}=JPEG(f(\\\\textbf{DM}(\\\\textbf{L}+n(\\\\textbf{L})))))\n\n## Result\n\n![](imgs/results.png)\n"
  },
  {
    "path": "dataset/__init__.py",
    "content": ""
  },
  {
    "path": "dataset/loader.py",
    "content": "import os\nimport random\nimport torch\nimport numpy as np\nimport glob\nfrom torch.utils.data import Dataset\n\nfrom utils import read_img, hwc_to_chw\n\n\ndef get_patch(imgs, patch_size):\n\tH = imgs[0].shape[0]\n\tW = imgs[0].shape[1]\n\n\tps_temp = min(H, W, patch_size)\n\n\txx = np.random.randint(0, W-ps_temp) if W > ps_temp else 0\n\tyy = np.random.randint(0, H-ps_temp) if H > ps_temp else 0\n\n\tfor i in range(len(imgs)):\n\t\timgs[i] = imgs[i][yy:yy+ps_temp, xx:xx+ps_temp, :]\n\n\tif np.random.randint(2, size=1)[0] == 1:\n\t\tfor i in range(len(imgs)):\n\t\t\timgs[i] = np.flip(imgs[i], axis=1)\n\tif np.random.randint(2, size=1)[0] == 1: \n\t\tfor i in range(len(imgs)):\n\t\t\timgs[i] = np.flip(imgs[i], axis=0)\n\tif np.random.randint(2, size=1)[0] == 1:\n\t\tfor i in range(len(imgs)):\n\t\t\timgs[i] = np.transpose(imgs[i], (1, 0, 2))\n\n\treturn imgs\n\n\nclass Real(Dataset):\n\tdef __init__(self, root_dir, sample_num, patch_size=128):\n\t\tself.patch_size = patch_size\n\n\t\tfolders = glob.glob(root_dir + '/*')\n\t\tfolders.sort()\n\n\t\tself.clean_fns = [None] * sample_num\n\t\tfor i in range(sample_num):\n\t\t\tself.clean_fns[i] = []\n\n\t\tfor ind, folder in enumerate(folders):\n\t\t\tclean_imgs = glob.glob(folder + '/*GT_SRGB*')\n\t\t\tclean_imgs.sort()\n\n\t\t\tfor clean_img in clean_imgs:\n\t\t\t\tself.clean_fns[ind % sample_num].append(clean_img)\n\n\tdef __len__(self):\n\t\tl = len(self.clean_fns)\n\t\treturn l\n\n\tdef __getitem__(self, idx):\n\t\tclean_fn = random.choice(self.clean_fns[idx])\n\n\t\tclean_img = read_img(clean_fn)\n\t\tnoise_img = read_img(clean_fn.replace('GT_SRGB', 'NOISY_SRGB'))\n\n\t\tif self.patch_size > 0:\n\t\t\t[clean_img, noise_img] = get_patch([clean_img, noise_img], self.patch_size)\n\n\t\treturn hwc_to_chw(noise_img), hwc_to_chw(clean_img), np.zeros((3, self.patch_size, self.patch_size)), np.zeros((3, self.patch_size, self.patch_size))\n\n\nclass Syn(Dataset):\n\tdef __init__(self, root_dir, sample_num, patch_size=128):\n\t\tself.patch_size = patch_size\n\n\t\tfolders = glob.glob(root_dir + '/*')\n\t\tfolders.sort()\n\n\t\tself.clean_fns = [None] * sample_num\n\t\tfor i in range(sample_num):\n\t\t\tself.clean_fns[i] = []\n\n\t\tfor ind, folder in enumerate(folders):\n\t\t\tclean_imgs = glob.glob(folder + '/*GT_SRGB*')\n\t\t\tclean_imgs.sort()\n\n\t\t\tfor clean_img in clean_imgs:\n\t\t\t\tself.clean_fns[ind % sample_num].append(clean_img)\n\n\tdef __len__(self):\n\t\tl = len(self.clean_fns)\n\t\treturn l\n\n\tdef __getitem__(self, idx):\n\t\tclean_fn = random.choice(self.clean_fns[idx])\n\n\t\tclean_img = read_img(clean_fn)\n\t\tnoise_img = read_img(clean_fn.replace('GT_SRGB', 'NOISY_SRGB'))\n\t\tsigma_img = read_img(clean_fn.replace('GT_SRGB', 'SIGMA_SRGB')) / 15.\t# inverse scaling\n\n\t\tif self.patch_size > 0:\n\t\t\t[clean_img, noise_img, sigma_img] = get_patch([clean_img, noise_img, sigma_img], self.patch_size)\n\n\t\treturn hwc_to_chw(noise_img), hwc_to_chw(clean_img), hwc_to_chw(sigma_img), np.ones((3, self.patch_size, self.patch_size))"
  },
  {
    "path": "model/__init__.py",
    "content": ""
  },
  {
    "path": "model/cbdnet.py",
    "content": "\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n\nclass single_conv(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(single_conv, self).__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(in_ch, out_ch, 3, padding=1),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self, x):\n        return self.conv(x)\n\n\nclass up(nn.Module):\n    def __init__(self, in_ch):\n        super(up, self).__init__()\n        self.up = nn.ConvTranspose2d(in_ch, in_ch//2, 2, stride=2)\n\n    def forward(self, x1, x2):\n        x1 = self.up(x1)\n        \n        # input is CHW\n        diffY = x2.size()[2] - x1.size()[2]\n        diffX = x2.size()[3] - x1.size()[3]\n\n        x1 = F.pad(x1, (diffX // 2, diffX - diffX//2,\n                        diffY // 2, diffY - diffY//2))\n\n        x = x2 + x1\n        return x\n\n\nclass outconv(nn.Module):\n    def __init__(self, in_ch, out_ch):\n        super(outconv, self).__init__()\n        self.conv = nn.Conv2d(in_ch, out_ch, 1)\n\n    def forward(self, x):\n        x = self.conv(x)\n        return x\n\n\nclass FCN(nn.Module):\n    def __init__(self):\n        super(FCN, self).__init__()\n        self.fcn = nn.Sequential(\n            nn.Conv2d(3, 32, 3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(32, 32, 3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(32, 32, 3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(32, 32, 3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(32, 3, 3, padding=1),\n            nn.ReLU(inplace=True)\n        )\n    \n    def forward(self, x):\n        return self.fcn(x)\n\n\nclass UNet(nn.Module):\n    def __init__(self):\n        super(UNet, self).__init__()\n        \n        self.inc = nn.Sequential(\n            single_conv(6, 64),\n            single_conv(64, 64)\n        )\n\n        self.down1 = nn.AvgPool2d(2)\n        self.conv1 = nn.Sequential(\n            single_conv(64, 128),\n            single_conv(128, 128),\n            single_conv(128, 128)\n        )\n\n        self.down2 = nn.AvgPool2d(2)\n        self.conv2 = nn.Sequential(\n            single_conv(128, 256),\n            single_conv(256, 256),\n            single_conv(256, 256),\n            single_conv(256, 256),\n            single_conv(256, 256),\n            single_conv(256, 256)\n        )\n\n        self.up1 = up(256)\n        self.conv3 = nn.Sequential(\n            single_conv(128, 128),\n            single_conv(128, 128),\n            single_conv(128, 128)\n        )\n\n        self.up2 = up(128)\n        self.conv4 = nn.Sequential(\n            single_conv(64, 64),\n            single_conv(64, 64)\n        )\n\n        self.outc = outconv(64, 3)\n\n    def forward(self, x):\n        inx = self.inc(x)\n\n        down1 = self.down1(inx)\n        conv1 = self.conv1(down1)\n\n        down2 = self.down2(conv1)\n        conv2 = self.conv2(down2)\n\n        up1 = self.up1(conv2, conv1)\n        conv3 = self.conv3(up1)\n\n        up2 = self.up2(conv3, inx)\n        conv4 = self.conv4(up2)\n\n        out = self.outc(conv4)\n        return out\n\n\nclass Network(nn.Module):\n    def __init__(self):\n        super(Network, self).__init__()\n        self.fcn = FCN()\n        self.unet = UNet()\n    \n    def forward(self, x):\n        noise_level = self.fcn(x)\n        concat_img = torch.cat([x, noise_level], dim=1)\n        out = self.unet(concat_img) + x\n        return noise_level, out\n\n\nclass fixed_loss(nn.Module):\n    def __init__(self):\n        super().__init__()\n        \n    def forward(self, out_image, gt_image, est_noise, gt_noise, if_asym):\n        l2_loss = F.mse_loss(out_image, gt_image)\n\n        asym_loss = torch.mean(if_asym * torch.abs(0.3 - torch.lt(gt_noise, est_noise).float()) * torch.pow(est_noise - gt_noise, 2))\n\n        h_x = est_noise.size()[2]\n        w_x = est_noise.size()[3]\n        count_h = self._tensor_size(est_noise[:, :, 1:, :])\n        count_w = self._tensor_size(est_noise[:, :, : ,1:])\n        h_tv = torch.pow((est_noise[:, :, 1:, :] - est_noise[:, :, :h_x-1, :]), 2).sum()\n        w_tv = torch.pow((est_noise[:, :, :, 1:] - est_noise[:, :, :, :w_x-1]), 2).sum()\n        tvloss = h_tv / count_h + w_tv / count_w\n\n        loss = l2_loss +  0.5 * asym_loss + 0.05 * tvloss\n\n        return loss\n\n    def _tensor_size(self, t):\n        return t.size()[1]*t.size()[2]*t.size()[3]"
  },
  {
    "path": "predict.py",
    "content": "import os, time, scipy.io, shutil\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport argparse\nimport cv2\n\nfrom model.cbdnet import Network\nfrom utils import read_img, chw_to_hwc, hwc_to_chw\n\nparser = argparse.ArgumentParser(description = 'Test')\nparser.add_argument('input_filename', type=str)\nparser.add_argument('output_filename', type=str)\nargs = parser.parse_args()\n\nsave_dir = './save_model/'\n\nmodel = Network()\nmodel.cuda()\nmodel = nn.DataParallel(model)\n\nmodel.eval()\n\nif os.path.exists(os.path.join(save_dir, 'checkpoint.pth.tar')):\n    # load existing model\n    model_info = torch.load(os.path.join(save_dir, 'checkpoint.pth.tar'))\n    model.load_state_dict(model_info['state_dict'])\nelse:\n    print('Error: no trained model detected!')\n    exit(1)\n\ninput_image = read_img(args.input_filename)\ninput_var =  torch.from_numpy(hwc_to_chw(input_image)).unsqueeze(0).cuda()\n\nwith torch.no_grad():\n    _, output = model(input_var)\n\noutput_image = chw_to_hwc(output[0,...].cpu().numpy())\noutput_image = np.uint8(np.round(np.clip(output_image, 0, 1) * 255.))[: ,: ,::-1]\n\ncv2.imwrite(args.output_filename, output_image)"
  },
  {
    "path": "train.py",
    "content": "import os, time, shutil\nimport argparse\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom utils import AverageMeter\nfrom dataset.loader import Real, Syn\nfrom model.cbdnet import Network, fixed_loss\n\n\nparser = argparse.ArgumentParser(description = 'Train')\nparser.add_argument('--bs', default=32, type=int, help='batch size')\nparser.add_argument('--ps', default=128, type=int, help='patch size')\nparser.add_argument('--lr', default=2e-4, type=float, help='learning rate')\nparser.add_argument('--epochs', default=5000, type=int, help='sum of epochs')\nargs = parser.parse_args()\n\n\ndef train(train_loader, model, criterion, optimizer):\n\tlosses = AverageMeter()\n\tmodel.train()\n\n\tfor (noise_img, clean_img, sigma_img, flag) in train_loader:\n\t\tinput_var = noise_img.cuda()\n\t\ttarget_var = clean_img.cuda()\n\t\tsigma_var = sigma_img.cuda()\n\t\tflag_var = flag.cuda()\n\n\t\tnoise_level_est, output = model(input_var)\n\n\t\tloss = criterion(output, target_var, noise_level_est, sigma_var, flag_var)\n\t\tlosses.update(loss.item())\n\n\t\toptimizer.zero_grad()\n\t\tloss.backward()\n\t\toptimizer.step()\n\t\n\treturn losses.avg\n\n\nif __name__ == '__main__':\n\tsave_dir = './save_model/'\n\n\tmodel = Network()\n\tmodel.cuda()\n\tmodel = nn.DataParallel(model)\n\n\tif os.path.exists(os.path.join(save_dir, 'checkpoint.pth.tar')):\n\t\t# load existing model\n\t\tmodel_info = torch.load(os.path.join(save_dir, 'checkpoint.pth.tar'))\n\t\tprint('==> loading existing model:', os.path.join(save_dir, 'checkpoint.pth.tar'))\n\t\tmodel.load_state_dict(model_info['state_dict'])\n\t\toptimizer = torch.optim.Adam(model.parameters())\n\t\toptimizer.load_state_dict(model_info['optimizer'])\n\t\tscheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=args.epochs)\n\t\tscheduler.load_state_dict(model_info['scheduler'])\n\t\tcur_epoch = model_info['epoch']\n\telse:\n\t\tif not os.path.isdir(save_dir):\n\t\t\tos.makedirs(save_dir)\n\t\t# create model\n\t\toptimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n\t\tscheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=args.epochs)\n\t\tcur_epoch = 0\n\t\t\n\tcriterion = fixed_loss()\n\tcriterion.cuda()\n\n\ttrain_dataset = Real('./data/SIDD_train/', 320, args.ps) + Syn('./data/Syn_train/', 100, args.ps)\n\ttrain_loader = torch.utils.data.DataLoader(\n\t\ttrain_dataset, batch_size=args.bs, shuffle=True, num_workers=8, pin_memory=True, drop_last=True)\n\n\tfor epoch in range(cur_epoch, args.epochs + 1):\n\t\tloss = train(train_loader, model, criterion, optimizer)\n\t\tscheduler.step()\n\n\t\ttorch.save({\n\t\t\t'epoch': epoch + 1,\n\t\t\t'state_dict': model.state_dict(),\n\t\t\t'optimizer' : optimizer.state_dict(),\n\t\t\t'scheduler' : scheduler.state_dict()}, \n\t\t\tos.path.join(save_dir, 'checkpoint.pth.tar'))\n\n\t\tprint('Epoch [{0}]\\t'\n\t\t\t'lr: {lr:.6f}\\t'\n\t\t\t'Loss: {loss:.5f}'\n\t\t\t.format(\n\t\t\tepoch,\n\t\t\tlr=optimizer.param_groups[-1]['lr'],\n\t\t\tloss=loss))\n"
  },
  {
    "path": "utils/__init__.py",
    "content": "from .common import AverageMeter, ListAverageMeter, read_img, hwc_to_chw, chw_to_hwc"
  },
  {
    "path": "utils/common.py",
    "content": "import numpy as np\nimport cv2\n\n\nclass AverageMeter(object):\n\tdef __init__(self):\n\t\tself.reset()\n\n\tdef reset(self):\n\t\tself.val = 0\n\t\tself.avg = 0\n\t\tself.sum = 0\n\t\tself.count = 0\n\n\tdef update(self, val, n=1):\n\t\tself.val = val\n\t\tself.sum += val * n\n\t\tself.count += n\n\t\tself.avg = self.sum / self.count\n\n\nclass ListAverageMeter(object):\n\t\"\"\"Computes and stores the average and current values of a list\"\"\"\n\tdef __init__(self):\n\t\tself.len = 10000  # set up the maximum length\n\t\tself.reset()\n\n\tdef reset(self):\n\t\tself.val = [0] * self.len\n\t\tself.avg = [0] * self.len\n\t\tself.sum = [0] * self.len\n\t\tself.count = 0\n\n\tdef set_len(self, n):\n\t\tself.len = n\n\t\tself.reset()\n\n\tdef update(self, vals, n=1):\n\t\tassert len(vals) == self.len, 'length of vals not equal to self.len'\n\t\tself.val = vals\n\t\tfor i in range(self.len):\n\t\t\tself.sum[i] += self.val[i] * n\n\t\tself.count += n\n\t\tfor i in range(self.len):\n\t\t\tself.avg[i] = self.sum[i] / self.count\n\t\t\t\n\ndef read_img(filename):\n\timg = cv2.imread(filename)\n\timg = img[:,:,::-1] / 255.0\n\t\t\n\timg = np.array(img).astype('float32')\n\n\treturn img\n\n\ndef hwc_to_chw(img):\n\treturn np.transpose(img, axes=[2, 0, 1]).astype('float32')\n\n\ndef chw_to_hwc(img):\n\treturn np.transpose(img, axes=[1, 2, 0]).astype('float32')\n"
  },
  {
    "path": "utils/syn/ISP_implement.py",
    "content": "import random\nimport numpy as np\nimport cv2\nimport os\nimport json\nimport scipy.io\nimport math\nimport skimage\n\nfrom modules import demosaicing_CFA_Bayer_Malvar2004, CRF_Map_Cython, ICRF_Map_Cython\n\n\nclass ISP:\n    def __init__(self, curve_path='./'):\n        filename = os.path.join(curve_path, 'metadata/201_CRF_data.mat')\n        CRFs = scipy.io.loadmat(filename)\n        self.I = CRFs['I']\n        self.B = CRFs['B']\n        filename = os.path.join(curve_path, 'metadata/dorfCurvesInv.mat')\n        inverseCRFs = scipy.io.loadmat(filename)\n        self.I_inv = inverseCRFs['invI']\n        self.B_inv = inverseCRFs['invB']\n        filename = os.path.join(curve_path, 'metadata/cameras.json')\n        with open(filename, 'r') as load_f:\n            self.cameras = json.load(load_f)\n\n    def ICRF_Map(self, img):\n        invI_temp = self.I_inv[self.icrf_index, :]\n        invB_temp = self.B_inv[self.icrf_index, :]\n        out = ICRF_Map_Cython(img.astype(np.double), invI_temp.astype(np.double), invB_temp.astype(np.double))\n        return out\n\n    def CRF_Map(self, img):\n        I_temp = self.I[self.icrf_index, :]  # shape: (1024, 1)\n        B_temp = self.B[self.icrf_index, :]  # shape: (1024, 1)\n        out = CRF_Map_Cython(img.astype(np.double), I_temp.astype(np.double), B_temp.astype(np.double))\n        return out\n\n    def RGB2XYZ(self, img):\n        xyz = skimage.color.rgb2xyz(img)\n        return xyz\n\n    def XYZ2RGB(self, img):\n        rgb = skimage.color.xyz2rgb(img)\n        return rgb\n\n    def XYZ2CAM(self, img):\n        M_xyz2cam = np.reshape(self.M_xyz2cam, (3, 3))\n        M_xyz2cam = M_xyz2cam / np.tile(np.sum(M_xyz2cam, axis=1), [3, 1]).T\n        cam = self.apply_cmatrix(img, M_xyz2cam)\n        cam = np.clip(cam, 0, 1)\n        return cam\n\n    def CAM2XYZ(self, img):\n        M_xyz2cam = np.reshape(self.M_xyz2cam, (3, 3))\n        M_xyz2cam = M_xyz2cam / np.tile(np.sum(M_xyz2cam, axis=1), [3, 1]).T\n        M_cam2xyz = np.linalg.inv(M_xyz2cam)\n        xyz = self.apply_cmatrix(img, M_cam2xyz)\n        xyz = np.clip(xyz, 0, 1)\n        return xyz\n\n    def apply_cmatrix(self, img, matrix):\n        r = (matrix[0, 0] * img[:, :, 0] + matrix[0, 1] * img[:, :, 1]\n             + matrix[0, 2] * img[:, :, 2])\n        g = (matrix[1, 0] * img[:, :, 0] + matrix[1, 1] * img[:, :, 1]\n             + matrix[1, 2] * img[:, :, 2])\n        b = (matrix[2, 0] * img[:, :, 0] + matrix[2, 1] * img[:, :, 1]\n             + matrix[2, 2] * img[:, :, 2])\n        r = np.expand_dims(r, axis=2)\n        g = np.expand_dims(g, axis=2)\n        b = np.expand_dims(b, axis=2)\n        results = np.concatenate((r, g, b), axis=2)\n        return results\n\n    def mosaic_bayer(self, rgb):\n        # analysis pattern\n        num = np.zeros(4, dtype=int)\n        # the image store in OpenCV using BGR\n        temp = list(self.find(self.pattern, 'R'))\n        num[temp] = 0\n        temp = list(self.find(self.pattern, 'G'))\n        num[temp] = 1\n        temp = list(self.find(self.pattern, 'B'))\n        num[temp] = 2\n\n        mosaic_img = np.zeros((rgb.shape[0], rgb.shape[1]), dtype=rgb.dtype)\n        mosaic_img[0::2, 0::2] = rgb[0::2, 0::2, num[0]]\n        mosaic_img[0::2, 1::2] = rgb[0::2, 1::2, num[1]]\n        mosaic_img[1::2, 0::2] = rgb[1::2, 0::2, num[2]]\n        mosaic_img[1::2, 1::2] = rgb[1::2, 1::2, num[3]]\n        return mosaic_img\n\n    def WB_Mask(self, img, fr_now, fb_now):\n        wb_mask = np.ones(img.shape)\n        if  self.pattern == 'RGGB':\n            wb_mask[0::2, 0::2] = fr_now\n            wb_mask[1::2, 1::2] = fb_now\n        elif  self.pattern == 'BGGR':\n            wb_mask[1::2, 1::2] = fr_now\n            wb_mask[0::2, 0::2] = fb_now\n        elif  self.pattern == 'GRBG':\n            wb_mask[0::2, 1::2] = fr_now\n            wb_mask[1::2, 0::2] = fb_now\n        elif  self.pattern == 'GBRG':\n            wb_mask[1::2, 0::2] = fr_now\n            wb_mask[0::2, 1::2] = fb_now\n        return wb_mask\n\n\n    def find(self, str, ch):\n        for i, ltr in enumerate(str):\n            if ltr == ch:\n                yield i\n\n    def Demosaic(self, bayer):\n        results = demosaicing_CFA_Bayer_Malvar2004(bayer, self.pattern)\n        results = np.clip(results, 0, 1)\n        return results\n    \n    def add_PG_noise(self, img):\n        min_log = np.log([0.0001])\n        max_log_s = np.log([0.01])\n\n        log_sigma_s = min_log + np.random.rand(1) * (max_log_s - min_log)\n        sigma_s = np.exp(log_sigma_s)\n\n        line_c = 2.2 * log_sigma_s + 1.2\n        offset_c = np.random.normal(0.0, 0.26)\n        log_sigma_c = line_c + offset_c\n        sigma_c = np.exp(log_sigma_c)\n\n        # add noise\n        sigma_total = np.sqrt(sigma_s * img + sigma_c)\n\n        noisy_img = img +  \\\n            sigma_total * np.random.randn(img.shape[0], img.shape[1])\n        return noisy_img, sigma_s, sigma_c\n\n    def noise_generate_srgb(self, img, configs='DND'):\n        # -------------------------- CAMERA SETTING --------------------------\n        cameras = self.cameras[configs]\n        camera = cameras[random.randint(0, len(cameras)-1)]\n\n        self.icrf_index = random.randint(0, 200)\n\n        try:\n            self.pattern = camera['bayertype']\n        except:\n            self.pattern = random.choice(['GRBG', 'RGGB', 'GBRG', 'BGGR'])\n\n        try:\n            ColorMatrix1 = camera['ColorMatrix1']\n            ColorMatrix2 = camera['ColorMatrix2']\n            alpha = np.random.random_sample([1])\n            self.M_xyz2cam = alpha * ColorMatrix1 + (1 - alpha) * ColorMatrix2\n        except:\n            cam_index = np.random.random((1, 4))\n            cam_index = cam_index / np.sum(cam_index)\n            self.M_xyz2cam = ([1.0234,-0.2969,-0.2266,-0.5625,1.6328,-0.0469,-0.0703,0.2188,0.6406] * cam_index[0, 0] + \\\n                            [0.4913,-0.0541,-0.0202,-0.613,1.3513,0.2906,-0.1564,0.2151,0.7183] * cam_index[0, 1] + \\\n                            [0.838,-0.263,-0.0639,-0.2887,1.0725,0.2496,-0.0627,0.1427,0.5438] * cam_index[0, 2] + \\\n                            [0.6596,-0.2079,-0.0562,-0.4782,1.3016,0.1933,-0.097,0.1581,0.5181] * cam_index[0, 3])\n\n        try:\n            min_offset = -0.05\n            max_offset = 0.05\n            AsShotNeutral = camera['AsShotNeutral']\n            self.fr_now = AsShotNeutral[0] + random.uniform(min_offset, max_offset)\n            self.fb_now = AsShotNeutral[2] + random.uniform(min_offset, max_offset)\n        except:\n            min_fc = 0.75\n            max_fc = 1\n            self.fr_now = random.uniform(min_fc, max_fc)\n            self.fb_now = random.uniform(min_fc, max_fc)\n        \n        try:\n            blacklevel = camera['blacklevel']\n            whitelevel = camera['whitelevel']\n        except:\n            blacklevel = 254\n            whitelevel = 4094\n        \n        # -------------------------- INVERSE ISP PROCESS --------------------------\n        img_rgb = img\n        # Step 1 : inverse tone mapping\n        img_L = self.ICRF_Map(img_rgb)\n        # Step 2 : from RGB to XYZ\n        img_XYZ = self.RGB2XYZ(img_L)\n        # Step 3: from XYZ to Cam\n        img_Cam = self.XYZ2CAM(img_XYZ)\n        # Step 4: Mosaic\n        img_mosaic = self.mosaic_bayer(img_Cam)\n        # Step 5: inverse White Balance\n        wb_mask = self.WB_Mask(img_mosaic, self.fr_now, self.fb_now)\n        img_mosaic = img_mosaic * wb_mask\n        img_mosaic_gt = img_mosaic\n\n        # -------------------------- POISSON-GAUSSIAN NOISE ON RAW --------------------------\n        img_mosaic_noise, sigma_s, sigma_c = self.add_PG_noise(img_mosaic)\n\n        # -------------------------- QUANTIZATION NOISE AND CLIPPING EFFECT ON RAW --------------------------\n        upper_bound = math.pow(2, math.ceil(math.log(whitelevel + 1, 2))) - 1\n        img_mosaic_noise = np.clip(np.floor(img_mosaic_noise * (whitelevel - blacklevel) + blacklevel), 0, upper_bound)\n        img_mosaic_noise = (img_mosaic_noise - blacklevel) / (whitelevel - blacklevel)\n        img_mosaic_gt = np.clip(np.floor(img_mosaic_gt * (whitelevel - blacklevel) + blacklevel), 0, upper_bound)\n        img_mosaic_gt = (img_mosaic_gt - blacklevel) / (whitelevel - blacklevel)\n\n        # -------------------------- ISP PROCESS --------------------------\n        # Step 5 : White Balance\n        wb_mask = self.WB_Mask(img_mosaic_noise, 1/self.fr_now, 1/self.fb_now)\n        img_mosaic_noise = img_mosaic_noise * wb_mask\n        img_mosaic_noise = np.clip(img_mosaic_noise, 0, 1)\n        img_mosaic_gt = img_mosaic_gt * wb_mask\n        img_mosaic_gt = np.clip(img_mosaic_gt, 0, 1)\n        # Step 4 : Demosaic\n        img_demosaic = self.Demosaic(img_mosaic_noise)\n        img_demosaic_gt = self.Demosaic(img_mosaic_gt)\n        # Step 3 : from Cam to XYZ\n        img_IXYZ = self.CAM2XYZ(img_demosaic)\n        img_IXYZ_gt = self.CAM2XYZ(img_demosaic_gt)\n        # Step 2 : frome XYZ to RGB\n        img_IL = self.XYZ2RGB(img_IXYZ)\n        img_IL_gt = self.XYZ2RGB(img_IXYZ_gt)\n        # Step 1 : tone mapping\n        img_Irgb = self.CRF_Map(img_IL)\n        img_Irgb_gt = self.CRF_Map(img_IL_gt)\n\n        # -------------------------- QUANTIZATION NOISE AND CLIPPING EFFECT ON RGB --------------------------\n        noise = np.clip(img_Irgb, 0, 1) - np.clip(img_Irgb_gt, 0, 1)\n        img_Irgb_gt = np.clip(img_rgb, 0, 1)\n        img_Irgb = np.clip((img_rgb + noise), 0, 1)\n\n        sigma_total = np.sqrt(sigma_s * img + sigma_c)  # noise level map\n\n        return np.uint8(np.round(img_Irgb_gt*255)), np.uint8(np.round(img_Irgb*255)), sigma_total\n"
  },
  {
    "path": "utils/syn/generate_dataset.py",
    "content": "import os\nimport random, math\nimport torch\nimport numpy as np\nimport glob\nimport cv2\nfrom tqdm import tqdm\nfrom skimage import io\n\nfrom ISP_implement import ISP\n\n\nif __name__ == '__main__':\n\tisp = ISP()\n\n\tsource_dir = './source/'\n\ttarget_dir = './target/'\n\n\tif not os.path.isdir(target_dir):\n\t\tos.makedirs(target_dir)\n\n\tfns = glob.glob(os.path.join(source_dir, '*.png'))\n\n\tpatch_size = 256\n\n\tfor fn in tqdm(fns):\n\t\timg_rgb = cv2.imread(fn)[:, :, ::-1] / 255.0\n\n\t\tH = img_rgb.shape[0]\n\t\tW = img_rgb.shape[1]\n\n\t\tH_s = H // patch_size\n\t\tW_s = W // patch_size\n\n\t\tpatch_id = 0\n\n\t\tfor i in range(H_s):\n\t\t\tfor j in range(W_s):\n\t\n\t\t\t\tyy = i * patch_size\n\t\t\t\txx = j * patch_size\n\n\t\t\t\tpatch_img_rgb = img_rgb[yy:yy+patch_size, xx:xx+patch_size, :]\n\n\t\t\t\tgt, noise, sigma = isp.noise_generate_srgb(patch_img_rgb)\n\n\t\t\t\tsigma = np.uint8(np.round(np.clip(sigma * 15 , 0, 1) * 255))\t# store in uint8\n\n\t\t\t\tfilename = os.path.basename(fn)\n\t\t\t\tfoldername = filename.split('.')[0]\n\n\t\t\t\tout_folder = os.path.join(target_dir, foldername)\n\n\t\t\t\tif not os.path.isdir(out_folder):\n\t\t\t\t\tos.makedirs(out_folder)\n\n\t\t\t\tio.imsave(os.path.join(out_folder, 'GT_SRGB_%d_%d.png' % (i, j)), gt)\n\t\t\t\tio.imsave(os.path.join(out_folder, 'NOISY_SRGB_%d_%d.png' % (i, j)), noise)\n\t\t\t\tio.imsave(os.path.join(out_folder, 'SIGMA_SRGB_%d_%d.png' % (i, j)), sigma)\n"
  },
  {
    "path": "utils/syn/metadata/cameras.json",
    "content": "{\n    \"DND\": [\n        {\n            \"bayertype\": \"GBRG\",\n            \"blacklevel\": 52.0,\n            \"whitelevel\": 1023.0,\n            \"ColorMatrix1\": [\n                0.8203,\n                -0.2266,\n                -0.125,\n                -0.3203,\n                1.2656,\n                0.0391,\n                -0.0391,\n                0.2266,\n                0.4531\n            ],\n            \"ColorMatrix2\": [\n                1.0234,\n                -0.2969,\n                -0.2266,\n                -0.5625,\n                1.6328,\n                -0.0469,\n                -0.0703,\n                0.2188,\n                0.6406\n            ],\n            \"AsShotNeutral\": [\n                0.4922,\n                1.0078,\n                0.6016\n            ]\n        },\n        {\n            \"bayertype\": \"RGGB\",\n            \"blacklevel\": 256.0,\n            \"whitelevel\": 7680.0,\n            \"ColorMatrix1\": [\n                0.7216,\n                -0.2921,\n                0.035,\n                -0.4204,\n                1.1461,\n                0.3143,\n                -0.0767,\n                0.1485,\n                0.7418\n            ],\n            \"ColorMatrix2\": [\n                0.4913,\n                -0.0541,\n                -0.0202,\n                -0.613,\n                1.3513,\n                0.2906,\n                -0.1564,\n                0.2151,\n                0.7183\n            ],\n            \"AsShotNeutral\": [\n                0.419,\n                1.0,\n                0.6275\n            ]\n        },\n        {\n            \"bayertype\": \"RGGB\",\n            \"blacklevel\": 254.0,\n            \"whitelevel\": 4094.0,\n            \"ColorMatrix1\": [\n                0.9033,\n                -0.3597,\n                0.026,\n                -0.2351,\n                0.97,\n                0.3111,\n                -0.0181,\n                0.0807,\n                0.5838\n            ],\n            \"ColorMatrix2\": [\n                0.838,\n                -0.263,\n                -0.0639,\n                -0.2887,\n                1.0725,\n                0.2496,\n                -0.0627,\n                0.1427,\n                0.5438\n            ],\n            \"AsShotNeutral\": [\n                0.5246,\n                1.0,\n                0.5424\n            ]\n        },\n        {\n            \"bayertype\": \"GBRG\",\n            \"blacklevel\": 254.0,\n            \"whitelevel\": 4094.0,\n            \"ColorMatrix1\": [\n                0.9033,\n                -0.3597,\n                0.026,\n                -0.2351,\n                0.97,\n                0.3111,\n                -0.0181,\n                0.0807,\n                0.5838\n            ],\n            \"ColorMatrix2\": [\n                0.838,\n                -0.263,\n                -0.0639,\n                -0.2887,\n                1.0725,\n                0.2496,\n                -0.0627,\n                0.1427,\n                0.5438\n            ],\n            \"AsShotNeutral\": [\n                0.5246,\n                1.0,\n                0.5424\n            ]\n        },\n        {\n            \"bayertype\": \"RGGB\",\n            \"blacklevel\": 400.0,\n            \"whitelevel\": 7680.0,\n            \"ColorMatrix1\": [\n                0.7366,\n                -0.3213,\n                0.038,\n                -0.3609,\n                1.1127,\n                0.2852,\n                -0.0218,\n                0.0694,\n                0.5821\n            ],\n            \"ColorMatrix2\": [\n                0.6596,\n                -0.2079,\n                -0.0562,\n                -0.4782,\n                1.3016,\n                0.1933,\n                -0.097,\n                0.1581,\n                0.5181\n            ],\n            \"AsShotNeutral\": [\n                0.4044,\n                1.0,\n                0.5356\n            ]\n        },\n        {\n            \"bayertype\": \"GRBG\",\n            \"blacklevel\": 400.0,\n            \"whitelevel\": 7680.0,\n            \"ColorMatrix1\": [\n                0.7366,\n                -0.3213,\n                0.038,\n                -0.3609,\n                1.1127,\n                0.2852,\n                -0.0218,\n                0.0694,\n                0.5821\n            ],\n            \"ColorMatrix2\": [\n                0.6596,\n                -0.2079,\n                -0.0562,\n                -0.4782,\n                1.3016,\n                0.1933,\n                -0.097,\n                0.1581,\n                0.5181\n            ],\n            \"AsShotNeutral\": [\n                0.4044,\n                1.0,\n                0.5356\n            ]\n        }\n    ],\n    \"SIDD\": [\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.56640625,\n                1.0,\n                0.4951171875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.4140625,\n                1.0,\n                0.5859375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.484375,\n                1.0,\n                0.6328125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.4609375,\n                1.0,\n                0.6875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.406349,\n                1.0,\n                0.601468\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.5703125,\n                1.0078125,\n                0.5078125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.407806,\n                1.0,\n                0.640901\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.640625,\n                1.0,\n                0.515625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.71875,\n                1.0,\n                0.4921875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.5478515625,\n                1.0,\n                0.576171875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.546875,\n                1.0,\n                0.625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.515625,\n                1.0,\n                0.65625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.583984375,\n                1.0,\n                0.5869140625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.5546875,\n                0.9921875,\n                0.5078125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.5752,\n                1.0,\n                0.407076\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.796875,\n                0.9921875,\n                0.390625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.71875,\n                1.0,\n                0.484375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.751953125,\n                1.0,\n                0.59375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.65625,\n                0.9921875,\n                0.4296875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.590712,\n                1.0,\n                0.453448\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.609375,\n                1.0,\n                0.5\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.5625,\n                1.0,\n                0.515625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.4951171875,\n                1.0,\n                0.576171875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.4453125,\n                0.9921875,\n                0.53125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.343221,\n                1.0,\n                0.593365\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.578125,\n                1.0,\n                0.53125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.5859375,\n                1.0,\n                0.515625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.5234375,\n                1.0,\n                0.5947265625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.4140625,\n                0.9921875,\n                0.5703125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.383592,\n                1.0,\n                0.555993\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.625,\n                1.0,\n                0.609375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.578125,\n                1.0,\n                0.609375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.5556640625,\n                1.0,\n                0.626953125\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.546875,\n                0.9921875,\n                0.4375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.524523,\n                1.0,\n                0.480638\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6796875,\n                -0.078125,\n                -0.09375,\n                -0.4609375,\n                1.296875,\n                0.1328125,\n                -0.109375,\n                0.25,\n                0.5234375\n            ],\n            \"ColorMatrix2\": [\n                1.1875,\n                -0.4140625,\n                -0.25,\n                -0.4609375,\n                1.5,\n                0.015625,\n                -0.046875,\n                0.2109375,\n                0.59375\n            ],\n            \"AsShotNeutral\": [\n                0.71875,\n                1.0,\n                0.5234375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.5859375,\n                0.0546875,\n                -0.125,\n                -0.6484375,\n                1.5546875,\n                0.0546875,\n                -0.2421875,\n                0.5625,\n                0.390625\n            ],\n            \"ColorMatrix2\": [\n                1.15625,\n                -0.2890625,\n                -0.3203125,\n                -0.53125,\n                1.5625,\n                0.0625,\n                -0.078125,\n                0.28125,\n                0.5625\n            ],\n            \"AsShotNeutral\": [\n                0.59375,\n                1.0,\n                0.5546875\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.6640625,\n                -0.0458984375,\n                -0.1201171875,\n                -0.54296875,\n                1.4384765625,\n                0.0712890625,\n                -0.1767578125,\n                0.4052734375,\n                0.4755859375\n            ],\n            \"ColorMatrix2\": [\n                1.23828125,\n                -0.4443359375,\n                -0.2783203125,\n                -0.4501953125,\n                1.4697265625,\n                0.0693359375,\n                -0.08984375,\n                0.2919921875,\n                0.61328125\n            ],\n            \"AsShotNeutral\": [\n                0.6005859375,\n                1.0,\n                0.6416015625\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.7265625,\n                -0.1953125,\n                -0.0859375,\n                -0.5625,\n                1.3515625,\n                0.1640625,\n                -0.2265625,\n                0.3046875,\n                0.53125\n            ],\n            \"ColorMatrix2\": [\n                1.0703125,\n                -0.3125,\n                -0.28125,\n                -0.5625,\n                1.65625,\n                -0.1171875,\n                -0.0546875,\n                0.1875,\n                0.5859375\n            ],\n            \"AsShotNeutral\": [\n                0.546875,\n                0.9921875,\n                0.4375\n            ]\n        },\n        {\n            \"ColorMatrix1\": [\n                0.8353,\n                -0.3171,\n                -0.1289,\n                -0.3878,\n                1.1893,\n                0.2237,\n                -0.038,\n                0.1056,\n                0.6397\n            ],\n            \"ColorMatrix2\": [\n                0.7418,\n                -0.2398,\n                -0.061,\n                -0.5006,\n                1.2972,\n                0.2248,\n                -0.1074,\n                0.1419,\n                0.59\n            ],\n            \"AsShotNeutral\": [\n                0.630736,\n                1.0,\n                0.419586\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "utils/syn/modules/Demosaicing_malvar2004.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nMalvar (2004) Bayer CFA Demosaicing\n===================================\n\n*Bayer* CFA (Colour Filter Array) *Malvar (2004)* demosaicing.\n\nReferences\n----------\n-   :cite:`Malvar2004a` : Malvar, H. S., He, L.-W., Cutler, R., & Way, O. M.\n    (2004). High-Quality Linear Interpolation for Demosaicing of\n    Bayer-Patterned Color Images. In International Conference of Acoustic,\n    Speech and Signal Processing (pp. 5-8). Institute of Electrical and\n    Electronics Engineers, Inc. Retrieved from\n    http://research.microsoft.com/apps/pubs/default.aspx?id=102068\n    https://colour-demosaicing.readthedocs.io/en/develop/_modules/colour_demosaicing/bayer/demosaicing/malvar2004.html\n\"\"\"\n\nfrom __future__ import division, unicode_literals\n\nimport numpy as np\nfrom scipy.ndimage.filters import convolve\n\n#from colour.utilities import tstack\nimport cv2\n\nfrom .masks import masks_CFA_Bayer\n\n__author__ = 'Colour Developers'\n__copyright__ = 'Copyright (C) 2015-2018 - Colour Developers'\n__license__ = 'New BSD License - http://opensource.org/licenses/BSD-3-Clause'\n__maintainer__ = 'Colour Developers'\n__email__ = 'colour-science@googlegroups.com'\n__status__ = 'Production'\n\n__all__ = ['demosaicing_CFA_Bayer_Malvar2004']\n\n\ndef demosaicing_CFA_Bayer_Malvar2004(CFA, pattern='RGGB'):\n    \"\"\"\n    Returns the demosaiced *RGB* colourspace array from given *Bayer* CFA using\n    *Malvar (2004)* demosaicing algorithm.\n\n    Parameters\n    ----------\n    CFA : array_like\n        *Bayer* CFA.\n    pattern : unicode, optional\n        **{'RGGB', 'BGGR', 'GRBG', 'GBRG'}**,\n        Arrangement of the colour filters on the pixel array.\n\n    Returns\n    -------\n    ndarray\n        *RGB* colourspace array.\n\n    Notes\n    -----\n    -   The definition output is not clipped in range [0, 1] : this allows for\n        direct HDRI / radiance image generation on *Bayer* CFA data and post\n        demosaicing of the high dynamic range data as showcased in this\n        `Jupyter Notebook <https://github.com/colour-science/colour-hdri/\\\nblob/develop/colour_hdri/examples/\\\nexamples_merge_from_raw_files_with_post_demosaicing.ipynb>`_.\n\n    References\n    ----------\n    -   :cite:`Malvar2004a`\n\n    Examples\n    --------\n    >>> CFA = np.array(\n    ...     [[0.30980393, 0.36078432, 0.30588236, 0.3764706],\n    ...      [0.35686275, 0.39607844, 0.36078432, 0.40000001]])\n    >>> demosaicing_CFA_Bayer_Malvar2004(CFA)\n    array([[[ 0.30980393,  0.31666668,  0.32941177],\n            [ 0.33039216,  0.36078432,  0.38112746],\n            [ 0.30588236,  0.32794118,  0.34877452],\n            [ 0.36274511,  0.3764706 ,  0.38480393]],\n    <BLANKLINE>\n           [[ 0.34828432,  0.35686275,  0.36568628],\n            [ 0.35318628,  0.38186275,  0.39607844],\n            [ 0.3379902 ,  0.36078432,  0.3754902 ],\n            [ 0.37769609,  0.39558825,  0.40000001]]])\n    >>> CFA = np.array(\n    ...     [[0.3764706, 0.360784320, 0.40784314, 0.3764706],\n    ...      [0.35686275, 0.30980393, 0.36078432, 0.29803923]])\n    >>> demosaicing_CFA_Bayer_Malvar2004(CFA, 'BGGR')\n    array([[[ 0.35539217,  0.37058825,  0.3764706 ],\n            [ 0.34264707,  0.36078432,  0.37450981],\n            [ 0.36568628,  0.39607844,  0.40784314],\n            [ 0.36568629,  0.3764706 ,  0.3882353 ]],\n    <BLANKLINE>\n           [[ 0.34411765,  0.35686275,  0.36200981],\n            [ 0.30980393,  0.32990197,  0.34975491],\n            [ 0.33039216,  0.36078432,  0.38063726],\n            [ 0.29803923,  0.30441178,  0.31740197]]])\n    \"\"\"\n\n    CFA = np.asarray(CFA)\n    R_m, G_m, B_m = masks_CFA_Bayer(CFA.shape, pattern)\n\n    GR_GB = np.asarray(\n        [[0, 0, -1, 0, 0],\n         [0, 0, 2, 0, 0],\n         [-1, 2, 4, 2, -1],\n         [0, 0, 2, 0, 0],\n         [0, 0, -1, 0, 0]]) / 8  # yapf: disable\n\n    Rg_RB_Bg_BR = np.asarray(\n        [[0, 0, 0.5, 0, 0],\n         [0, -1, 0, -1, 0],\n         [-1, 4, 5, 4, - 1],\n         [0, -1, 0, -1, 0],\n         [0, 0, 0.5, 0, 0]]) / 8  # yapf: disable\n\n    Rg_BR_Bg_RB = np.transpose(Rg_RB_Bg_BR)\n\n    Rb_BB_Br_RR = np.asarray(\n        [[0, 0, -1.5, 0, 0],\n         [0, 2, 0, 2, 0],\n         [-1.5, 0, 6, 0, -1.5],\n         [0, 2, 0, 2, 0],\n         [0, 0, -1.5, 0, 0]]) / 8  # yapf: disable\n\n    R = CFA * R_m\n    G = CFA * G_m\n    B = CFA * B_m\n\n    del G_m\n\n    G = np.where(np.logical_or(R_m == 1, B_m == 1), convolve(CFA, GR_GB), G)\n\n    RBg_RBBR = convolve(CFA, Rg_RB_Bg_BR)\n    RBg_BRRB = convolve(CFA, Rg_BR_Bg_RB)\n    RBgr_BBRR = convolve(CFA, Rb_BB_Br_RR)\n\n    del GR_GB, Rg_RB_Bg_BR, Rg_BR_Bg_RB, Rb_BB_Br_RR\n\n    # Red rows.\n    R_r = np.transpose(np.any(R_m == 1, axis=1)[np.newaxis]) * np.ones(R.shape)\n    # Red columns.\n    R_c = np.any(R_m == 1, axis=0)[np.newaxis] * np.ones(R.shape)\n    # Blue rows.\n    B_r = np.transpose(np.any(B_m == 1, axis=1)[np.newaxis]) * np.ones(B.shape)\n    # Blue columns\n    B_c = np.any(B_m == 1, axis=0)[np.newaxis] * np.ones(B.shape)\n\n    del R_m, B_m\n\n    R = np.where(np.logical_and(R_r == 1, B_c == 1), RBg_RBBR, R)\n    R = np.where(np.logical_and(B_r == 1, R_c == 1), RBg_BRRB, R)\n\n    B = np.where(np.logical_and(B_r == 1, R_c == 1), RBg_RBBR, B)\n    B = np.where(np.logical_and(R_r == 1, B_c == 1), RBg_BRRB, B)\n\n    R = np.where(np.logical_and(B_r == 1, B_c == 1), RBgr_BBRR, R)\n    B = np.where(np.logical_and(R_r == 1, R_c == 1), RBgr_BBRR, B)\n\n    del RBg_RBBR, RBg_BRRB, RBgr_BBRR, R_r, R_c, B_r, B_c\n\n    #return tstack((R, G, B))\n    return cv2.merge([R, G, B])"
  },
  {
    "path": "utils/syn/modules/__init__.py",
    "content": "from .Demosaicing_malvar2004 import demosaicing_CFA_Bayer_Malvar2004\nimport pyximport; pyximport.install()\nfrom .tone_mapping_cython import CRF_Map_Cython, ICRF_Map_Cython"
  },
  {
    "path": "utils/syn/modules/masks.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"\nBayer CFA Masks\n===============\n\n*Bayer* CFA (Colour Filter Array) masks generation.\n\"\"\"\n\nfrom __future__ import division, unicode_literals\n\nimport numpy as np\n\n__author__ = 'Colour Developers'\n__copyright__ = 'Copyright (C) 2015-2018 - Colour Developers'\n__license__ = 'New BSD License - http://opensource.org/licenses/BSD-3-Clause'\n__maintainer__ = 'Colour Developers'\n__email__ = 'colour-science@googlegroups.com'\n__status__ = 'Production'\n\n__all__ = ['masks_CFA_Bayer']\n\n\ndef masks_CFA_Bayer(shape, pattern='RGGB'):\n    \"\"\"\n    Returns the *Bayer* CFA red, green and blue masks for given pattern.\n\n    Parameters\n    ----------\n    shape : array_like\n        Dimensions of the *Bayer* CFA.\n    pattern : unicode, optional\n        **{'RGGB', 'BGGR', 'GRBG', 'GBRG'}**,\n        Arrangement of the colour filters on the pixel array.\n\n    Returns\n    -------\n    tuple\n        *Bayer* CFA red, green and blue masks.\n\n    Examples\n    --------\n    >>> from pprint import pprint\n    >>> shape = (3, 3)\n    >>> pprint(masks_CFA_Bayer(shape))\n    (array([[ True, False,  True],\n           [False, False, False],\n           [ True, False,  True]], dtype=bool),\n     array([[False,  True, False],\n           [ True, False,  True],\n           [False,  True, False]], dtype=bool),\n     array([[False, False, False],\n           [False,  True, False],\n           [False, False, False]], dtype=bool))\n    >>> pprint(masks_CFA_Bayer(shape, 'BGGR'))\n    (array([[False, False, False],\n           [False,  True, False],\n           [False, False, False]], dtype=bool),\n     array([[False,  True, False],\n           [ True, False,  True],\n           [False,  True, False]], dtype=bool),\n     array([[ True, False,  True],\n           [False, False, False],\n           [ True, False,  True]], dtype=bool))\n    \"\"\"\n\n    pattern = pattern.upper()\n\n    channels = dict((channel, np.zeros(shape)) for channel in 'RGB')\n    for channel, (y, x) in zip(pattern, [(0, 0), (0, 1), (1, 0), (1, 1)]):\n        channels[channel][y::2, x::2] = 1\n\n    return tuple(channels[c].astype(bool) for c in 'RGB')\n"
  },
  {
    "path": "utils/syn/modules/tone_mapping_cython.pyx",
    "content": "# Power by Zongsheng Yue 2019-06-11 21:23:27\n\nimport numpy as np\nfrom math import floor\n\ndef CRF_Map_Cython(double[:, :, :] img, double[:] I, double[:] B):\n    cdef Py_ssize_t h = img.shape[0]\n    cdef Py_ssize_t w = img.shape[1]\n    cdef Py_ssize_t c = img.shape[2]\n    cdef Py_ssize_t bin = I.shape[0]\n\n    cdef int ii, jj, cc, start_bin, b, index\n    out = np.zeros((h,w,c), dtype=np.float64)\n    cdef double[:,:,:] out_view = out\n\n    cdef double tiny_bin = 9.7656e-04      # 1/1024 = 9.7656e-04\n    cdef double min_tiny_bin = 0.0039\n    cdef temp, tempB, comp1, comp2\n\n    for ii in range(h):\n        for jj in range(w):\n            for cc in range(c):\n                temp = img[ii, jj, cc]\n                start_bin = 1\n                if temp > min_tiny_bin:\n                    start_bin = floor(temp / tiny_bin - 1)\n                for b in range(start_bin, bin):\n                    tempI = I[b]\n                    if tempI >= temp:\n                        index = b\n                        if index > 1:\n                            comp1 = tempI - temp\n                            comp2 = temp - I[index - 1]\n                            if comp2 < comp1:\n                                index -= 1\n                        out_view[ii, jj, cc] = B[index]\n                        break\n    return out\n\ndef ICRF_Map_Cython(double[:, :, :] img, double[:] invI, double[:] invB):\n    cdef Py_ssize_t h = img.shape[0]\n    cdef Py_ssize_t w = img.shape[1]\n    cdef Py_ssize_t c = img.shape[2]\n    cdef Py_ssize_t bin = invI.shape[0]\n\n    cdef int ii, jj, cc, start_bin, b, index\n    out = np.zeros((h,w,c), dtype=np.float64)\n    cdef double[:,:,:] out_view = out\n\n    cdef double tiny_bin = 9.7656e-04      # 1/1024 = 9.7656e-04\n    cdef double min_tiny_bin = 0.0039\n    cdef temp, tempB, comp1, comp2\n\n    for ii in range(h):\n        for jj in range(w):\n            for cc in range(c):\n                temp = img[ii, jj, cc]\n                start_bin = 1\n                if temp > min_tiny_bin:\n                    start_bin = floor(temp / tiny_bin - 1)\n                for b in range(start_bin, bin):\n                    tempB = invB[b]\n                    if tempB >= temp:\n                        index = b\n                        if index > 1:\n                            comp1 = tempB - temp\n                            comp2 = temp - invB[index - 1]\n                            if comp2 < comp1:\n                                index -= 1\n                        out_view[ii, jj, cc] = invI[index]\n                        break\n    return out\n\n"
  }
]