1#!/usr/bin/env python3 2 3# Copyright (c) 2021 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import cv2 17import sys 18import os 19from datetime import datetime 20 21DEBUG = False 22DEBUG = True 23TARGET_WIDTH = 128 24TARGET_HEIGHT = 64 25PIXEL_PER_BYTE = 8 26WIDTH_BYTES = int(TARGET_WIDTH/PIXEL_PER_BYTE) 27PIXEL_THRESHOLD = 128.0 28 29# 将多个灰度像素打包到一个整数中 30def pack_pixels(pixels, threshold): 31 value = 0 32 for gray in pixels: 33 bit = 1 if gray >= threshold else 0 # 二值化 34 value = (value << 1) + bit # 多个二值化像素值拼接为一个字节值 35 return value 36 37frameCount = 0 38def resize_and_binarize_image(frame, width, height, threshold): 39 data = [] 40 # count = 0 # for debug 41 start = datetime.now() 42 frame = cv2.resize(frame, (width, height)) # 缩放 43 frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 转为灰度图 44 _, binary = cv2.threshold(frame, threshold, 255, cv2.THRESH_BINARY) # 二值化 45 46 for r in range(height): 47 for b in range(int(width / PIXEL_PER_BYTE)): 48 colStart = b * PIXEL_PER_BYTE 49 pixels = frame[r, colStart: colStart + PIXEL_PER_BYTE] 50 byte = pack_pixels(pixels, threshold) 51 data.append(byte) 52 if DEBUG: 53 global frameCount 54 cv2.imwrite(os.path.join('debug', str(frameCount) + '.png'), frame) 55 cv2.imwrite(os.path.join('debug', str(frameCount) + '-bin.png'), binary) 56 frameCount += 1 57 end = datetime.now() 58 print('time cost:', end - start) 59 return bytes(data) 60 61def convert_frame_to_bytes(frame): 62 return resize_and_binarize_image(frame, TARGET_WIDTH, TARGET_HEIGHT, PIXEL_THRESHOLD) 63 64def main(): 65 if len(sys.argv) < 3: 66 print("Usage: {} input outdir [width] [height] [threshod]".format(sys.argv[0])) 67 exit(-1) 68 69 imgPath = sys.argv[1] 70 outdir = sys.argv[2] 71 width = len(sys.argv) > 3 and int(sys.argv[3]) or TARGET_WIDTH 72 height = len(sys.argv) > 4 and int(sys.argv[4]) or TARGET_HEIGHT 73 threshold = len(sys.argv) > 5 and int(sys.argv[5]) or PIXEL_THRESHOLD 74 imgFile = os.path.split(imgPath)[-1] 75 imgBase = imgFile.split('.')[-2] 76 codeFile = os.path.join(outdir, imgBase + '.c') 77 if not os.path.exists(outdir): 78 os.mkdir(outdir) 79 80 frame = cv2.imread(imgPath) # 加载图片 81 bitmap = resize_and_binarize_image(frame, width, height, threshold) # 转为目标格式的数组 82 83 with open(codeFile, 'w+') as f: # 输出到.c文件 84 f.write('const unsigned char {}_size[] = {{ {}, {} }};\n'.format(imgBase, width, height)) 85 f.write('const unsigned char {}[] = {{\n'.format(imgBase)) 86 for i in range(len(bitmap)): 87 v = bitmap[i] 88 sep = '\n' if (i+1) % (TARGET_WIDTH/PIXEL_PER_BYTE) == 0 else ' ' 89 f.write('0x%02X,%s' % (v, sep)) 90 f.write('};\n') 91 print(imgFile, '=>', codeFile, 'done!') 92 93if __name__ == "__main__": 94 main() 95