Last active
October 13, 2015 20:49
-
-
Save tp7/280dc3c7a0abcc6ff5dd to your computer and use it in GitHub Desktop.
Sample lutspa implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import cv2 | |
import numpy as np | |
binary_operators = { | |
"+": lambda x, y: x + y, | |
"-": lambda x, y: x - y, | |
"*": lambda x, y: x * y, | |
"/": lambda x, y: x / y, | |
} | |
class Context(object): | |
def __init__(self, ops_string): | |
self._tokens = [] | |
for token in reversed(ops_string.split()): | |
try: | |
self._tokens.append(float(token)) | |
except ValueError: | |
self._tokens.append(token) | |
self._pos = 0 | |
def reset(self): | |
self._pos = 0 | |
def consume(self): | |
value = self._tokens[self._pos] | |
self._pos += 1 | |
return value | |
def evaluate_core(x, y, context): | |
top = context.consume() | |
if top == 'x': | |
return x | |
elif top == 'y': | |
return y | |
elif top in binary_operators: | |
op = binary_operators[top] | |
right = evaluate_core(x, y, context) | |
left = evaluate_core(x, y, context) | |
return op(left, right) | |
elif isinstance(top, float): | |
return top | |
else: | |
raise ValueError("Unexpected operator: {0}".format(top)) | |
def evaluate_expression(expr_string): | |
context = Context(expr_string) | |
frame = np.empty((720, 1280), "uint8") | |
for y in range(720): | |
for x in range(1280): | |
frame[y,x] = min(max(0, evaluate_core(x, y, context)), 255) | |
context.reset() | |
cv2.imshow("", frame) | |
cv2.waitKey(0) | |
def run(): | |
evaluate_expression("x y + 5.0 / ") | |
if __name__ == "__main__": | |
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import cv2 | |
import time | |
import numpy as np | |
binary_functions = { | |
"+": np.add, | |
"-": np.subtract, | |
"*": np.multiply, | |
"/": np.divide, | |
"max": np.maximum, | |
"min": np.minimum | |
} | |
def evaluate_token(token, stack, x_list, y): | |
if token == 'x': | |
stack.append(x_list) | |
elif token == 'y': | |
stack.append(y) | |
elif isinstance(token, float): | |
stack.append(token) | |
elif token in binary_functions: | |
op = binary_functions[token] | |
right = stack.pop() | |
left = stack.pop() | |
stack.append(op(left, right)) | |
else: | |
raise ValueError("Unexpected token") | |
def evaluate_expression(expr_string): | |
tokens = expr_string.split() | |
for idx, token in enumerate(tokens): | |
try: | |
tokens[idx] = float(token) | |
except: | |
pass | |
before = time.time() | |
frame = np.empty((720, 1280), "float") | |
x_list = np.arange(0, 1280, dtype="float") | |
for y in range(720): | |
stack = [] | |
for token in tokens: | |
evaluate_token(token, stack, x_list, y) | |
frame[y] = stack.pop() | |
frame = frame.clip(0, 255).astype("uint8") | |
# cv2.imshow("", frame) | |
# cv2.waitKey(0) | |
print(time.time() - before) | |
def run(): | |
evaluate_expression("x y + 5.0 / 64 max 128 min") | |
if __name__ == "__main__": | |
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import cv2 | |
import time | |
import numpy as np | |
binary_operators = {"+", "-", "*", "/"} | |
binary_functions = {'min', 'max'} | |
class Context(object): | |
def __init__(self, ops_string): | |
self._tokens = [] | |
for token in reversed(ops_string.split()): | |
try: | |
self._tokens.append(float(token)) | |
except ValueError: | |
self._tokens.append(token) | |
self._pos = 0 | |
def reset(self): | |
self._pos = 0 | |
def consume(self): | |
value = self._tokens[self._pos] | |
self._pos += 1 | |
return value | |
def generate_code(context): | |
top = context.consume() | |
if top == 'x': | |
return 'x' | |
elif top == 'y': | |
return 'y' | |
elif top in binary_operators: | |
right = generate_code(context) | |
left = generate_code(context) | |
return "({0} {1} {2})".format(left, top, right) | |
elif top in binary_functions: | |
right = generate_code(context) | |
left = generate_code(context) | |
return '{0}({1}, {2})'.format(top, left, right) | |
elif isinstance(top, float): | |
return str(top) | |
else: | |
raise ValueError("Unexpected operator: {0}".format(top)) | |
def evaluate_expression(expr_string): | |
context = Context(expr_string) | |
code = generate_code(context) | |
bytecode = compile(code, "", "eval") | |
before = time.time() | |
frame = np.empty((720, 1280), "float") | |
variables = {} | |
for y in range(720): | |
for x in range(1280): | |
variables["x"], variables["y"] = x, y | |
frame[y,x] = eval(bytecode, {}, variables) | |
frame = frame.clip(0, 255).astype("uint8") | |
# cv2.imshow("", frame) | |
# cv2.waitKey(0) | |
print(time.time() - before) | |
def run(): | |
evaluate_expression("x y + 5.0 /") | |
if __name__ == "__main__": | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment