问题描述
我试图删除原始文件的前 24 行,所以我打开了原始原始文件(我们称之为 raw1.raw)并将其转换为 nparray,然后我初始化了一个新数组并删除了 top24 行,但是将新数组写入新的二进制文件(raw2.raw)后,我发现raw2只有15.2mb,而原始文件raw1.raw大约有30.6mb,我的代码:
import numpy as np
import imageio
import rawpy
import cv2
def ave():
fd = open('raw1.raw','rb')
rows = 3000 #around 3000,not the real rows
cols = 5100 #around 5100,not the real cols
f = np.fromfile(fd,dtype=np.uint8,count=rows*cols)
I_array = f.reshape((rows,cols)) #notice row,column format
#print(I_array)
fd.close()
im = np.zeros((rows - 24,cols))
for i in range (len(I_array) - 24):
for j in range(len(I_array[i])):
im[i][j] = I_array[i + 24][j]
#print(im)
newFile = open("raw2.raw","wb")
im.astype('uint8').tofile(newFile)
newFile.close()
if __name__ == "__main__":
ave()
我在二进制文件中写入时尝试使用im.astype('uint16'),但如果我使用uint16,该值会出错。
解决方法
您的“raw1.raw”文件中肯定有更多您没有使用的数据。您确定该文件不是使用“uint16”数据创建的,而您只是将前半部分提取为“uint8”数据?我刚刚检查了随机数据的写入。
import os,numpy as np
x = np.random.randint(0,256,size=(3000,5100),dtype='uint8')
x.tofile(open('testfile.raw','w'))
print(os.stat('testfile.raw').st_size) #I get 15.3MB.
因此,3000 x 5100 的 'uint8' 显然占用 15.3MB。我不知道你是怎么得到 30+ 的。
########################### 编辑#########
只是为了添加更多说明。您是否意识到 dtype 只是改变了数据的“视图”?它不会影响保存在内存中的实际数据。这也适用于您从文件中读取的数据。举个例子:
import numpy as np
#The way to understand x,is that x is taking 12 bytes in memory and using
#that information to hold 3 values. The first 4 bytes are the first value,#the second 4 bytes are the second,etc.
x = np.array([1,2,3],dtype='uint32')
#Change x to display those 12 bytes at 6 different values. Doing this does
#NOT change the data that the array is holding. You are only changing the
#'view' of the data.
x.dtype = 'uint16'
print(x)
一般情况下(很少有特殊情况),更改 dtype 不会更改基础数据。但是,转换函数 .astype() 确实会更改基础数据。如果您将任何 12 字节的数组视为 'int32',则运行 .astype('uint8') 将获取每个条目(4 个字节)并将其转换(称为强制转换)为 uint8 条目(1 个字节)。对于 3 个条目,新数组将只有 3 个字节。你可以从字面上看到这一点:
x = np.array([1,dtype='uint32')
print(x.tobytes())
y = x.astype('uint8')
print(y.tobytes())
所以,当我们说一个文件是 30mb 时,我们的意思是该文件(减去一些头信息)是 30,000,000 字节,这正是 uint8s。 1 uint8 是 1 个字节。如果任何数组有 6000by5100 uint8s(字节),那么该数组在内存中就有 30,600,000 字节的信息。
同样,如果您读取文件(与文件无关)并写入 np.fromfile(,dtype=np.uint8,count=15_300_000) 那么您告诉 python 读取 15_300_000 字节(同样 1 字节是 1 uint8 ) 的信息 (15mb)。如果您的文件是 100mb、40mb 甚至 30mb,那将完全无关紧要,因为您告诉 python 只读取前 15mb 的数据。