Always-on computer music
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

88 satır
2.5KB

  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. def draw_rectangle(frame, sp, ep):
  13. """ Draw a rectangle on the frame """
  14. return cv2.rectangle(frame, sp, ep, RED, 1)
  15. def analyze_block(frame, osc, index, sp, ep, send=False):
  16. """ Analyze a block """
  17. block = frame[sp[1]:ep[1], sp[0]:ep[0], 0:3]
  18. average_color = np.average(block, (0, 1)) / 255
  19. h, s, v = colorsys.rgb_to_hsv(*average_color)
  20. # Configure the oscillator
  21. if send:
  22. print("Sending message", h, s, v)
  23. osc.send_message(
  24. "/radio",
  25. [int(index), float(h),
  26. float(s), float(v), .5])
  27. # Draw a blob of the average color
  28. sp2 = tuple(int(x) for x in (2 * np.array(sp) + np.array(ep)) / 3)
  29. ep2 = tuple(int(x) for x in (np.array(sp) + 2 * np.array(ep)) / 3)
  30. frame = cv2.rectangle(frame, sp2, ep2,
  31. [int(x * 255) for x in average_color], -1)
  32. # Draw the image
  33. for thickness, color in ((3, (0, 0, 0)), (1, (255, 255, 255))):
  34. frame = cv2.putText(frame,
  35. text=f"{h:.2f} {s:.2f} {v:.2f}",
  36. org=(sp[0] + 10, sp[1] + 20),
  37. fontScale=.5,
  38. color=color,
  39. fontFace=2,
  40. thickness=thickness)
  41. return frame
  42. def analyze(frame, osc):
  43. """ Analyze the full frame """
  44. global LAST_MESSAGE_TIME
  45. height, width, d = frame.shape
  46. n = DENSITY
  47. m = math.ceil(n * (height / width))
  48. dx = width / n
  49. dy = height / m
  50. send = False
  51. if time.time() - LAST_MESSAGE_TIME > 0.1:
  52. LAST_MESSAGE_TIME = time.time()
  53. send = True
  54. for index, (y, x) in enumerate(it.product(range(m), range(n))):
  55. sp = (int(x * dx), int(y * dy))
  56. ep = (int(x * dx + dx), int(y * dy + dy))
  57. frame = draw_rectangle(frame, sp, ep)
  58. frame = analyze_block(frame, osc, index, sp, ep, send)
  59. return frame
  60. if __name__ == '__main__':
  61. camera = cv2.VideoCapture("/dev/video2")
  62. # camera = cv2.VideoCapture(0)
  63. osc = udp_client.SimpleUDPClient("0.0.0.0", 5005)
  64. while True:
  65. ret, frame = camera.read()
  66. frame = analyze(frame, osc)
  67. cv2.imshow('Input', frame)
  68. c = cv2.waitKey(1)
  69. if c == 27:
  70. break
  71. camera.release()
  72. cv2.destroyAllWindows()