-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathraw_correction.py
66 lines (50 loc) · 2.52 KB
/
raw_correction.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
import numpy as np
import cv2
from pySP.bayer_chan_mixer import bayer_to_rgbg, rgbg_to_bayer
from .image import RawRgbgData
def dark_frame_subtraction(raw : RawRgbgData, dark_frame : RawRgbgData):
"""Remove dark current noise from an image.
Args:
raw (RawRgbgData): Raw RGBG image.
dark_frame (RawRgbgData): Raw dark frame RGBG image.
"""
return np.copy(raw)
def bias_frame_subtraction(raw : RawRgbgData, bias_frame : RawRgbgData):
"""Remove fixed-pattern noise from an image.
Args:
raw (RawRgbgData): Raw RGBG image.
bias_frame (RawRgbgData): Raw bias frame RGBG image.
"""
return np.copy(raw)
def flat_frame_correction(image : RawRgbgData, flat : RawRgbgData, clamp_high : bool = False):
"""Apply flat-frame correction in-place to an image.
The output for this method will always be a valid image, but steps are taken in-case of problematic data:
- Divide by zero is replaced by the maximal value of each channel after correction
- Missing flat frames will leave the image untouched
- Correction pushing below zero will clamp photosite values to zero.
Args:
image (RawRgbgData): Image to be corrected.
flat (RawRgbgData): Flat field image.
clamp_high (bool, optional): True to clamp corrected photosites at 1. Breaks HDR images but useful elsewhere. Defaults to False.
"""
if not(image.is_valid() and flat.is_valid()):
return
r, g1, b, g2 = bayer_to_rgbg(image.bayer_data_scaled)
flat_r, flat_g1, flat_b, flat_g2 = bayer_to_rgbg(flat.bayer_data_scaled)
def correct_channel(chan : np.ndarray, chan_flat : np.ndarray) -> np.ndarray:
# TODO - Add dark frame correction, currently we assume dark frame is zero
mean_chan = np.mean(chan_flat)
output = (chan * mean_chan) / chan_flat
if np.isinf(output).all():
# In the case where the flat frame was completely black, leave image alone
return np.copy(chan)
max_output = np.max(np.ma.masked_invalid(output))
output[output == np.inf] = max_output # Where we have infinity, replace with max channel
output[output < 0] = 0
if clamp_high:
output[output > 1] = 1
return output
image.bayer_data_scaled = rgbg_to_bayer(correct_channel(r, flat_r),
correct_channel(g1, flat_g1),
correct_channel(b, flat_b),
correct_channel(g2, flat_g2))