Example #1
0
def _diff_husl(a, b, max_rgb_diff=2):
    """Checks HUSL conversion by converting HUSL to RGB.
    Both HUSL triplets/arrays should produce the same RGB
    triplet/array."""
    rgb_a = nphusl.to_rgb(a).astype(np.int)
    rgb_b = nphusl.to_rgb(b).astype(np.int)
    make_fail = lambda: "HSL diff: {} (HSL-A: {} HSL-B: {})".format(
        a - b, a, b)

    # we check that the HUSL->RGB conversion for both
    # a and b are within 2 (in [0, 255] scale), and if that's not
    # true we may be dealing with a low saturation pixel or a dark
    # pixel where humans can't really tell the difference, so
    # we check the raw HUSL values so that they're within 2.0
    try:
        assert np.all(np.abs(rgb_a - rgb_b) <= max_rgb_diff), make_fail()
    except AssertionError:
        a = np.asarray(a)
        b = np.asarray(b)
        a_hue, a_sat, a_lit = (a[..., n] for n in range(3))
        b_hue, b_sat, b_lit = (b[..., n] for n in range(3))
        _diff(a_hue, b_hue, 0.3)
        _diff(a_sat, b_sat, 2.0)  # HUSL saturation is hard to approximate
        _diff(a_lit, b_lit, 0.1)
    imageio.imwrite("horkle.jpg", _img())
Example #2
0
def melonize(img, n_frames):
    hsl = nphusl.to_husl(img)
    hue, sat, lit = (hsl[..., n] for n in range(3))
    #sat[:] = 99
    pink = 360  # very end of the H spectrum
    green = 130

    def gen_chunksizes():
        yield from range(1, 100)
        yield from range(100, 1, -1)

    for chunksize in gen_chunksizes():
        hsl_out = hsl.copy()
        hue_out, sat_out, lit_out = (hsl_out[..., i] for i in range(3))
        for low, high in nphusl.chunk(100, chunksize):  # chunks of the hue range
            select = np.logical_and(lit > low, lit < high)
            is_odd = low % (chunksize * 2)
            color = pink if is_odd else green
            hue_out[select] = color
            select = np.logical_and(lit > (low - 1), lit < low)
            select = np.logical_and(select, lit > 60)
            ave = (low + high) / 2
            select = np.logical_and(lit > (ave - 2), lit < (ave + 2))
            sat_out[select] = 100
        yield nphusl.to_rgb(hsl_out)
Example #3
0
def microwave(img):
    hsl = nphusl.to_husl(img)
    hue = hsl[..., 0]
    rows, cols = hue.shape
    yield nphusl.to_rgb(hsl)
    while True:
        for chunk, ((rs, re), (cs, ce)) in nphusl.chunk_img(hue, chunksize=8):
            hue_left = hue[rs, cs - 1]
            hue_up = hue[rs - 1, cs]
            this_hue = chunk[0, 0]
            new_hue = (-random.randrange(30, 50) * (hue_up / 360) -
                       10 * random.randrange(1, 10) * (hue_left / 360))
            new_hue = (15 * this_hue + 2 * new_hue) / 17
            chunk[:] = new_hue
        np.mod(hue, 360, out=hue)
        yield nphusl.to_rgb(hsl)
Example #4
0
def melonize(img, n_frames):
    hsl = nphusl.to_husl(img)
    hue, sat, lit = (hsl[..., n] for n in range(3))
    #sat[:] = 99
    pink = 360  # very end of the H spectrum
    green = 130

    def gen_chunksizes():
        yield from range(1, 100)
        yield from range(100, 1, -1)

    for chunksize in gen_chunksizes():
        hsl_out = hsl.copy()
        hue_out, sat_out, lit_out = (hsl_out[..., i] for i in range(3))
        for low, high in nphusl.chunk(100,
                                      chunksize):  # chunks of the hue range
            select = np.logical_and(lit > low, lit < high)
            is_odd = low % (chunksize * 2)
            color = pink if is_odd else green
            hue_out[select] = color
            select = np.logical_and(lit > (low - 1), lit < low)
            select = np.logical_and(select, lit > 60)
            ave = (low + high) / 2
            select = np.logical_and(lit > (ave - 2), lit < (ave + 2))
            sat_out[select] = 100
        yield nphusl.to_rgb(hsl_out)
