Opencv Numpy Uint8和float型对显示图像(cv.imshow)的影响

发现两个问题

在昨天做实验的内容时,图像部分显示很奇怪,该亮的地方是黑色的(使用np.uint8后溢出导致的),以及不该亮的画面,出现过分亮的样子(矩阵中元素是浮点数导致的)

该亮的地方是黑色的

在这里插入图片描述

出现过分亮的样子

在这里插入图片描述

dtype = float

其实不仅是定义了类型,在进行矩阵运算的过程中,数值也很容易变成浮点数,如果没有对图像数据定义为uint8,会出现整个画面过白的情况,详情见cv.imshow使用手册内容:
cv.imshow
红圈部分说明了,如果数据是浮点数,cv.imshow会把数值×255,因为他默认你的浮点数位于0~1之间,×255后,就可以在0到255之间了。

但是如果我们的数据是大于1的呢?是20呢?也会×255,这样那个位置的灰度值必大于255,所以会显示成白色。

小小测验,定义四个区域,灰度值分别为0.0, 0.3,1.01, 15。对于前两个浮点数,×255后,仍在可显示范围内,对于1.01×255>255,应该显示白色,15.0×255>255,应该显示白色。实验验证如下:
在这里插入图片描述
解决办法就是,在定义图像时,把他的类型定义成np.uint8型,如下:

	img = np.ones([500, 500, 1], dtype=np.uint8)

但是uint8型也有其问题,下面继续说。

dtype = np.uint8

今早看到大佬总结的np.uint8
其实把我想表达的都说了,np.uint8会把高位部分砍掉,意思就是,比如图像进行矩阵运算后,得到某点的灰度值为260,那他实际存储值为:260 - 256 = 4,以为他会是白色的,事实上显示出来是黑色的。

验证如下:定义四个区域,灰度值分别为
在这里插入图片描述
在这里插入图片描述
从实际输出也可以看出来,并没有按照想象中的白色输出,而是显示成了黑色。
上面链接里,大佬也给出了他的解决办法:

	cv2.normalize(img, out, 0, 255, cv2.NORM_MINMAX)
	np.array([out],dtype=‘uint8’)

这样是可以的,先对数据处理后,再改变数据类型,同样的,可以使用:

	np.clip(a, a_min, a_max)
	np.array([out],dtype=‘uint8’)

也可以实现相应的效果,基于能力有限,目前没想到其他解决的好办法。

np.ones定义图像

最后,关于np.ones定义图像时,如果没有定义类型,他默认输出的是浮点数型,浮点数型可能就会导致我上述说的错误,需要注意下。

	>>> a = np.ones([2,2,1])
	>>> print(a)
	[[[1.]
	  [1.]]
	
	 [[1.]
	  [1.]]]

定义类型后:

	b = np.ones([2,2,1], dtype = np.uint8)
	>>> print (b)
	[[[1]
	  [1]]
	
	 [[1]
	  [1]]]
	>>> 

补充更新(2020.11.16)

在这里插入图片描述

今天做图像减法的时候遇到的,当时就想了一下,如果减出负数的话,uint8会怎么样?(因为uint8是无符号的嘛,只能存储0~255),测验了一下,负数的话,输入-1,输出255,输入-255,输出1。

那么如果:
输入-N,(-256<N<0)
输出的值是256-N。
输入-N,(N<-256)
先把输入加上256的倍数,加到(-256,0)这个范围内,再带进上式
OK!

本文是本人小总结,有不足的地方欢迎批评指正!

  • 17
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值