Colorfy icon indicating copy to clipboard operation
Colorfy copied to clipboard

Weird logic in `colorfulness`

Open bbb651 opened this issue 1 year ago • 1 comments

I'm working on implementing a color extracting algorithm into a music player, and I'm following this project as a reference. While going through colorfulness, I've noticed that since rg, yb are scalars, np.mean is a noop and np.std always returns 0, leading to most of the logic not affecting the end result, the return value can be simplified to 0.3 * np.sqrt(rg ** 2 + yb ** 2). I have not read through the paper closely yet, I'm not sure if the algorithm is generalized and can be simplified in this case, or if this is a subtle logic error.

Reproduction:

diff --git a/spotify_background_color.py b/spotify_background_color.py
index a10ff33..4ab91ec 100644
--- a/spotify_background_color.py
+++ b/spotify_background_color.py
@@ -1,3 +1,5 @@
+import sys
+
 import numpy as np
 import scipy.misc as sp
 import matplotlib.pyplot as plt
@@ -157,9 +159,22 @@ class SpotifyBackgroundColor():
         # Compute the mean and standard deviation of both `rg` and `yb`.
         rg_mean, rg_std = (np.mean(rg), np.std(rg))
         yb_mean, yb_std = (np.mean(yb), np.std(yb))
+        print(f"{rg=}, {yb=}")
+        print(f"{rg_mean=}, {rg_std=}, {yb_mean=}, {yb_std=}")
 
         # Combine the mean and standard deviations.
         std_root = np.sqrt((rg_std ** 2) + (yb_std ** 2))
         mean_root = np.sqrt((rg_mean ** 2) + (yb_mean ** 2))
+        print(f"{std_root=}, {mean_root=}")
 
+        print(f"Result: {std_root + (0.3 * mean_root)=}")
+        print(f"Simplified: {0.3 * np.sqrt(rg ** 2 + yb ** 2)=}")
         return std_root + (0.3 * mean_root)
+
+if __name__ == "__main__":
+    if len(sys.argv) < 2:
+        print("Usage: py spotify_background_color.py <image>", file=sys.stderr)
+        exit(1)
+    img = np.array(Image.open(sys.argv[1]))
+    sbc = SpotifyBackgroundColor(img)
+    print(sbc.best_color())

bbb651 avatar Sep 30 '24 09:09 bbb651

Thank you for your observation!

The code is old and no longer maintained due to it being deprecated (since Spotify updating their Chromecast graphics). However, I do have some thoughts regarding your comment:

  • What do you mean with the mean being "noop"?
  • I see your point in the logic being weird. If the values are scalars, then the mean of those scalars will be equal to the value itself and the standard deviation will, of course, equal zero. This is not unexpected. The question is if the input values should be scalars or not.
  • From a quick glance at the article again, a difference could be that they consider a full RGB image, while I only feed the algorithm a single pixel with a red, green and blue value. Do you see what I mean?

Hope this gives you some insights!

davidkrantz avatar Nov 19 '24 21:11 davidkrantz