convert_image.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # Licensed to the Apache Software Foundation (ASF) under one
  2. # or more contributor license agreements. See the NOTICE file
  3. # distributed with this work for additional information
  4. # regarding copyright ownership. The ASF licenses this file
  5. # to you under the Apache License, Version 2.0 (the
  6. # "License"); you may not use this file except in compliance
  7. # with the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing,
  12. # software distributed under the License is distributed on an
  13. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. # KIND, either express or implied. See the License for the
  15. # specific language governing permissions and limitations
  16. # under the License.
  17. import os
  18. import pathlib
  19. import re
  20. import sys
  21. import cv2
  22. import math
  23. from PIL import Image
  24. import numpy as np
  25. def resize_norm_img(img, image_shape, padding=True):
  26. imgC, imgH, imgW = image_shape
  27. h = img.shape[0]
  28. w = img.shape[1]
  29. if not padding:
  30. resized_image = cv2.resize(
  31. img, (imgW, imgH), interpolation=cv2.INTER_LINEAR)
  32. resized_w = imgW
  33. else:
  34. ratio = w / float(h)
  35. if math.ceil(imgH * ratio) > imgW:
  36. resized_w = imgW
  37. else:
  38. resized_w = int(math.ceil(imgH * ratio))
  39. resized_image = cv2.resize(img, (resized_w, imgH))
  40. resized_image = resized_image.astype('float32')
  41. if image_shape[0] == 1:
  42. resized_image = resized_image / 255
  43. resized_image = resized_image[np.newaxis, :]
  44. else:
  45. resized_image = resized_image.transpose((2, 0, 1)) / 255
  46. resized_image -= 0.5
  47. resized_image /= 0.5
  48. padding_im = np.zeros((imgC, imgH, imgW), dtype=np.float32)
  49. padding_im[:, :, 0:resized_w] = resized_image
  50. return padding_im
  51. def create_header_file(name, tensor_name, tensor_data, output_path):
  52. """
  53. This function generates a header file containing the data from the numpy array provided.
  54. """
  55. file_path = pathlib.Path(f"{output_path}/" + name).resolve()
  56. # Create header file with npy_data as a C array
  57. raw_path = file_path.with_suffix(".h").resolve()
  58. with open(raw_path, "w") as header_file:
  59. header_file.write(
  60. "\n" + f"const size_t {tensor_name}_len = {tensor_data.size};\n" +
  61. f'__attribute__((section(".data.tvm"), aligned(16))) float {tensor_name}[] = '
  62. )
  63. header_file.write("{")
  64. for i in np.ndindex(tensor_data.shape):
  65. header_file.write(f"{tensor_data[i]}, ")
  66. header_file.write("};\n\n")
  67. def create_headers(image_name):
  68. """
  69. This function generates C header files for the input and output arrays required to run inferences
  70. """
  71. img_path = os.path.join("./", f"{image_name}")
  72. # Resize image to 32x320
  73. img = cv2.imread(img_path)
  74. img = resize_norm_img(img, [3, 32, 320])
  75. img_data = img.astype("float32")
  76. # # Add the batch dimension, as we are expecting 4-dimensional input: NCHW.
  77. img_data = np.expand_dims(img_data, axis=0)
  78. # Create input header file
  79. create_header_file("inputs", "input", img_data, "./include")
  80. # Create output header file
  81. output_data = np.zeros([7760], np.float32)
  82. create_header_file(
  83. "outputs",
  84. "output",
  85. output_data,
  86. "./include", )
  87. if __name__ == "__main__":
  88. create_headers(sys.argv[1])