Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird logic in colorfulness #18

Open
bbb651 opened this issue Sep 30, 2024 · 1 comment
Open

Weird logic in colorfulness #18

bbb651 opened this issue Sep 30, 2024 · 1 comment

Comments

@bbb651
Copy link

bbb651 commented Sep 30, 2024

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())
@davidkrantz
Copy link
Owner

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants