10a7ce71fSopenharmony_ci#!/usr/bin/env python3
20a7ce71fSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd.
30a7ce71fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
40a7ce71fSopenharmony_ci# you may not use this file except in compliance with the License.
50a7ce71fSopenharmony_ci# You may obtain a copy of the License at
60a7ce71fSopenharmony_ci#
70a7ce71fSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
80a7ce71fSopenharmony_ci#
90a7ce71fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
100a7ce71fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
110a7ce71fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a7ce71fSopenharmony_ci# See the License for the specific language governing permissions and
130a7ce71fSopenharmony_ci# limitations under the License.
140a7ce71fSopenharmony_ci
150a7ce71fSopenharmony_ciimport cv2
160a7ce71fSopenharmony_ciimport sys
170a7ce71fSopenharmony_ciimport os
180a7ce71fSopenharmony_cifrom datetime import datetime
190a7ce71fSopenharmony_ci
200a7ce71fSopenharmony_ciDEBUG = False
210a7ce71fSopenharmony_ciDEBUG = True
220a7ce71fSopenharmony_ciTARGET_WIDTH = 128
230a7ce71fSopenharmony_ciTARGET_HEIGHT = 64
240a7ce71fSopenharmony_ciPIXEL_PER_BYTE = 8
250a7ce71fSopenharmony_ciWIDTH_BYTES = int(TARGET_WIDTH/PIXEL_PER_BYTE)
260a7ce71fSopenharmony_ciPIXEL_THRESHOLD = 128.0
270a7ce71fSopenharmony_ci
280a7ce71fSopenharmony_ci# 将多个灰度像素打包到一个整数中
290a7ce71fSopenharmony_cidef pack_pixels(pixels, threshold):
300a7ce71fSopenharmony_ci    value = 0
310a7ce71fSopenharmony_ci    for gray in pixels:
320a7ce71fSopenharmony_ci        bit = 1 if gray >= threshold else 0 # 二值化
330a7ce71fSopenharmony_ci        value = (value << 1) + bit # 多个二值化像素值拼接为一个字节值
340a7ce71fSopenharmony_ci    return value
350a7ce71fSopenharmony_ci
360a7ce71fSopenharmony_ciframeCount = 0
370a7ce71fSopenharmony_cidef resize_and_binarize_image(frame, width, height, threshold):
380a7ce71fSopenharmony_ci    data = []
390a7ce71fSopenharmony_ci    # count = 0 # for debug
400a7ce71fSopenharmony_ci    start = datetime.now()
410a7ce71fSopenharmony_ci    frame = cv2.resize(frame, (width, height)) # 缩放
420a7ce71fSopenharmony_ci    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 转为灰度图
430a7ce71fSopenharmony_ci    _, binary = cv2.threshold(frame, threshold, 255, cv2.THRESH_BINARY) # 二值化
440a7ce71fSopenharmony_ci
450a7ce71fSopenharmony_ci    for r in range(height):
460a7ce71fSopenharmony_ci        for b in range(int(width / PIXEL_PER_BYTE)):
470a7ce71fSopenharmony_ci            colStart = b * PIXEL_PER_BYTE
480a7ce71fSopenharmony_ci            pixels = frame[r, colStart: colStart + PIXEL_PER_BYTE]
490a7ce71fSopenharmony_ci            byte = pack_pixels(pixels, threshold)
500a7ce71fSopenharmony_ci            data.append(byte)
510a7ce71fSopenharmony_ci    if DEBUG:
520a7ce71fSopenharmony_ci        global frameCount
530a7ce71fSopenharmony_ci        cv2.imwrite(os.path.join('debug', str(frameCount) + '.png'), frame)
540a7ce71fSopenharmony_ci        cv2.imwrite(os.path.join('debug', str(frameCount) + '-bin.png'), binary)
550a7ce71fSopenharmony_ci        frameCount += 1
560a7ce71fSopenharmony_ci        end = datetime.now()
570a7ce71fSopenharmony_ci        print('time cost:', end - start)
580a7ce71fSopenharmony_ci    return bytes(data)
590a7ce71fSopenharmony_ci
600a7ce71fSopenharmony_cidef convert_frame_to_bytes(frame):
610a7ce71fSopenharmony_ci    return resize_and_binarize_image(frame, TARGET_WIDTH, TARGET_HEIGHT, PIXEL_THRESHOLD)
620a7ce71fSopenharmony_ci
630a7ce71fSopenharmony_cidef main():
640a7ce71fSopenharmony_ci    if len(sys.argv) < 3:
650a7ce71fSopenharmony_ci        print("Usage: {} input outdir [width] [height] [threshod]".format(sys.argv[0]))
660a7ce71fSopenharmony_ci        exit(-1)
670a7ce71fSopenharmony_ci
680a7ce71fSopenharmony_ci    imgPath = sys.argv[1]
690a7ce71fSopenharmony_ci    outdir = sys.argv[2]
700a7ce71fSopenharmony_ci    width = len(sys.argv) > 3 and int(sys.argv[3]) or TARGET_WIDTH
710a7ce71fSopenharmony_ci    height = len(sys.argv) > 4 and int(sys.argv[4]) or TARGET_HEIGHT
720a7ce71fSopenharmony_ci    threshold = len(sys.argv) > 5 and int(sys.argv[5]) or PIXEL_THRESHOLD
730a7ce71fSopenharmony_ci    imgFile = os.path.split(imgPath)[-1]
740a7ce71fSopenharmony_ci    imgBase = imgFile.split('.')[-2]
750a7ce71fSopenharmony_ci    codeFile = os.path.join(outdir, imgBase + '.c')
760a7ce71fSopenharmony_ci    if not os.path.exists(outdir):
770a7ce71fSopenharmony_ci        os.mkdir(outdir)
780a7ce71fSopenharmony_ci
790a7ce71fSopenharmony_ci    frame = cv2.imread(imgPath) # 加载图片
800a7ce71fSopenharmony_ci    bitmap = resize_and_binarize_image(frame, width, height, threshold) # 转为目标格式的数组
810a7ce71fSopenharmony_ci
820a7ce71fSopenharmony_ci    with open(codeFile, 'w+') as f: # 输出到.c文件
830a7ce71fSopenharmony_ci        f.write('const unsigned char {}_size[] = {{ {}, {} }};\n'.format(imgBase, width, height))
840a7ce71fSopenharmony_ci        f.write('const unsigned char {}[] = {{\n'.format(imgBase))
850a7ce71fSopenharmony_ci        for i in range(len(bitmap)):
860a7ce71fSopenharmony_ci            v = bitmap[i]
870a7ce71fSopenharmony_ci            sep = '\n' if (i+1) % (TARGET_WIDTH/PIXEL_PER_BYTE) == 0 else ' '
880a7ce71fSopenharmony_ci            f.write('0x%02X,%s' % (v, sep))
890a7ce71fSopenharmony_ci        f.write('};\n')
900a7ce71fSopenharmony_ci    print(imgFile, '=>', codeFile, 'done!')
910a7ce71fSopenharmony_ci
920a7ce71fSopenharmony_ciif __name__ == "__main__":
930a7ce71fSopenharmony_ci    main()
94