Skip to content

Commit

Permalink
refactor(contrast): amend default color treatment
Browse files Browse the repository at this point in the history
  • Loading branch information
hahnec committed Dec 3, 2019
1 parent 06599cb commit 2ce2f5a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 18 deletions.
75 changes: 60 additions & 15 deletions plenopticam/lfp_extractor/lfp_contrast.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def __init__(self, p_lo=None, p_hi=None, *args, **kwargs):
self.p_lo = p_lo if p_lo is not None else 0.0
self.p_hi = p_hi if p_hi is not None else 1.0

self.ref_img = kwargs['ref_img'] if 'ref_img' in kwargs else self.central_view

# internal variables
self._contrast, self._brightness = (1., 1.)

Expand All @@ -54,19 +56,25 @@ def contrast_bal(self):

def post_lum(self):

self.proc_vp_arr(self.stretch_lum_vp, ch=0, msg='contrast eq')
self.proc_vp_arr(self.lum_norm, ch=0, msg='contrast eq')

def stretch_lum_vp(self, img, ch=None):
def lum_norm(self, img, ch=None, dtype=None):

# set default channel
ch = ch if ch is not None else 0

# set default data type
dtype = img.dtype if dtype is None else dtype

# RGB to YUV conversion
img = misc.clr_spc_conv.yuv_conv(img)
#img = misc.hsv_conv(img)
obj = misc.HistogramEqualizer(img=img, ch=ch)
obj.cdf_from_img()
obj.correct_histeq()
img = obj._ref_img
del obj

# normalization of Y (luminance channel) for given data type
img[..., ch] = misc.Normalizer(img=img[..., ch],
min=np.percentile(img[..., ch], self.p_lo*100),
max=np.percentile(img[..., ch], self.p_hi*100), dtype=dtype).type_norm()

# YUV to RGB conversion
img = misc.clr_spc_conv.yuv_conv(img, inverse=True)

return img
Expand All @@ -77,16 +85,53 @@ def auto_wht_bal(self, method=None):
self.sta.status_msg(msg='Auto white balance', opt=self.cfg.params[self.cfg.opt_prnt])
self.sta.progress(None, opt=self.cfg.params[self.cfg.opt_prnt])

ch_num = self.vp_img_arr.shape[-1] if len(self.vp_img_arr.shape) > 4 else 1
ch_num = self.vp_img_arr.shape[-1] if len(self.vp_img_arr.shape) > 4 else 3
for i in range(ch_num):
if method is None:
ref_ch = self.central_view[..., i]

# channel selection
ref_ch = self.ref_img[..., i]
img_ch = self.vp_img_arr[..., i]

# normalization of color channel
self.vp_img_arr[..., i] = misc.Normalizer(img=img_ch,
min=np.percentile(ref_ch, self.p_lo*100),
max=np.percentile(ref_ch, self.p_hi*100)).uint16_norm()
else:
self.set_stretch(ref_ch=self.central_view[..., i])
# brightness and contrast method
self.set_stretch(ref_ch=self.ref_img[..., i])
self.apply_stretch(ch=i)

# status update
self.sta.progress((i+1)/ch_num*100, opt=self.cfg.params[self.cfg.opt_prnt])

return True

def channel_bal(self, method=None):

# status update
self.sta.status_msg(msg='Auto white balance', opt=self.cfg.params[self.cfg.opt_prnt])
self.sta.progress(None, opt=self.cfg.params[self.cfg.opt_prnt])

ch_num = self.vp_img_arr.shape[-1] if len(self.vp_img_arr.shape) > 4 else 3

min = float('Inf')
max = 0.
for i in range(ch_num):
min = np.min([min, np.percentile(self.ref_img[..., i], self.p_lo * 100)])
max = np.max([max, np.percentile(self.ref_img[..., i], self.p_hi * 100)])

for i in range(ch_num):
if method is None:

# channel selection
img_ch = self.vp_img_arr[..., i]

# normalization of color channel
self.vp_img_arr[..., i] = misc.Normalizer(img=img_ch, min=min, max=max).uint16_norm()
else:
# brightness and contrast method
self.set_stretch(ref_ch=self.ref_img[..., i])
self.apply_stretch(ch=i)

# status update
Expand Down Expand Up @@ -144,7 +189,7 @@ def apply_stretch(self, img=None, ch=None):
# convert to float
f = img[..., ch].astype(np.float32)

# perform auto contrast (by default: "value" channel only)
# perform auto contrast (by default: "lum" channel only)
img[..., ch] = self._contrast * f + self._brightness

# clip to input extrema to remove contrast outliers
Expand All @@ -155,7 +200,7 @@ def apply_stretch(self, img=None, ch=None):

def set_stretch_lum(self, img=None):

img = img if img is not None else self.central_view
img = img if img is not None else self.ref_img

# use luminance channel for parameter analysis
ref_img = misc.clr_spc_conv.yuv_conv(img)
Expand All @@ -180,11 +225,11 @@ def apply_stretch_lum(self, img=None):
def set_stretch_hsv(self):

# use luminance channel for parameter analysis
ref_img = misc.clr_spc_conv.hsv_conv(self.central_view)
ref_img = misc.clr_spc_conv.hsv_conv(self.ref_img)
self.set_stretch(ref_ch=ref_img[..., 1]*(2**16-1))

def apply_stretch_hsv(self, img):
''' contrast and brightness rectification to luminance channel of provided RGB image '''
''' saturation '''

# color model conversion
hsv = misc.clr_spc_conv.hsv_conv(img)
Expand Down
8 changes: 5 additions & 3 deletions plenopticam/lfp_extractor/top_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,14 @@ def main(self):
del obj

if not self.sta.interrupt:
obj = LfpContrast(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta, p_lo=0.002, p_hi=0.998)
obj = LfpContrast(vp_img_arr=self.vp_img_arr, cfg=self.cfg, sta=self.sta, p_lo=0.005, p_hi=0.999)
# automatic white balance
if self.cfg.params[self.cfg.opt_awb_]:
obj.auto_wht_bal()
obj.p_lo = 0
obj.p_hi = 1
else:
obj.channel_bal()
obj.p_lo = 0
obj.p_hi = 1

# automatic saturation
if self.cfg.params[self.cfg.opt_sat_]:
Expand Down

0 comments on commit 2ce2f5a

Please sign in to comment.