本文详细解释为什么读取到内存中的图片大小往往要比外存中的图片大的原因。
我先给出一个例子,如下:
这里使用openCV-Python 对图片的这种差异进行解释。
我把这个例程的代码贴出来:
import cv2 as cv
import numpy as np
img1 = cv.imread('C:\\Python\\OpenCV\\666.png')
print(img1.shape)
cv.imshow("input image1", img1)
cv.waitKey(0)
首先我们可以看到,img1.shape 三元元组输出这个彩色图像的像素高,像素宽,通道数,即 (557, 583, 3)
我们可以将鼠标悬停在(‘C:\Python\OpenCV\666.png’) 这句话上,它会自动显示图片的信息。
如下图:
我们可以看到,它的分辨率是 583 * 557, 24位真彩色 ,每个像素点占用3Byte, 外存大小是495.19K.
这里我会讲解该怎么根据分辨率和通道数计算图片在内存中的BitMap大小。
首先,需要知道以下知识:
图像按照颜色空间可以分为 二值图,灰度图,RGB三通道图,HSV 三通道图,HSI三通道图。
我们经常遇到的,并且手机拍摄的图片就是RGB 三通道图片,即红绿蓝 三通道,各自的取值范围是0-255。将三种具有不同取值的颜色通道值混合,便可以得到各种不同的颜色。对于一个像素点而言,比如说RGB全取255就是白色,全取0就是黑色,R 255 G 255 B 0, 就是黄色。其实就是红绿蓝的三种组合。
关于图片,图片就是一个三维数组,在内存中就是BitMap,对于openCV-python输出shape函数的输出的元组(557, 583, 3)来说,就是一个三维数组。你可以把它想象成华夫饼,网上有关于三维数组的介绍,这里不做过多讲解。
图片的分辨率比如说上面这张图片的分辨率: 583 * 557,就代表这张图像横向有583个像素格子,纵向有557个像素格子,那么总像素大小就是:
583 * 557=324731 个像素点。对于RGB 三通道24位真彩色图片而言,每个像素点都有三个通道,每个通道都占8位,那么三通道就是24位,即每个像素点占3个Byte,那么图片在内存中的大小就是583 * 557 * 3=980877 Byte,即957.887KB。那么为什么外存中的图片大小却是495.19KB 呢?
是因为,存储在外存即磁盘中的图片是编码过的,是为了提高存储效率,所以这个大小是不定的,这跟图片格式和压缩率有关。简言之,读取磁盘中的图片到内存中,需要将图片解码成BitMap, BitMap 的大小就是上面我们计算的大小,这个值是唯一可以确定的。这个解码对应的格式比如jpg bnp 等等就是图片压缩解码算法的原因,导致磁盘上的图片大小会比内存中的BitMap要小很多。
关于二值图,灰度图,HSV图,HSI图以及关于通道的深度理解请大家搜索互联网,很多人已经将此概念讲解得很清楚了。