又是被坑的一天~
我想压缩一张图片origin.png,百度图片将就找一张吧。1101103的彩图:
先读进来:
img = cv2.imread('D:/Secondcoding/remote/origin.png')
然后我对它分成了三通道对每一个通道的图片进行小波变换压缩图片:
R, G, B = cv2.split(img)
# 对三个通道进行小波分解和压缩
four_compress, gzip_csr_size = wavelet_transform((R, G, B), LK, HK)
重点不是小波变换,是小波系数矩阵被我稀疏化后我要把高低频稀疏矩阵用csr表示:
csr_LL = csr_matrix(LL, dtype=np.float32)
csr_LH = csr_matrix(LH, dtype=np.float32)
csr_HL = csr_matrix(HL, dtype=np.float32)
csr_HH = csr_matrix(HH, dtype=np.float32)
这里说明一下,csr_matrix将低频稀疏系数矩阵LL表示成了三个数组(csr_LL里面):data,indices,indptr
然后我用gzip进一步压缩:
compressed_LL = (gzip.compress(csr_LL.data.tobytes()),
gzip.compress(csr_LL.indices.tobytes()), gzip.compress(csr_LL.indptr.tobytes()))
compressed_LH = (gzip.compress(csr_LH.data.tobytes()),
gzip.compress(csr_LH.indices.tobytes()),gzip.compress(csr_LH.indptr.tobytes()))
compressed_HL = (gzip.compress(csr_HL.data.tobytes()),
gzip.compress(csr_HL.indices.tobytes()), gzip.compress(csr_HL.indptr.tobytes()))
compressed_HH = (gzip.compress(csr_HH.data.tobytes()),
gzip.compress(csr_HH.indices.tobytes()), gzip.compress(csr_HH.indptr.tobytes()))
好了我通过mqtt协议将压缩好的数据(压缩了至少30%)传输到另一个机器后,我要解压数据恢复成矩阵进行图像分类了。
先gzip解压再将csr格式还原:
data = np.frombuffer(gzip.decompress(compressed_LL[0]))
indices = np.frombuffer(gzip.decompress(compressed_LL[1]))
indptr = np.frombuffer(gzip.decompress(compressed_LL[2]))
# 将data、indices、indptr三个数组转换为CSR格式的稀疏矩阵
sparse = csr_matrix((data,indices,indptr), shape=shape) # shape是csr格式表示之前的那个矩阵的shape(55,55)
# 将CSR格式转换为原始矩阵格式
dense_LL = sparse.toarray()
没错没错!就是这个坑!!!
问题来了,我的sparse稀疏矩阵一直都是空的!,data,indices,indptr都是0 len。我就纳闷了,我的三个数组不是空的呀怎么到sparse就空了,害得我debug了csr_matrix,然后我就想是不是我没指定数据类型,于是我赶紧添上:
data = np.frombuffer(gzip.decompress(compressed_LL[0]),dtype=np.float32)
indices = np.frombuffer(gzip.decompress(compressed_LL[1]),dtype=np.float32)
indptr = np.frombuffer(gzip.decompress(compressed_LL[2]),dtype=np.float32)
# 将data、indices、indptr三个数组转换为CSR格式的稀疏矩阵
sparse = csr_matrix((data,indices,indptr), shape=shape) # shape是csr格式表示之前的那个矩阵的shape(55,55)
# 将CSR格式转换为原始矩阵格式
dense_LL = sparse.toarray()
继续空,于是就回到了开头,我说过indices和indptr是int32类型!,我终于误了,就像语言编码一样GBK和utf的转换,他们都是通过字符流编码解码转换的,所以我通过gzip的bytes流压缩解压的时候也要明确对应的数据类型!所以用np.frombuffer的时候一定要明确类型!
最终改为:
data = np.frombuffer(gzip.decompress(compressed_LL[0]),dtype=np.float32)
indices = np.frombuffer(gzip.decompress(compressed_LL[1]),dtype=np.int32)
indptr = np.frombuffer(gzip.decompress(compressed_LL[2]),dtype=np.int32)
# 将data、indices、indptr三个数组转换为CSR格式的稀疏矩阵
sparse = csr_matrix((data,indices,indptr), shape=shape) # shape是csr格式表示之前的那个矩阵的shape(55,55)
# 将CSR格式转换为原始矩阵格式
dense_LL = sparse.toarray()
可气坏我了
省流: 有空看完,没空看这
原数组压缩时是什么数据类型,解压时需要明确数据类型,因为gzip表示是bytes流表示,你不告诉他几个字节表示一个数据电脑会宕机啦~
# 压缩
compressed = gzip.compress(原数组.tobytes()) # int32类型
# 解压
array = np.frombuffer(gzip.decompress(compressed), dtype=np.int32)
呵呵图片变成这样了