Advertisement
yclee126

14 segment display font viewer(simulator)

Mar 6th, 2022
1,565
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.41 KB | None | 0 0
  1. # 14 segment display decoder and viewer (simulator)
  2. # the segment image is taken from below link
  3. # https://www.youtube.com/channel/UCXBrLU1A-J51eVtTOEsIbAw/community?lb=UgkxViWPs-1e6Ii89cxlRPN2EHmUE_I0ngLM
  4.  
  5. import cv2
  6. import numpy as np
  7. import ctypes
  8. ctypes.windll.user32.SetProcessDPIAware()
  9.  
  10. # 14 segment chars image
  11. img = cv2.imread('segment.png')
  12. seg_area = [(90, 114), (774, 1935)] # first and last display center coords
  13. h_count = 8
  14. v_count = 12
  15. # pixels lower than this grayscale value will be considered as "ON"
  16. threshold = 100
  17. inverse_threshold = True
  18.  
  19. # position of each segments (clockwise, from outer to inner, centered)
  20. seg_coords = [(1, -67), (36, -37), (38, 32), (2, 71), (-33, 37), (-34, -35), (-15, 3), (20, 2), (-16, -33), (2, -33), (18, -32), (20, 37), (2, 36), (-15, 37)]
  21. seg_datas = []
  22.  
  23. # preprocess the image
  24. img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  25. threshold_type = cv2.THRESH_BINARY_INV if inverse_threshold else cv2.THRESH_BINARY
  26. ret, img = cv2.threshold(img, threshold, 255, threshold_type)
  27.  
  28. # parse 14 segment data - detect segment by distance
  29. seg_w = (seg_area[1][0] - seg_area[0][0]) / (h_count-1)
  30. seg_h = (seg_area[1][1] - seg_area[0][1]) / (v_count-1)
  31. for v in range(v_count):
  32.     for h in range(h_count):
  33.         # current char index
  34.         index = v*h_count + h
  35.         seg_data = 0 # 14-bit binary data
  36.  
  37.         # current display center coord
  38.         cx = ((seg_area[1][0] - seg_area[0][0]) / (h_count-1)) * h + seg_area[0][0]
  39.         cy = ((seg_area[1][1] - seg_area[0][1]) / (v_count-1)) * v + seg_area[0][1]
  40.  
  41.         # crop current display image
  42.         x0, x1 = int(cx - seg_w/2), int(cx + seg_w/2)
  43.         y0, y1 = int(cy - seg_h/2), int(cy + seg_h/2)
  44.         segment_img = img[y0:y1, x0:x1]
  45.  
  46.         # find contours and measure each distance to the nearest segment center
  47.         contours, _ = cv2.findContours(segment_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  48.         for contour in contours:
  49.             dists = []
  50.             for coord in seg_coords:
  51.                 x, y = coord
  52.                 x = int(x+seg_w/2)
  53.                 y = int(y+seg_h/2)
  54.                 dist = cv2.pointPolygonTest(contour, (x, y), True)
  55.                 dists.append(dist)
  56.  
  57.             # find the nearest segment index
  58.             seg_index = np.argmax(np.array(dists))
  59.             seg_data |= 1 << seg_index
  60.        
  61.         # append to the list
  62.         seg_datas.append(seg_data)
  63.  
  64. # print char segment datas
  65. for data in seg_datas:
  66.     print(f'0x{data:04x}, ', end='')
  67.  
  68. # segment display simulator
  69.  
  70. # the last image is used as "full segment display" reference
  71. x0, x1 = int(seg_area[1][0] - seg_w/2), int(seg_area[1][0] + seg_w/2)
  72. y0, y1 = int(seg_area[1][1] - seg_h/2), int(seg_area[1][1] + seg_h/2)
  73. segment_img = img[y0:y1, x0:x1]
  74.  
  75. # find each segment with segment coordinates
  76. segment_contours = []
  77. contours, _ = cv2.findContours(segment_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  78. for coord in seg_coords:
  79.     x, y = coord
  80.     x = int(x+seg_w/2)
  81.     y = int(y+seg_h/2)
  82.     for contour in contours:
  83.         if cv2.pointPolygonTest(contour, (x, y), False) > 0:
  84.             segment_contours.append(contour)
  85.             break
  86.  
  87. def draw_segment(segment_img, char_index, offset):
  88.     seg_data = seg_datas[char_index]
  89.     for seg_index in range(14):
  90.         if seg_data & (1 << seg_index):
  91.             segment_img = cv2.drawContours(segment_img, [segment_contours[seg_index]], -1, 255, -1, offset=offset)
  92.     return segment_img
  93.  
  94. # main view loop
  95. window = '14 segment viewer'
  96. char_count = 10
  97. text_list = list(' '*char_count)
  98. auto_text_list = list('')
  99. while True:
  100.     img = np.zeros((int(seg_h), int(seg_w*char_count)), 'uint8')
  101.     for i, char in enumerate(text_list):
  102.         x = int(i*seg_w)
  103.         img = draw_segment(img, ord(char)-32, (x, 0))
  104.    
  105.     cv2.imshow(window, img)
  106.     if len(auto_text_list) != 0:
  107.         key = cv2.waitKey(500)
  108.         print(key)
  109.         if key > 0:
  110.             auto_text_list = []
  111.         else:
  112.             key = ord(auto_text_list.pop(0))
  113.     else:
  114.         key = cv2.waitKey(0)
  115.  
  116.     if cv2.getWindowProperty(window, cv2.WND_PROP_VISIBLE) < 1:
  117.         break
  118.  
  119.     if key == 8: # backspace
  120.         text_list = text_list[:-1]
  121.         text_list.insert(0, ' ')
  122.     elif key == 13: # enter
  123.         text_list = list(' '*char_count)
  124.     elif(key & 0xFF): # other keys
  125.         text_list.pop(0)
  126.         text_list.append(chr(key))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement