脚本用处
对于做CSI以及ISP验证过程中需要输入不同格式的随机图片,如果用真实图片作为输入则随机性不够,因此有了开发该脚本的动力。
脚本功能
- 支持指定输出文件路径
- 支持指定输出文件分辨率
- 支持指定输出图像格式,支持csi2 2.0所有format
脚本限制
- 不支持指定位深度(bit_depth),bit_depth与图像格式绑定(参考csi2 2.0 Spec),暂时未开放接口给用户
代码:
#!/usr/bin/python
#-*-coding:utf-8-*-
import os
import numpy as np
import struct
import argparse
class image_gen(object):
def __init__(self, name):
self.name = name
self.width = 640
self.height = 480
self.image_format = "RGB888"
self.image_output = ""
self.y_bit_depth = 8
self.u_bit_depth = 8
self.v_bit_depth = 8
self.r_bit_depth = 8
self.g_bit_depth = 8
self.b_bit_depth = 8
self.raw_bit_depth = 8
def parse_input(self):
parse = argparse.ArgumentParser(description = "Used to Generate Image Files")
parse.add_argument("-format", "--image_format", type=str, action = 'store', default="RGB888", help = "Image Format")
parse.add_argument("-width", "--image_width", type=int, action = 'store', default = 640, help = "Image Width")
parse.add_argument("-height", "--image_height", type=int, action = 'store', default = 480, help = "Image Height")
parse.add_argument("-o", "--output_floder", type=str, action = 'store', default = "", help = "Output Image File Floder")
args = parse.parse_args()
self.image_format = args.image_format
self.width = args.image_width
self.heigh = args.image_height
self.image_output = args.output_floder
# all csi2 2.0 supported image format
format_legal_list = ["YUV444", "YUV422_8bit", "YUV422_10bit", "YUV420_8bit_Legacy", "YUV420_8bit", "YUV420_10bit", "RGB888", "RGB666", "RGB565", "RGB555", "RGB444", "RAW6", "RAW7", "RAW8", "RAW10", "RAW12", "RAW14"];
# input format check
if self.image_format not in format_legal_list:
legal_format = str(format_legal_list)[1:-1]
raise Exception("%s is invalid image format, legal format is : %s"%(self.image_format, legal_format))
def raw_image_gen(self, raw_bit_depth):
print("Generate %s Image"%self.image_format)
if self.image_output == "":
file = open("%s_%sx%s.raw"%(self.image_format, self.width, self.height), "wb")
else:
file = open("%s/%s_%sx%s.raw"%(self.image_output, self.image_format, self.width, self.height), "wb")
R = np.random.randint(0, 2**raw_bit_depth, (self.height, self.width), dtype=np.uint16)
if self.image_format == "RAW10" or self.image_format == "RAW12" or self.image_format == "RAW14":
for row in R:
# 16bit in file
file.write(struct.pack("{}H".format(self.width), *row))
else:
for row in R:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
file.close()
def rgb_image_gen(self, r_bit_depth, g_bit_depth, b_bit_depth):
print("Generate %s Image"%self.image_format)
if self.image_output == "":
file = open("%s_%sx%s.rgb"%(self.image_format, self.width, self.height), "wb")
else:
file = open("%s/%s_%sx%s.rgb"%(self.image_output, self.image_format, self.width, self.height), "wb")
R = np.random.randint(0, 2**r_bit_depth, (self.height, self.width), dtype=np.uint16)
G = np.random.randint(0, 2**g_bit_depth, (self.height, self.width), dtype=np.uint16)
B = np.random.randint(0, 2**b_bit_depth, (self.height, self.width), dtype=np.uint16)
for i in range(len(R)):
for j in range(len(R[0])):
file.write(R[i][j])
file.write(G[i][j])
file.write(B[i][j])
file.close()
def yuv_image_gen(self, y_bit_depth, u_bit_depth, v_bit_depth):
print("Generate %s Image"%self.image_format)
if self.image_output == "":
file = open("%s_%sx%s.yuv"%(self.image_format, self.width, self.height), "wb")
else:
file = open("%s/%s_%sx%s.yuv"%(self.image_output, self.image_format, self.width, self.height), "wb")
if self.image_format == "YUV420_8bit_Legacy" or self.image_format == "YUV420_8bit" or self.image_format == "YUV420_10bit":
# Y:U:V = 4:1:1
Y = np.random.randint(0, 2**y_bit_depth, (self.height, self.width), dtype=np.uint16)
if self.image_format == "YUV420_10bit":
for row in Y:
# 10bit in file
file.write(struct.pack("{}H".format(self.width), *row))
else:
for row in Y:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
U = np.random.randint(0, 2**y_bit_depth, (int(self.height/2), int(self.width/2)), dtype=np.uint16)
if self.image_format == "YUV420_10bit":
for row in U:
# 10bit in file
file.write(struct.pack("{}H".format(int(self.width/2)), *row))
else:
for row in U:
# 8bit in file
file.write(struct.pack("{}B".format(int(self.width/2)), *row))
V = np.random.randint(0, 2**y_bit_depth, (int(self.height/2), int(self.width/2)), dtype=np.uint16)
if self.image_format == "YUV420_10bit":
for row in V:
# 10bit in file
file.write(struct.pack("{}H".format(int(self.width/2)), *row))
else:
for row in V:
# 8bit in file
file.write(struct.pack("{}B".format(int(self.width/2)), *row))
elif self.image_format == "YUV422_10bit" or self.image_format == "YUV422_8bit":
# Y:U:V = 4:2:2
Y = np.random.randint(0, 2**y_bit_depth, (self.height, self.width), dtype=np.uint16)
if self.image_format == "YUV422_10bit":
for row in Y:
# 10bit in file
file.write(struct.pack("{}H".format(self.width), *row))
else:
for row in Y:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
U = np.random.randint(0, 2**u_bit_depth, (int(self.height/2), self.width), dtype=np.uint16)
if self.image_format == "YUV422_10bit":
for row in U:
# 10bit in file
file.write(struct.pack("{}H".format(self.width), *row))
else:
for row in U:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
V = np.random.randint(0, 2**v_bit_depth, (int(self.height/2), self.width), dtype=np.uint16)
if self.image_format == "YUV422_10bit":
for row in V:
# 10bit in file
file.write(struct.pack("{}H".format(self.width), *row))
else:
for row in V:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
else: #YUV444
Y = np.random.randint(0, 2**y_bit_depth, (self.height, self.width), dtype=np.uint16)
U = np.random.randint(0, 2**u_bit_depth, (self.height, self.width), dtype=np.uint16)
V = np.random.randint(0, 2**v_bit_depth, (self.height, self.width), dtype=np.uint16)
for row in Y:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
for row in U:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
for row in V:
# 8bit in file
file.write(struct.pack("{}B".format(self.width), *row))
def parse_format(self) :
####################################RGB format####################################
if self.image_format == "RGB888":
self.rgb_image_gen(8, 8, 8)
elif self.image_format == "RGB666":
self.rgb_image_gen(6, 6, 6)
elif self.image_format == "RGB565":
self.rgb_image_gen(5, 6, 5)
elif self.image_format == "RGB555":
self.rgb_image_gen(5, 5, 5)
elif self.image_format == "RGB444":
self.rgb_image_gen(4, 4, 4)
####################################YUV format####################################
elif self.image_format == "YUV444":
self.yuv_image_gen(4, 4, 4)
elif self.image_format == "YUV422_8bit":
self.yuv_image_gen(8, 8, 8)
elif self.image_format == "YUV422_10bit":
self.yuv_image_gen(10, 10, 10)
elif self.image_format == "YUV420_8bit_Legacy":
self.yuv_image_gen(8, 8, 8)
elif self.image_format == "YUV420_8bit":
self.yuv_image_gen(8, 8, 8)
elif self.image_format == "YUV420_10bit":
self.yuv_image_gen(10, 10, 10)
####################################RAW format####################################
elif self.image_format == "RAW6":
self.raw_image_gen(6)
elif self.image_format == "RAW7":
self.raw_image_gen(7)
elif self.image_format == "RAW8":
self.raw_image_gen(8)
elif self.image_format == "RAW10":
self.raw_image_gen(10)
elif self.image_format == "RAW12":
self.raw_image_gen(12)
elif self.image_format == "RAW14":
self.raw_image_gen(14)
if __name__=="__main__" :
image_gen_inst = image_gen("image_gen")
image_gen_inst.parse_input()
image_gen_inst.parse_format()
Example:
python image_gen.py -format YUV422_8bit
结果:下图是使用YUV view查看,工具下载路径YUV view
下面用yuv view和HxD分别展示出前几个像素点: