Use python to read RGB and YUV format pictures and calculate their entropy

Use python to read RGB and YUV format pictures and calculate their entropy

I. Introduction

The content of this task:
Analyze the probability distribution of the three channels on down.rgb and down.yuv, and calculate their respective entropies. The resolution of the two files is 256*256, yuv is 4:2:0 sampling space, and the storage format is: rgb files are stored in sequence according to the BGR component of each pixel; the YUV format is according to the Y data block and U data block of all pixels And V data blocks are stored in sequence.
Although I used c++ to read YUV format files and perform a series of processing in the last semester, in comparison, python is more convenient to perform such operations, with more packages that can be called, and I am more familiar with it. Therefore, python is chosen as the programming language this time.

Second, read the image

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)

Originally, for the convenience of viewing the image of each channel, it was reshaped to (256, 256, 3). Later, when calculating the entropy, it was discovered that the np.bincount() function can only pass in one-dimensional data, so it was changed to a two-dimensional matrix.

Picture display
Insert picture description here
Note: The data storage order isBGRInstead of RGB

After consulting the data, it is found that the default reading method in opencv is also BGR, which needs to be paid attention to in the future

The function converts an input image from one color space to another. In case of a transformation to-from RGB color space, the order of the channels should be specified explicitly (RGB or BGR). Note that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the bytes are reversed). So the first byte in a standard (24-bit) color image will be an 8-bit Blue component, the second byte will be Green, and the third byte will be Red. The fourth, fifth, and sixth bytes would then be the second pixel (Blue, then Green, then Red), and so on.

2.YUV

First, I checked some code written by others to read YUV on csdn, and it felt too complicated. After experimentation, it is found that directly restricting the size of each read by f.read() can read the YUV most quickly, and the read pointer will stay at the end of the last read.

#读取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]

The picture shows
Y
Insert picture description here
U
Insert picture description here
V
Insert picture description here

Three, calculate entropy

1. Formulas and functions

Entropy calculation formula
function

#计算熵函数
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

np.bincount() function note:
Insert picture description here
np.nonzero() function note
Insert picture description here

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)

result:

R G B
7.229552890551847 7.178462484835099 6.856861210882991

2.YUV

#计算熵
Y = entropy(data_Y)
U = entropy(data_U)
V = entropy(data_V)

result:

Y U V
6.3318185418675075 5.126401914399721 4.113143002049819

Four, summary

It can be obtained from the calculation result that storing this image in YUV format can compress it even smaller. Through the file manager, the size of down.rgb is 192kb, while the size of down.yuv is only 96kb, but the knowledge is limited, and it is not clear whether it is related to this (get it back and update).

Guess you like

Origin blog.csdn.net/cppKillMe/article/details/114417577