Tweaks and fixes
This commit is contained in:
parent
48db8f070f
commit
9e67dcebd6
@ -1,5 +1,7 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
import math
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
from wavelength import wavelength_to_ansi
|
||||||
|
|
||||||
def gaussian_sensitivity(peak1, peak2, sigma, wavelengths, depth=2):
|
def gaussian_sensitivity(peak1, peak2, sigma, wavelengths, depth=2):
|
||||||
if depth <= 0: return 0
|
if depth <= 0: return 0
|
||||||
@ -19,12 +21,13 @@ sigma_starling = 35
|
|||||||
human_peaks = {(437, 315): 'blue', (533,345): 'green', (564,355): 'red'}
|
human_peaks = {(437, 315): 'blue', (533,345): 'green', (564,355): 'red'}
|
||||||
|
|
||||||
# Starling cone sensitivities (including UV)
|
# Starling cone sensitivities (including UV)
|
||||||
starling_peaks = {(362,250): 'violet', (449,320): 'blue', (504,340): 'green', (563,360): 'red'}
|
starling_peaks = {(362,250): 'violet', (449,320): 'cyan', (504,340): 'green', (563,360): 'red'}
|
||||||
|
|
||||||
ANSI_COLORS = {
|
ANSI_COLORS = {
|
||||||
"blue": "\033[34m",
|
"blue": "\033[34m",
|
||||||
"red": "\033[31m",
|
"red": "\033[31m",
|
||||||
"green": "\033[32m",
|
"green": "\033[32m",
|
||||||
|
"cyan": "\033[36m",
|
||||||
"violet": "\033[38;5;177m",
|
"violet": "\033[38;5;177m",
|
||||||
"purple": "\033[38;5;177m",
|
"purple": "\033[38;5;177m",
|
||||||
}
|
}
|
||||||
@ -53,27 +56,40 @@ plt.tight_layout()
|
|||||||
plt.savefig("retinal_cones.png")
|
plt.savefig("retinal_cones.png")
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
def bar(progress : float, width : int):
|
||||||
|
progress = min(1, max(0, progress))
|
||||||
|
whole_width = math.floor(progress * width)
|
||||||
|
remainder_width = (progress * width) % 1
|
||||||
|
part_width = math.floor(remainder_width * 8)
|
||||||
|
part_char = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉"][part_width]
|
||||||
|
if (width - whole_width - 1) < 0:
|
||||||
|
part_char = ""
|
||||||
|
line = "\033[48;5;237m" + "█" * whole_width + part_char + " " * (width - whole_width - 1) + "\033[40m"
|
||||||
|
return line
|
||||||
|
|
||||||
def human_activations(color_name, wavelengths, verbose=False):
|
def human_activations(color_name, wavelengths, verbose=False):
|
||||||
raw_activations = {}
|
raw_activations = {}
|
||||||
for (peak1,peak2), color in human_peaks.items():
|
for (peak1,peak2), color in human_peaks.items():
|
||||||
raw_activations[color] = gaussian_sensitivity(peak1, peak2, sigma_human, wavelengths)
|
raw_activations[color] = gaussian_sensitivity(peak1, peak2, sigma_human, wavelengths)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"\033[1mHumans\033[m see {ANSI_COLORS[color_name]}{color_name}\033[m as:")
|
print(f"\033[1mHumans\033[m see {color_name}\033[m as:")
|
||||||
|
|
||||||
activations = []
|
activations = []
|
||||||
for color,levels in raw_activations.items():
|
for color,levels in raw_activations.items():
|
||||||
k = sum(levels)/sum(sum(l) for l in raw_activations.values())
|
k = sum(levels)/sum(sum(l) for l in raw_activations.values())
|
||||||
activations.append(k)
|
activations.append(k)
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"{ANSI_COLORS[color]}{color}: \033[10G {k:%}\033[m")
|
print(f"{ANSI_COLORS[color]}{color}: \033[10G {k:%} \033[30G{bar(k, 30)}\033[m")
|
||||||
if verbose:
|
if verbose:
|
||||||
print("")
|
print("")
|
||||||
vec = np.array(activations)
|
vec = np.array(activations)
|
||||||
return vec / np.linalg.norm(vec)
|
return vec / np.linalg.norm(vec)
|
||||||
|
|
||||||
human_activations("violet", np.array([380]), verbose=True)
|
colored_purple = "".join(f"\033[38;2;255;78;0m{c}" if i % 2 == 0 else f"\033[38;2;0;146;255m{c}" for i,c in enumerate("purple")) + "\033[m"
|
||||||
human_activations("purple", np.array([623, 462]), verbose=True)
|
colored_purple += " (\033[38;2;255;78;0m630nm\033[m & \033[38;2;0;146;255m465nm\033[m)"
|
||||||
|
human_activations("\033[38;5;177mviolet (384nm)\033[m", np.array([384]), verbose=True)
|
||||||
|
human_activations(colored_purple, np.array([630, 465]), verbose=True)
|
||||||
print("\nThey look the same to us!")
|
print("\nThey look the same to us!")
|
||||||
|
|
||||||
section_break()
|
section_break()
|
||||||
@ -84,21 +100,21 @@ def starling_activations(color_name, wavelengths, verbose=False):
|
|||||||
raw_activations[color] = gaussian_sensitivity(peak1, peak2, sigma_starling, wavelengths)
|
raw_activations[color] = gaussian_sensitivity(peak1, peak2, sigma_starling, wavelengths)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"\033[1mStarlings\033[m see {ANSI_COLORS[color_name]}{color_name}\033[m as:")
|
print(f"\033[1mStarlings\033[m see {color_name} as:")
|
||||||
|
|
||||||
activations = []
|
activations = []
|
||||||
for color,levels in raw_activations.items():
|
for color,levels in raw_activations.items():
|
||||||
k = sum(levels)/sum(sum(l) for l in raw_activations.values())
|
k = sum(levels)/sum(sum(l) for l in raw_activations.values())
|
||||||
activations.append(k)
|
activations.append(k)
|
||||||
if verbose:
|
if verbose:
|
||||||
print(f"{ANSI_COLORS[color]}{color}: \033[10G {k:%}\033[m")
|
print(f"{ANSI_COLORS[color]}{color}: \033[10G {k:%} \033[30G{bar(k, 30)}\033[m")
|
||||||
if verbose:
|
if verbose:
|
||||||
print("")
|
print("")
|
||||||
vec = np.array(activations)
|
vec = np.array(activations)
|
||||||
return vec / np.linalg.norm(vec)
|
return vec / np.linalg.norm(vec)
|
||||||
|
|
||||||
starling_activations("violet", np.array([380]), verbose=True)
|
starling_activations("\033[38;5;177mviolet (384nm)\033[m", np.array([384]), verbose=True)
|
||||||
starling_purple = starling_activations("purple", np.array([623, 455]), verbose=True)
|
starling_purple = starling_activations(colored_purple, np.array([630, 465]), verbose=True)
|
||||||
print("\nThey look completely differe to a starling!")
|
print("\nThey look completely differe to a starling!")
|
||||||
|
|
||||||
|
|
||||||
@ -106,68 +122,23 @@ section_break()
|
|||||||
|
|
||||||
print("...But what pure wavelength looks like purple?")
|
print("...But what pure wavelength looks like purple?")
|
||||||
|
|
||||||
def wavelength_to_rgb(wavelength, gamma=0.8):
|
|
||||||
'''
|
|
||||||
This converts a given wavelength of light to an
|
|
||||||
approximate RGB color value. The wavelength must be given
|
|
||||||
in nanometers in the range from 380 nm through 750 nm
|
|
||||||
(789 THz through 400 THz).
|
|
||||||
Based on code by Dan Bruton
|
|
||||||
http://www.physics.sfasu.edu/astro/color/spectra.html
|
|
||||||
'''
|
|
||||||
wavelength = float(wavelength)
|
|
||||||
if wavelength >= 380 and wavelength <= 440:
|
|
||||||
attenuation = 0.3 + 0.7 * (wavelength - 380) / (440 - 380)
|
|
||||||
R = ((-(wavelength - 440) / (440 - 380)) * attenuation) ** gamma
|
|
||||||
G = 0.0
|
|
||||||
B = (1.0 * attenuation) ** gamma
|
|
||||||
elif wavelength >= 440 and wavelength <= 490:
|
|
||||||
R = 0.0
|
|
||||||
G = ((wavelength - 440) / (490 - 440)) ** gamma
|
|
||||||
B = 1.0
|
|
||||||
elif wavelength >= 490 and wavelength <= 510:
|
|
||||||
R = 0.0
|
|
||||||
G = 1.0
|
|
||||||
B = (-(wavelength - 510) / (510 - 490)) ** gamma
|
|
||||||
elif wavelength >= 510 and wavelength <= 580:
|
|
||||||
R = ((wavelength - 510) / (580 - 510)) ** gamma
|
|
||||||
G = 1.0
|
|
||||||
B = 0.0
|
|
||||||
elif wavelength >= 580 and wavelength <= 645:
|
|
||||||
R = 1.0
|
|
||||||
G = (-(wavelength - 645) / (645 - 580)) ** gamma
|
|
||||||
B = 0.0
|
|
||||||
elif wavelength >= 645 and wavelength <= 750:
|
|
||||||
attenuation = 0.3 + 0.7 * (750 - wavelength) / (750 - 645)
|
|
||||||
R = (1.0 * attenuation) ** gamma
|
|
||||||
G = 0.0
|
|
||||||
B = 0.0
|
|
||||||
else:
|
|
||||||
R = 0.0
|
|
||||||
G = 0.0
|
|
||||||
B = 0.0
|
|
||||||
R *= 255
|
|
||||||
G *= 255
|
|
||||||
B *= 255
|
|
||||||
return (int(R), int(G), int(B))
|
|
||||||
|
|
||||||
print("")
|
|
||||||
closest_wavelength = None
|
closest_wavelength = None
|
||||||
best_dist = None
|
best_dist = None
|
||||||
import time
|
for wavelength in range(100,700,1):
|
||||||
for wavelength in range(100,700,2):
|
|
||||||
activations = starling_activations("???", np.array([wavelength]), verbose=False)
|
activations = starling_activations("???", np.array([wavelength]), verbose=False)
|
||||||
# dist = np.linalg.norm(starling_purple - activations)
|
# dist = np.linalg.norm(starling_purple - activations)
|
||||||
dist = np.dot(starling_purple, activations)
|
dist = np.dot(starling_purple, activations)
|
||||||
if closest_wavelength is None or dist > best_dist:
|
if closest_wavelength is None or dist > best_dist:
|
||||||
closest_wavelength, best_dist = wavelength, dist
|
closest_wavelength, best_dist = wavelength, dist
|
||||||
r,g,b = wavelength_to_rgb(wavelength)
|
|
||||||
#print(f"\033[48;2;{r};{g};{b}m Scanning: {closest_wavelength}nm... \033[m dist = {dist}", end="\033[K\n", flush=True)
|
#print(f"\033[48;2;{r};{g};{b}m Scanning: {closest_wavelength}nm... \033[m dist = {dist}", end="\033[K\n", flush=True)
|
||||||
|
|
||||||
section_break()
|
section_break()
|
||||||
|
|
||||||
r,g,b = wavelength_to_rgb(closest_wavelength)
|
color = wavelength_to_ansi(closest_wavelength)
|
||||||
print(f"\033[48;2;{r};{g};{b}m WINNER: {closest_wavelength}nm! (blue) \033[m\n\n")
|
print(f"{color}\033[30m WINNER: {closest_wavelength}nm! (blue) \033[m\n\n")
|
||||||
|
|
||||||
|
starling_activations(f"{color}blue ({closest_wavelength}nm)\033[m", np.array([closest_wavelength]), verbose=True)
|
||||||
|
print(f"Which looks more like {colored_purple} than any other pure wavelength!")
|
||||||
|
|
||||||
|
|
||||||
# import subprocess
|
# import subprocess
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 107 KiB |
Loading…
Reference in New Issue
Block a user