1#!/usr/bin/env python3 2import cv2 3import sys 4import os 5from datetime import datetime 6 7DEBUG = False 8DEBUG = True 9TARGET_WIDTH = 128 10TARGET_HEIGHT = 64 11PIXEL_PER_BYTE = 8 12WIDTH_BYTES = int(TARGET_WIDTH/PIXEL_PER_BYTE) 13PIXEL_THRESHOLD = 128.0 14 15# 将多个灰度像素打包到一个整数中 16def pack_pixels(pixels, threshold): 17 value = 0 18 for gray in pixels: 19 bit = 1 if gray >= threshold else 0 # 二值化 20 value = (value << 1) + bit # 多个二值化像素值拼接为一个字节值 21 return value 22 23frameCount = 0 24def resize_and_binarize_image(frame, width, height, threshold): 25 data = [] 26 # count = 0 # for debug 27 start = datetime.now() 28 frame = cv2.resize(frame, (width, height)) # 缩放 29 frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 转为灰度图 30 _, binary = cv2.threshold(frame, threshold, 255, cv2.THRESH_BINARY) # 二值化 31 32 for r in range(height): 33 for b in range(int(width / PIXEL_PER_BYTE)): 34 colStart = b * PIXEL_PER_BYTE 35 pixels = frame[r, colStart: colStart + PIXEL_PER_BYTE] 36 byte = pack_pixels(pixels, threshold) 37 data.append(byte) 38 if DEBUG: 39 global frameCount 40 cv2.imwrite(os.path.join('debug', str(frameCount) + '.png'), frame) 41 cv2.imwrite(os.path.join('debug', str(frameCount) + '-bin.png'), binary) 42 frameCount += 1 43 end = datetime.now() 44 print('time cost:', end - start) 45 return bytes(data) 46 47def convert_frame_to_bytes(frame): 48 return resize_and_binarize_image(frame, TARGET_WIDTH, TARGET_HEIGHT, PIXEL_THRESHOLD) 49 50def main(): 51 if len(sys.argv) < 3: 52 print("Usage: {} input outdir [width] [height] [threshod]".format(sys.argv[0])) 53 exit(-1) 54 55 imgPath = sys.argv[1] 56 outdir = sys.argv[2] 57 width = len(sys.argv) > 3 and int(sys.argv[3]) or TARGET_WIDTH 58 height = len(sys.argv) > 4 and int(sys.argv[4]) or TARGET_HEIGHT 59 threshold = len(sys.argv) > 5 and int(sys.argv[5]) or PIXEL_THRESHOLD 60 imgFile = os.path.split(imgPath)[-1] 61 imgBase = imgFile.split('.')[-2] 62 codeFile = os.path.join(outdir, imgBase + '.c') 63 if not os.path.exists(outdir): 64 os.mkdir(outdir) 65 66 frame = cv2.imread(imgPath) # 加载图片 67 bitmap = resize_and_binarize_image(frame, width, height, threshold) # 转为目标格式的数组 68 69 with open(codeFile, 'w+') as f: # 输出到.c文件 70 f.write('const unsigned char {}_size[] = {{ {}, {} }};\n'.format(imgBase, width, height)) 71 f.write('const unsigned char {}[] = {{\n'.format(imgBase)) 72 for i in range(len(bitmap)): 73 v = bitmap[i] 74 sep = '\n' if (i+1) % (TARGET_WIDTH/PIXEL_PER_BYTE) == 0 else ' ' 75 f.write('0x%02X,%s' % (v, sep)) 76 f.write('};\n') 77 print(imgFile, '=>', codeFile, 'done!') 78 79if __name__ == "__main__": 80 main() 81