-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnv21torgb24.py
More file actions
executable file
·116 lines (97 loc) · 3.43 KB
/
nv21torgb24.py
File metadata and controls
executable file
·116 lines (97 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/python
# -*- coding: utf-8 -*-
# 各种YUV格式详解: https://www.jianshu.com/p/e67f79f10c65
# 1. Y∈ [0,1] U∈ [-0.5,0.5] V∈ [-0.5 ,0.5]
# 2. Y∈[16,235] U∈[16,240] V∈[ 16,240 ]
# 3. jpeg的标准中,Y、U、V的取值范围都是0-255
# NV21是420sp的一种,先V后U,YYYYYYYYVUVU
# 本文针对jpeg标准
#[Y,U,V]T = M[R,G,B]T 其中 M = 0.299 , 0.587, 0.114, -0.169, - 0.331, 0.5, 0.5, - 0.419 - 0.081
#[R,G,B]T = M[Y,U,V]T 其中 M =
#1 0 1.4017
#1 -0.3437 -0.7142
#1 1.7722 0
import sys
import os
from nv21torgb24table import *
def clamp2byte(v):
if v < 0:
return chr(0)
elif v > 255:
return chr(255)
else:
return chr(int(v))
def clamp(v, minv, maxv):
if v < minv:
return minv
elif v > maxv:
return maxv
else:
return v
def convert(src, width, height, table):
dst = ''
p = 0
for y in range(height):
for x in range(width):
Y = src[y * width + x]
V = src[width * height + (y / 2) * width + (x / 2) * 2]
U = src[width * height + (y / 2) * width + (x / 2) * 2 + 1]
# 虽然图片的实际YUV值的范围是0-254,但是当成MPEG的量化能得到较好图片
Y = clamp(ord(Y), 16, 235)
U = clamp(ord(U), 16, 240)
V = clamp(ord(V), 16, 240)
index = 220 + int((U - 16) * 225 + (V - 16))
premul = table[index]
#R = Y + 1.4017 * V;
#G = Y - 0.3437 * U - 0.7142 * V;
#B = Y + 1.7722 * U
Y = table[Y - 16]
R = Y + premul[0]
G = Y - premul[1]
B = Y + premul[2]
R = clamp2byte(R >> 16)
G = clamp2byte(G >> 16)
B = clamp2byte(B >> 16)
dst += R
dst += G
dst += B
return dst
def build_table():
# 将乘法做成查表
# 建立Y -> (Y - 16) / (235.0 - 16)
# 建立(U,V)->((U - 16) / (240.0 - 16) - 0.5, (V - 16) / (240.0 - 16) - 0.5)->(1.4017 * V, 0.3437 * U + 0.7142 * V, 1.7722 * U)的转换表
# 注意UV取值范围,先对齐值再用表
# 由于是顺序无跳值,表可以转为数组
# *255量化RGB,再乘65536,浮点转整数
table = [0] * (256 * 256)
for U in range(256):
for V in range(256):
index = int((U) * 256 + (V))
fU = (clamp(U, 16, 240) - 16) / (240.0 - 16) - 0.5
fV = (clamp(V, 16, 240) - 16) / (240.0 - 16) - 0.5
#最大值为255
table[index] = (int(1.4017 * fV * 255 * 65536), int(0.3437 * fU * 255 * 65536 + 0.7142 * fV * 255 * 65536), int(1.7722 * fU * 255 * 65536))
return table
if __name__ == '__main__':
path = sys.argv[1]
width = int(sys.argv[2])
src = None
with open(path, 'rb') as f:
src = f.read()
print(src[:100])
height = int(len(src)/1.5/width)
print('height:' , height)
table = build_table()
#with open('nv21torgb24table.py', 'w') as f:
# f.write('table = [');
# for i in range(len(table)):
# f.write('%s,' % repr(table[i]))
# f.write(']');
with open('nv21torgb24table.h', 'w') as f:
f.write('const int nv21torgb24_table_uv[256*256][3] = {');
for i in range(256 * 256):
f.write('{%d,%d,%d},' % table[i])
f.write('};');
#dst = convert(src, width, height, table)
#with open(path + '.dst', 'wb') as f:
# f.write(dst)