Example #5
0
def test_to_rgb_2d():
    img = _img()[:, 0]
    int_img = np.ndarray(shape=img.shape, dtype=np.uint8)
    int_img[:] = img * 255
    husl = nphusl.rgb_to_husl(img)
    rgb = nphusl.to_rgb(husl)
    assert np.all(rgb == int_img)
Example #6
0
def microwave(img):
    hsl = nphusl.to_husl(img)
    hue = hsl[..., 0]
    rows, cols = hue.shape
    yield nphusl.to_rgb(hsl)
    while True:
        for chunk, ((rs, re), (cs, ce)) in nphusl.chunk_img(hue, chunksize=8):
            hue_left = hue[rs, cs-1]
            hue_up = hue[rs-1, cs]
            this_hue = chunk[0, 0]
            new_hue = (-random.randrange(30, 50) * (hue_up / 360)
                       -10*random.randrange(1, 10) * (hue_left / 360))
            new_hue = (15*this_hue + 2*new_hue) / 17
            chunk[:] = new_hue
        np.mod(hue, 360, out=hue)
        yield nphusl.to_rgb(hsl)
Example #7
0
def reveal_blue(img):
    """Easy mode! Selecting bluish pixels with the HUSL color space."""
    # convert an integer RGB image to HUSL array of floats
    hsl = nphusl.to_husl(img)
    hue = hsl[..., 0]  # separate out the hue channel
    # create a mask for pixels with hues between 250 and 290 (blue)
    bluish = np.logical_and(hue > 250, hue < 290)
    hsl[..., 2][~bluish] *= 0.5  # halve lightness of non-bluish areas
    return nphusl.to_rgb(hsl), "blue"
Example #8
0
def reveal_blue(img):
    """Easy mode! Selecting bluish pixels with the HUSL color space."""
    # convert an integer RGB image to HUSL array of floats
    hsl = nphusl.to_husl(img)
    hue = hsl[..., 0]  # separate out the hue channel
    # create a mask for pixels with hues between 250 and 290 (blue)
    bluish = np.logical_and(hue > 250, hue < 290)
    hsl[..., 2][~bluish] *= 0.5  # halve lightness of non-bluish areas
    return nphusl.to_rgb(hsl), "blue"
Example #9
0
def hue_watermelon(img):
    hsl = nphusl.to_husl(img)
    hue, saturation, lightness = (hsl[..., n] for n in range(3))
    hue_out = hue.copy()
    pink = 360  # very end of the H spectrum
    green = 130
    chunksize = 45
    for low, high in nphusl.chunk(360, chunksize):  # chunks of the hue range
        select = np.logical_and(hue > low, hue < high)
        is_odd = low % (chunksize * 2)
        color = pink if is_odd else green
        hue_out[select] = color
    hue[:] = hue_out
    return nphusl.to_rgb(hsl), "watermelon"
Example #10
0
def hue_watermelon(img):
    hsl = nphusl.to_husl(img)
    hue, saturation, lightness = (hsl[..., n] for n in range(3))
    hue_out = hue.copy()
    pink = 360  # very end of the H spectrum
    green = 130
    chunksize = 45
    for low, high in nphusl.chunk(360, chunksize):  # chunks of the hue range
        select = np.logical_and(hue > low, hue < high)
        is_odd = low % (chunksize * 2)
        color = pink if is_odd else green
        hue_out[select] = color
    hue[:] = hue_out
    return nphusl.to_rgb(hsl), "watermelon"
Example #11
0
def highlight_saturation(img):
    hsl = nphusl.to_husl(img)
    hsl[..., 2][hsl[..., 1] < 80] = 0
    return nphusl.to_rgb(hsl), "saturation"
Example #12
0
def reveal_light(img):
    hsl = nphusl.to_husl(img)
    lightness = hsl[..., 2]  # just the lightness channel
    dark = lightness < 62
    hsl[..., 2][dark] = 0  # darkish areas to completely dark
    return nphusl.to_rgb(hsl), "light"
Example #13
0
def test_to_rgb_2d():
    img = np.ascontiguousarray(_img()[:, 17])
    husl = nphusl.to_husl(img)
    rgb = nphusl.to_rgb(husl)
    _diff(rgb, img, diff=1)
Example #14
0
def highlight_saturation(img):
    hsl = nphusl.to_husl(img)
    hsl[..., 2][hsl[..., 1] < 80] = 0
    return nphusl.to_rgb(hsl), "saturation"
Example #15
0
def reveal_light(img):
    hsl = nphusl.to_husl(img)
    lightness = hsl[..., 2]  # just the lightness channel
    dark = lightness < 62
    hsl[..., 2][dark] = 0  # darkish areas to completely dark
    return nphusl.to_rgb(hsl), "light"
Example #16
0
def test_to_rgb_triplet():
    assert type(nphusl.to_rgb([360, 100, 100])) == np.ndarray
    assert np.all(nphusl.to_rgb([360, 100, 100]) == [255, 255, 255])
def test_accuracy(img):
    with nphusl.simd_enabled():
        hsl = nphusl.to_husl(img.rgb)
    with nphusl.numpy_enabled():
        rgb = nphusl.to_rgb(hsl)
        hsl_ref = nphusl.to_husl(img.rgb)
    size = hsl.shape[0] * hsl.shape[1]
    hsl_flat = hsl.reshape((size, 3))
    rgb_flat = rgb.reshape((size, 3))
    hsl_ref_flat = hsl_ref.reshape((size, 3))
    rgb_ref_flat = img.rgb.reshape((size, 3))
    rgb_diff = np.abs(rgb_flat.astype(int) - rgb_ref_flat)
    hsl_diff = np.abs(hsl_flat - hsl_ref_flat)
    h_err, s_err, l_err = (hsl_diff[..., n] for n in range(3))
    h, s, l = (hsl_flat[..., n] for n in range(3))
    percentiles = [0, 25, 50, 90, 95, 96, 97, 98,
                   99.5, 99.6, 99.7, 99.8, 99.9, 100]

    def print_err_tables():
        fields = "Percentile", "Red error", "Green error", "Blue error", " "
        print(BOLD + "\nIMG->HUSL->RGB roundtrip error" + END)
        print(_error_table(rgb_diff, percentiles, fields))
        fields = "Percentile", "Hue error", "Sat error", "Light error", " "
        print(BOLD + "\nIMG->HUSL error vs. reference impl." + END)
        print(_error_table(hsl_diff, percentiles, fields))
        for i, name in enumerate("hue saturation lightness".split()):
            c = hsl_flat[..., i]
            c_err = hsl_diff[..., i]
            err_99 = np.percentile(c_err, 99)
            print(BOLD + "\nTypical RGB for {} error above 99th "
                  "percentile: ".format(name) + END)
            print(img.rgb[c_err.reshape(rgb.shape[:-1]) > err_99])
            print(BOLD + "\nTypical HUSL for {} error above 99th "
                  "percentile: ".format(name) + END)
            print(hsl[c_err.reshape(rgb.shape[:-1]) > err_99])

    print(BOLD + "\nAll RGB & HUSL errors")
    print(         "=====================" + END)
    print_err_tables()
    h_err[s < 0.1] = 0  # hue errors for low saturation have no meaning
    rgb_diff[s < 0.1] = 0
    s_err[l > 99.5] = 0  # saturation errors when very bright not meaningful
    rgb_diff[l > 99.5] = 0
    s_err[l < 1] = 0  # saturation errors when very dim not meaningful
    rgb_diff[l < 1] = 0
    print(BOLD + "\nPerceptible RGB & HUSL errors")
    print(         "=============================" + END)
    print_err_tables()

    max_err = max(np.percentile(rgb_diff, 100, axis=0))
    mask = np.any(rgb_diff == max_err, axis=1)
    print(BOLD + "\nMost challenging pixel")
    print(         "======================" + END)
    print("RGB input vs. output: {} -> {}".format(
        rgb_ref_flat[mask].squeeze(), rgb_flat[mask].squeeze()))
    print("HUSL ouput vs. reference impl.: {} vs. {}".format(
        hsl_flat[mask].squeeze(), hsl_ref_flat[mask].squeeze()))
    src = "_accuracy_test_source.png"
    rec = "_accuracy_test_recreated.png"
    print("\nWriting PNGs: {}, {}".format(src, rec))
    imageio.imwrite(src, img.rgb)
    imageio.imwrite(rec, rgb)
Example #18
0
def test_to_rgb_3d():
    img = _img()
    husl = _nphusl.to_husl(img)
    rgb = nphusl.to_rgb(husl)
    assert np.all(rgb == img)