-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathdevelop_images.py
137 lines (106 loc) · 5.34 KB
/
develop_images.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import json
import logging
import argparse
import tensorflow as tf
from helpers import fsutil
logging.basicConfig(level=logging.INFO)
log = logging.getLogger('data')
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
extensions = '(npy)'
raw_extensions = ['.nef', '.dng', '.NEF', '.DNG']
supported_pipelines = ['libRAW', 'Python', 'INet', 'DNet', 'UNet']
def develop_images(camera, pipeline, n_images=0, root_dir='./data', model_dir='nip', dev_dir='developed', nip_params=None):
if pipeline not in supported_pipelines:
raise ValueError('Unsupported pipeline model ({})! Available models: {}'.format(pipeline, ', '.join(supported_pipelines)))
dir_models = os.path.join(root_dir, model_dir)
nip_directory = os.path.join(root_dir, 'raw', 'training_data', camera)
out_directory = os.path.join(root_dir, 'raw', dev_dir, camera, pipeline)
raw_directory = os.path.join(root_dir, 'raw', 'images', camera)
if not os.path.exists(nip_directory):
raise IOError('Directory not found! {}'.format(nip_directory))
if not os.path.exists(out_directory):
os.makedirs(out_directory)
# Lazy loading of remaining dependencies to ensure responsiveness of the CLI
import numpy as np
import imageio
import tqdm
from helpers import raw
from models import pipelines
print('Camera: {}'.format(camera))
print('Pipeline: {}'.format(pipeline))
print('NIP Models: {}'.format(dir_models))
print('NIP Training Directory: {}'.format(nip_directory))
print('Out Directory: {}'.format(out_directory))
# %% Process Bayer stacks with the given pipeline
npy_filenames = fsutil.listdir(nip_directory, '.*\.{}$'.format(extensions))
log.info('Camera {} matched {:,} Bayer stacks'.format(camera, len(npy_filenames)))
manual_dev_settings = {'use_srgb': True, 'use_gamma': True, 'brightness': None}
# Setup the NIP model
if pipeline.endswith('Net'):
sess = tf.Session()
model = getattr(pipelines, pipeline)(sess, tf.get_default_graph(), loss_metric='L2', **nip_params)
model.load_model(camera, out_directory_root=dir_models)
# Limit the number of images
if n_images > 0:
npy_filenames = npy_filenames[:n_images]
for npy_file in tqdm.tqdm(npy_filenames, ncols=120, desc='Developing ({}/{})'.format(camera, pipeline)):
# Find the original RAW file (for standard pipelines.py)
raw_file = os.path.join(raw_directory, os.path.splitext(npy_file)[0])
raw_found = False
for extension in raw_extensions:
if os.path.exists(raw_file + extension):
raw_file = raw_file + extension
raw_found = True
break
if not raw_found:
raise RuntimeError('RAW file not found for Bayer stack: {}'.format(npy_file))
out_png = os.path.join(out_directory, os.path.splitext(npy_file)[0] + '.png')
if not os.path.exists(out_png):
# Process with the desired pipeline
if pipeline == 'libRAW':
rgb = raw.process_auto(raw_file)
elif pipeline == 'Python':
rgb = 255 * raw.process(raw_file, **manual_dev_settings)
rgb = rgb.astype(np.uint8)
else:
# Find the cached Bayer stack
bayer_file = os.path.join(nip_directory, npy_file)
bayer_stack = np.load(bayer_file).astype(np.float32) / (2**16 - 1)
rgb = 255 * model.process(bayer_stack).squeeze()
rgb = rgb.astype(np.uint8)
imageio.imwrite(out_png, rgb.astype(np.uint8))
def main():
parser = argparse.ArgumentParser(description='Develops RAW images with a selected pipeline')
parser.add_argument('--cam', dest='camera', action='store', help='camera')
parser.add_argument('--pipe', dest='pipeline', action='store', default='libRAW',
help='imaging pipeline ({})'.format(supported_pipelines))
parser.add_argument('--dir', dest='dir', action='store', default='./data',
help='root directory with images and training data')
parser.add_argument('--model_dir', dest='model_dir', action='store', default='nip',
help='directory with TF models')
parser.add_argument('--dev_dir', dest='dev_dir', action='store', default='developed',
help='output directory')
parser.add_argument('--params', dest='nip_params', default=None, help='Extra parameters for NIP constructor (JSON string)')
parser.add_argument('--images', dest='images', action='store', default=0, type=int,
help='number of images to process')
args = parser.parse_args()
if not args.camera:
print('A camera needs to be specified!')
parser.print_usage()
sys.exit(1)
try:
if args.nip_params is not None:
args.nip_params = json.loads(args.nip_params.replace('\'', '"'))
except json.decoder.JSONDecodeError:
print('WARNING', 'JSON parsing error for: ', args.nip_params.replace('\'', '"'))
sys.exit(2)
try:
develop_images(args.camera, args.pipeline, args.images, args.dir, args.model_dir, args.dev_dir, nip_params=args.nip_params)
except Exception as error:
log.error(error)
if __name__ == "__main__":
main()