创建矩阵
a=np.ones((3,3),dtype=np.uint8)
b=np.arange(9).reshape((3,3))
c=np.array([[50,55,60],[65,70,75],[80,85,90]])
如果在创建的时候没有指定数据类型,那么默认是int32
强制类型转换
方法一:
b.dtype=np.uint8
虽然dtype变了,但是shape也变了,再看看里面的数据
除了原先的数据,又添加了新的数据0
方法二:astype
对c这个对象做astype这个操作
c.astype(np.uint8)
Out[11]:
array([[50, 55, 60],
[65, 70, 75],
[80, 85, 90]], dtype=uint8)
这样就是期望的结果了。
不同数据类型之间的运算
1.int32+uint8=int32
f=c+d
2.uint8+float32=float32
g=d+e
cv2和plt显示矩阵的数据类型
d=c.astype(np.uint8)
plt.imshow(c,'gray')
Out[13]:
plt.imshow(d,'gray')
Out[14]:
plt显示uint8和int32的效果是一样的,都可以显示
cv2.namedWindow('1', cv2.WINDOW_NORMAL);
cv2.imshow('1',c);
cv2.imshow('1',d);
cv2.imshow()也可以显示uint8和int32类型的矩阵,由于矩阵过小,cv的窗口很小,就不截图了。
浮点型
1.简单例子
e=np.arange(9).reshape((3,3)).astype(np.float32)
plt.imshow(e,'gray')
Out[20]:
cv2.imshow('1',e)
cv2.imshow和plt都可以显示
2.但是如果是三通道的图片,像素是float型,那么plt无法显示
例如
lina=cv2.imread('lina2.png')
n1=0.5;
lina1=lina*n1
plt.imshow(lina1)
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Out[9]:
plt.imshow(lina1.astype(np.float32),'gray')
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
但是,plt可以显示单通道的float型
img=cv2.imread('lina2.png',0)
n1=0.5;n2=2
img1=img*n1
plt.imshow(img1,'gray')
lina=cv2.imread('lina2.png',0)
n1=0.5;n2=2
lina1=lina*n1
plt.subplot(121);plt.title('uint8')
plt.imshow(lina1.astype(np.uint8),'gray')
plt.subplot(122);plt.title('float64')
plt.imshow(lina1,'gray')
plt.show()
cv2
cv2.imshow('1',img1)
cv2.imshow('1',img1.astype(np.float32))
对于float32,float64。cv2显示都是一片空白
但是:
cv2.imshow('1',img1.astype(np.uint8))
可见:
cv2的显示只能显示uint8
数据溢出
数据类型:https://www.runoob.com/numpy/numpy-dtype.html
d矩阵是有c矩阵int32强制类型转化成的,数据类型是uint8,说明范围是0~255
通过赋值,观察console台中的数据变化发现
超过255的,从0开始,循环始终是从0到255
输入255对应255,输入256对应0,输入257对应1,输入365对应365-256=109,输入900对应900-256*2=132
输入-256对应0,-255对应1,-257对应255
如果从int32转换成uint8,是不是如上的数值结果呢?
c[0,:]=[256,365,900];c[1,:]=[-256,-255,-257]
d=c.astype(np.uint8)
结果与上述分析相同
总结:
在规定的数据类型下有一个数据范围,超过数据范围的数则从这个范围的最小开始重新计数
图像线性增强
1.对像素直接加上或减去一个数值
import cv2
import numpy as np
import matplotlib.pylab as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
lina = cv2.imread('lina2.png',0)
rows,cols = lina.shape
a=np.ones((rows,cols),dtype=lina.dtype)
plt.subplot(321)
plt.imshow(a*20+lina,'gray');plt.title('+20')
plt.subplot(322)
plt.imshow(a*50+lina,'gray');plt.title('+50')
plt.subplot(323)
plt.imshow(lina-a*20,'gray');plt.title('-20')
plt.subplot(324)
plt.imshow(lina-a*50,'gray');plt.title('-50')
plt.subplot(325)
plt.imshow(lina,'gray');plt.title('source')
plt.show()
加减20是在正常的范围内,因为原图像素的最大是37,最小是17
而加减50就会出现原来是白,变成黑,原来是黑又变成白的情况,因为原图Lina是uint8格式,新构建的矩阵a也是uint8,所以结果也是uint8类型的。
0到255从黑到白,然后又一轮从黑到白
import cv2
import numpy as np
import matplotlib.pylab as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# #直接对像素加上一个实数来对图像的亮度进行一个整体的提升
lina = cv2.imread('lina2.png',0)
rows,cols = lina.shape
构造数据类型是float64的常数矩阵
a=np.ones((rows,cols))
默认类型是float64
然后吧和这个float64+uint8
b=a*50+lina
plt.imshow(b,'gray')
用plt去显示一个float6的4矩阵
得到:
构造数据类型是uint8的常数矩阵
aa=np.ones((rows,cols),dtype=lina.dtype);
bb=aa*50+lina
plt.imshow(bb,'gray')
所以说,如果想避免以上的情况的话
一开始的常数矩阵就构造float型,最后用plt显示float型矩阵
但是…发现这么搞之后,跟原图没啥大的区别了
lina = cv2.imread('lina2.png',0)
rows,cols = lina.shape
#a=np.ones((rows,cols),dtype=lina.dtype)
a=np.ones((rows,cols))
plt.subplot(321)
plt.imshow(a*20+lina,'gray');plt.title('+20')
plt.subplot(322)
plt.imshow(a*5000+lina,'gray');plt.title('+5000')
plt.subplot(323)
plt.imshow(lina-a*20,'gray');plt.title('-20')
plt.subplot(324)
plt.imshow(lina-a*5000,'gray');plt.title('-5000')
plt.subplot(325)
plt.imshow(lina,'gray');plt.title('source')
plt.show()
3.直接对像素乘以一个系数n来对图像的对比度进行增加或减小,
其中n=2,n=0.5,注意灰度值超出255的区域还是以255来显示。
import cv2
import numpy as np
import matplotlib.pylab as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
##线性增强
#直接对像素乘以一个系数n来对图像的对比度进行增加或减小,其中n=2,n=0.5,注意灰度值超出255的区域还是以255来显示。
lina=cv2.imread('lina2.png',0)
n1=0.5;n2=2
lina1=lina*n1
plt.subplot(121);plt.title('*0.5')
plt.imshow(lina1,'gray')
#这一步先转成int32,再乘以2,这样的话超过255的值会正常显示
lina2=lina.astype(np.int32)*n2
lina2[lina2>255]=255 #超过255的设为255
plt.subplot(122);plt.title('*2')
plt.imshow(lina2,'gray')
plt.show()