Use Python para leer imágenes en formato RGB y YUV y calcular su entropía
I. Introducción
El contenido de esta tarea:
Analizar la distribución de probabilidad de los tres canales en down.rgb y down.yuv, y calcular sus respectivas entropías. La resolución de los dos archivos es 256 * 256, yuv es espacio de muestreo 4: 2: 0 y el formato de almacenamiento es: los archivos rgb se almacenan en secuencia de acuerdo con el componente BGR de cada píxel; el formato YUV está de acuerdo con el El bloque de datos Y y el bloque de datos U de todos los píxeles y los bloques de datos V se almacenan en secuencia.
Aunque usé c ++ para leer archivos en formato YUV y realizar una serie de procesamientos en el último semestre, en contraste, Python es más conveniente para realizar tales operaciones, con más paquetes que se pueden llamar y las personas están más familiarizadas con él. Por lo tanto, esta vez se elige Python como lenguaje de programación.
Segundo, lee la imagen
1.RGB
#读取RGB图像
f = open(image_path,"rb")
data = f.read()
f.close()
data = [int(x) for x in data]
data = np.array(data).reshape((256*256, 3)).astype(np.uint8)
Originalmente, para la conveniencia de ver la imagen de cada canal, se le cambió la forma a (256, 256, 3). Más tarde, al calcular la entropía, se descubrió que la función np.bincount () solo puede pasar datos unidimensionales, por lo que se cambió a una matriz bidimensional.
Visualización de imagen
Nota: El orden de almacenamiento de datos esBGREn lugar de RGB
Después de consultar los datos, se encuentra que el método de lectura predeterminado en opencv también es BGR, al que se debe prestar atención en el futuro
La función convierte una imagen de entrada de un espacio de color a otro. En caso de una transformación de un espacio de color RGB, el orden de los canales debe especificarse explícitamente (RGB o BGR). Tenga en cuenta que el formato de color predeterminado en OpenCV a menudo se denomina RGB, pero en realidad es BGR (los bytes están invertidos). Por lo tanto, el primer byte en una imagen en color estándar (24 bits) será un componente azul de 8 bits, el segundo byte será verde y el tercer byte será rojo. El cuarto, quinto y sexto bytes serían el segundo píxel (azul, luego verde, luego rojo), y así sucesivamente.
2.YUV
Primero, verifiqué un código escrito por otros para leer YUV en csdn, y me pareció demasiado complicado. Después de la experimentación, se encuentra que restringir directamente el tamaño de cada lectura por f.read () puede leer el YUV más rápidamente, y el puntero de lectura permanecerá en la posición final de la última lectura.
#读取YUV图像
f = open(image_path,"rb")
data_Y = f.read(256*256)
data_U = f.read(128*128)
data_V = f.read(128*128)
data_Y = [int(x) for x in data_Y]
data_U = [int(x) for x in data_U]
data_V = [int(x) for x in data_V]
La imagen muestra
Y
U
V
Tres, calcula la entropía
1. Fórmulas y funciones
función
#计算熵函数
def entropy(X):
n = len(X)
counts = np.bincount(X)
probs = counts[np.nonzero(counts)] / n
en = 0
for i in range(len(probs)):
en = en - probs[i] * np.log(probs[i])/np.log(2)
return en
Nota de la función np.bincount (): nota de la función
np.nonzero ()
2.RGB
#计算熵
data_B = data[:,0]
data_G = data[:,1]
data_R = data[:,2]
B = entropy(data_B)
G = entropy(data_G)
R = entropy(data_R)
print(B)
print(G)
print(R)
resultado:
R | GRAMO | B |
---|---|---|
7.229552890551847 | 7.178462484835099 | 6.856861210882991 |
2.YUV
#计算熵
Y = entropy(data_Y)
U = entropy(data_U)
V = entropy(data_V)
resultado:
Y | U | V |
---|---|---|
6.3318185418675075 | 5.126401914399721 | 4.113143002049819 |
Cuatro, resumen
Se puede obtener del resultado del cálculo que almacenar esta imagen en formato YUV puede comprimirla aún más. A través del administrador de archivos, el tamaño de down.rgb es de 192kb, mientras que el tamaño de down.yuv es de solo 96kb, pero el conocimiento es limitado y no está claro si está relacionado con esto (vuelva a actualizarlo)