Always-on computer music
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
1.6KB

  1. import math
  2. import time
  3. import itertools as it
  4. import cv2
  5. import colorsys
  6. from pythonosc import udp_client
  7. import numpy as np
  8. DENSITY = 4
  9. RED = [0, 0, 255]
  10. N_COLORS = 3
  11. LAST_MESSAGE_TIME = 0
  12. LAST_SNAPSHOT_TIME = 0
  13. def analyze_block(frame, osc, index, sp, ep, send=False):
  14. """ Analyze a block """
  15. block = frame[sp[1]:ep[1], sp[0]:ep[0], 0:3]
  16. average_color = np.average(block, (0, 1)) / 255
  17. h, s, v = colorsys.rgb_to_hsv(*average_color)
  18. # Configure the oscillator
  19. if send:
  20. osc.send_message(
  21. "/radio",
  22. [int(index), float(h),
  23. float(s), float(v), .5])
  24. return frame
  25. def analyze(frame, osc):
  26. """ Analyze the full frame """
  27. global LAST_MESSAGE_TIME, LAST_SNAPSHOT_TIME
  28. height, width, d = frame.shape
  29. n = DENSITY
  30. m = math.ceil(n * (height / width))
  31. dx = width / n
  32. dy = height / m
  33. send = False
  34. if time.time() - LAST_MESSAGE_TIME > 0.1:
  35. LAST_MESSAGE_TIME = time.time()
  36. send = True
  37. if time.time() - LAST_SNAPSHOT_TIME > 2:
  38. LAST_SNAPSHOT_TIME = time.time()
  39. cv2.imwrite("frame.png", frame)
  40. for index, (y, x) in enumerate(it.product(range(m), range(n))):
  41. sp = (int(x * dx), int(y * dy))
  42. ep = (int(x * dx + dx), int(y * dy + dy))
  43. frame = analyze_block(frame, osc, index, sp, ep, send)
  44. return frame
  45. if __name__ == '__main__':
  46. # camera = cv2.VideoCapture("/dev/video2")
  47. camera = cv2.VideoCapture(0)
  48. osc = udp_client.SimpleUDPClient("0.0.0.0", 5005)
  49. print("Radio is running...")
  50. while True:
  51. ret, frame = camera.read()
  52. frame = analyze(frame, osc)
  53. camera.release()