Skip to content

Commit

Permalink
Only calculate brightness based on the calculated ambient color, remo…
Browse files Browse the repository at this point in the history
…ve ignore black feature, make 0% minimum brightness the default
  • Loading branch information
cryzed committed Jan 20, 2018
1 parent ee95659 commit 8ed16aa
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 31 deletions.
18 changes: 6 additions & 12 deletions amby/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from amby.config import get_saved_username, save_username
from amby.constants import SUCCESS_EXIT_CODE, FAILURE_EXIT_CODE, PHILIPS_MAX_BRIGHTNESS, PHILIPS_MIN_BRIGHTNESS
from amby.core import get_average_color, get_pixel_data, get_relative_brightness, rgb_to_xy
from amby.core import get_average_color, get_pixel_data, rgb_to_xy, get_relative_luminance

argument_parser = argparse.ArgumentParser()
argument_parser.add_argument('bridge_address', help='The domain or IP address of the Philips Hue Bridge')
Expand All @@ -31,16 +31,11 @@
help='Specify which percentage of brightest colors to average in luminance mode')
argument_parser.add_argument(
'--change-brightness', '-b', action='store_true',
help='Adjust brightness of lights based on the overall relative luminance of the specified region. '
'Very CPU intensive!')
help='Adjust brightness of lights based on the overall relative luminance of the specified screen')
argument_parser.add_argument(
'--min-brightness', '-m', type=float, default=50, help='Minimum brightness in percent')
'--min-brightness', '-m', type=float, default=0, help='Minimum brightness in percent')
argument_parser.add_argument(
'--max-brightness', '-M', type=float, default=100, help='Maximum brightness in percent')
argument_parser.add_argument(
'--dont-ignore-black', '-B', dest='ignore_black', action='store_false',
help="Don't ignore absolutely black pixels. Absolutely black pixels are ignored by default because of the black "
"bars added by video players if the aspect ratio doesn't match, which skews the results")


def stderr(*args, **kwargs):
Expand Down Expand Up @@ -86,11 +81,10 @@ def change_light_states(state):
data = get_pixel_data(arguments.screen)
color = get_average_color(data)
if color != previous_color:
state = {'xy': rgb_to_xy(*color)}
state = {'xy': rgb_to_xy(color)}
if arguments.change_brightness:
state['bri'] = max(
min_brightness,
int(round(get_relative_brightness(data, arguments.ignore_black) * max_brightness)))
state['bri'] = max(min_brightness, int(round(get_relative_luminance(color) * max_brightness)))

change_light_states(state)

if arguments.run_once:
Expand Down
33 changes: 14 additions & 19 deletions amby/core.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import numpy as np
import rgbxy

from amby.constants import PHILIPS_MAX_BRIGHTNESS

try:
import PyQt5
from PyQt5.QtWidgets import QApplication
Expand All @@ -11,8 +9,8 @@
PyQt5 = None

# https://en.wikipedia.org/wiki/Relative_luminance
_luminance_multipliers = np.array([0.2126, 0.7152, 0.0722])
_max_luminance = np.dot([255, 255, 255], _luminance_multipliers)
_white_color = 255, 255, 255
_luminance_multipliers = 0.2126, 0.7152, 0.0722
_last_image_reference = None
_color_converter = rgbxy.Converter()

Expand Down Expand Up @@ -45,26 +43,23 @@ def get_pixel_data(screen=None, region=None):
raise Exception('no screenshot provider available')


def get_average_color(data):
return tuple(np.average(data, axis=0).round().astype(int))
def _get_absolute_luminance(color):
return sum(x * y for x, y in zip(color, _luminance_multipliers))


_max_luminance = _get_absolute_luminance(_white_color)


def get_relative_brightness(data, ignore_black):
max_brightness = _max_luminance * data.shape[0]
luminance = np.dot(data, _luminance_multipliers)
absolute_brightness = np.sum(luminance, axis=0)
def get_relative_luminance(color):
return _get_absolute_luminance(color) / _max_luminance

if ignore_black:
# Act like absolutely black pixels have a neutral effect on the absolute brightness by multiplying their amount
# with half of the maximum brightness
black_pixels = data.shape[0] - np.count_nonzero(luminance)
absolute_brightness += PHILIPS_MAX_BRIGHTNESS / 2 * black_pixels

return absolute_brightness / max_brightness
def get_average_color(data_matrix):
return tuple(np.average(data_matrix, axis=0).round().astype(int))


def rgb_to_xy(r, g, b):
def rgb_to_xy(color):
# Prevent DivisionByZero exception in rgbxy library:
# https://github.com/benknight/hue-python-rgb-converter/issues/6
r, g, b = tuple(max(component, 10 ** -3) for component in (r, g, b))
return _color_converter.rgb_to_xy(r, g, b)
color = tuple(max(component, 10 ** -3) for component in color)
return _color_converter.rgb_to_xy(*color)

0 comments on commit 8ed16aa

Please sign in to comment.