python和matlab都可以读取的图片,图片的数字类型也可以跟着改变。 比如如果读了一张hdr的图片,图片矩阵的数字一定的float的。但是如果把这张图片做色调映射(tone mapping)变成ldr图片再保存成.jpg格式的话,图片的数字类型必须变到[0,255]的整数。之前我在做灰度图到彩色图的转换的时候发现,同一张图片用matlab和python写成.jpg保存,结果是不一样的。如果图片名是img的话:
matlab中我用的
%matalb
uint8(img)
imwrite(img, ‘123.jpg’)
python用的
#python
img.astype(‘uint8‘)
imageio.imwrite(img, ‘123.jpg’)
这里matlab保存的图像很好,但是python的结果会出问题。如果不用astype的话,写下的图片会发暗。原因是原图的动态范围比较大,超过了8bit的范围。要想存入.jpg格式就必须对动态范围进行压缩。为了把凉的变暗,那么暗的地方自然就更暗了。
如果用astype(‘uint8’)的话,在图片一些区域会有集中的大片的单一颜色,好像被油漆刷过一样。这里我知道的原因是astype的机制是casting的格式转换,所以四舍五入会导致图片的颜色改变。具体为什么出现大片的单一色目前还不清楚。
而matlab的uint8()方程是直接切掉多出去的值。比如说有个2×2矩阵m=[-1,5,3000,200]。uint8(m)之后结果是[0, 5, 255, 200]。也就是说在[0, 255]之间的数字不动,只把大于255的变成255,把小于0的变成0就好了。
如果在python里想达到同样的切除多余值的效果也很简单:
m[m>255] = 255
m[m<0] = 0
如果图片或者矩阵很大的话建议用numpy.clip,速度会快一些。