RGBtoNTSC.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # Script to convert RGB332 to luma phase amplitude for NTSC composite
  2. import colorsys
  3. import numpy as np
  4. # list of available phases using 5 bits
  5. phaselist = []
  6. for x in range(32):
  7. phaselist.append(x*11.25)
  8. phaselist.append(360) # so we can set it back to 0 later if a match occurs
  9. """
  10. 000 001 010 011 100 101 110 111
  11. -------------------------------------
  12. r3bit (0, 36, 73, 109, 146, 182, 219, 255)
  13. g3bit (0, 36, 73, 109, 146, 182, 219, 255)
  14. b3bit (0, 85, 170, 255)
  15. -----------------
  16. 00 01 10 11
  17. """
  18. def rgb2ypa(r3, g3, b2):
  19. r = r3/7.0
  20. g = g3/7.0
  21. b = b2/3.0
  22. y, i, q = colorsys.rgb_to_yiq(r, g, b)
  23. i = i #* 1.67813391509
  24. q = q #* 1.91241155097
  25. phase = 0.0
  26. if i != 0.0:
  27. phase = np.arctan2(q, i) # arctan2 to get full 360 degrees
  28. phase = np.degrees(phase) # radians to degrees
  29. # make phases positive
  30. if phase < 0.0:
  31. phase += 360.0
  32. f.append((phase))
  33. # match to closest available phase in phaselist, and get index
  34. phase = min(phaselist, key=lambda x:abs(x-phase))
  35. phase = phaselist.index(phase)
  36. if phase == 32:
  37. phase = 0
  38. # wrap around to match correct phase:
  39. """
  40. yellow-ish = ~1
  41. orange-ish = ~3
  42. red = 6
  43. purple/violet = 12
  44. blue = 18
  45. cyan = 22
  46. green = 29 (good sync point!)
  47. """
  48. phase = (phase + 5) % 32
  49. saturation = np.sqrt(i**2 + q**2)
  50. saturation = round(saturation*130) # multiply to fit range
  51. # add luma offset (72 = black)
  52. y = round(72 + y * (255-72))
  53. return y, phase, saturation
  54. # loop through all 256 color possibilities
  55. for i in range(256):
  56. b = 0
  57. if i&0b01:
  58. b += 1
  59. if i&0b10:
  60. b += 2
  61. g = 0
  62. if i&0b0100:
  63. g += 1
  64. if i&0b1000:
  65. g += 2
  66. if i&0b10000:
  67. g += 4
  68. r = 0
  69. if i&0b0100000:
  70. r += 1
  71. if i&0b1000000:
  72. r += 2
  73. if i&0b10000000:
  74. r += 4
  75. y, p, a = rgb2ypa(r, g, b)
  76. # create verilog code line for RGBtoYPhaseAmpl.v
  77. print("8'b" + format(i, '08b') + " : begin luma <= 8'd" + str(y) + "; phase <= 5'd" + str(p) + "; ampl <= 8'd" + str(a) + "; end")